mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
Added interpreters for a bunch of functions and table aliases
This commit is contained in:
parent
277ce51fb5
commit
afcc62fc75
@ -71,20 +71,24 @@ namespace sqlpp
|
||||
any_t& operator=(any_t&&) = default;
|
||||
~any_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_any, "any() not supported by current database");
|
||||
os << "ANY(";
|
||||
_select.serialize(os, db);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Select _select;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Context, typename Select>
|
||||
struct interpreter_t<Context, detail::any_t<Select>>
|
||||
{
|
||||
using T = detail::any_t<Select>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "ANY(";
|
||||
interpret(t._select, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto any(T&& t) -> typename detail::any_t<typename operand_t<T, is_select_t>::type>
|
||||
{
|
||||
|
@ -70,20 +70,24 @@ namespace sqlpp
|
||||
avg_t& operator=(avg_t&&) = default;
|
||||
~avg_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_avg, "avg() not supported by current database");
|
||||
os << "AVG(";
|
||||
_expr.serialize(os, db);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Expr _expr;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Context, typename Expr>
|
||||
struct interpreter_t<Context, detail::avg_t<Expr>>
|
||||
{
|
||||
using T = detail::avg_t<Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "AVG(";
|
||||
interpret(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto avg(T&& t) -> typename detail::avg_t<typename operand_t<T, is_value_t>::type>
|
||||
{
|
||||
|
@ -70,20 +70,24 @@ namespace sqlpp
|
||||
count_t& operator=(count_t&&) = default;
|
||||
~count_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_count, "count() not supported by current database");
|
||||
os << "COUNT(";
|
||||
_expr.serialize(os, db);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Expr _expr;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Context, typename Expr>
|
||||
struct interpreter_t<Context, detail::count_t<Expr>>
|
||||
{
|
||||
using T = detail::count_t<Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "COUNT(";
|
||||
interpret(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto count(T&& t) -> typename detail::count_t<typename operand_t<T, is_value_t>::type>
|
||||
{
|
||||
|
@ -27,7 +27,6 @@
|
||||
#ifndef SQLPP_EXISTS_H
|
||||
#define SQLPP_EXISTS_H
|
||||
|
||||
#include <sstream>
|
||||
#include <sqlpp11/boolean.h>
|
||||
|
||||
namespace sqlpp
|
||||
@ -70,20 +69,25 @@ namespace sqlpp
|
||||
exists_t& operator=(exists_t&&) = default;
|
||||
~exists_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_exists, "exists() not supported by current database");
|
||||
os << "EXISTS(";
|
||||
_select.serialize(os, db);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Select _select;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Context, typename Select>
|
||||
struct interpreter_t<Context, detail::exists_t<Select>>
|
||||
{
|
||||
using T = detail::exists_t<Select>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "EXISTS(";
|
||||
interpret(t._select, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
auto exists(T&& t) -> typename detail::exists_t<typename operand_t<T, is_select_t>::type>
|
||||
{
|
||||
|
@ -61,16 +61,6 @@ namespace sqlpp
|
||||
_dynamic_tables.emplace_back(std::forward<Table>(table));
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
if (sizeof...(TableOrJoin) == 0 and _dynamic_tables.empty())
|
||||
return;
|
||||
os << " FROM ";
|
||||
detail::serialize_tuple(os, db, _tables, ',');
|
||||
_dynamic_tables.serialize(os, db, sizeof...(TableOrJoin) == 0);
|
||||
}
|
||||
|
||||
std::tuple<TableOrJoin...> _tables;
|
||||
detail::serializable_list<Database> _dynamic_tables;
|
||||
};
|
||||
|
@ -27,10 +27,8 @@
|
||||
#ifndef SQLPP_FUNCTIONS_H
|
||||
#define SQLPP_FUNCTIONS_H
|
||||
|
||||
#include <sstream>
|
||||
#include <sqlpp11/parameter.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/column_types.h>
|
||||
#include <sqlpp11/in.h>
|
||||
#include <sqlpp11/exists.h>
|
||||
@ -57,12 +55,6 @@ namespace sqlpp
|
||||
{
|
||||
using _value_type = ValueType;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, const Db& db) const
|
||||
{
|
||||
os << _verbatim;
|
||||
}
|
||||
|
||||
verbatim_t(const std::string& verbatim): _verbatim(verbatim) {}
|
||||
verbatim_t(std::string&& verbatim): _verbatim(std::forward<std::string>(verbatim)) {}
|
||||
verbatim_t(const verbatim_t&) = default;
|
||||
@ -74,6 +66,18 @@ namespace sqlpp
|
||||
std::string _verbatim;
|
||||
};
|
||||
|
||||
template<typename Context, typename ValueType>
|
||||
struct interpreter_t<Context, verbatim_t<ValueType>>
|
||||
{
|
||||
using T = verbatim_t<ValueType>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << t._verbatim;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ValueType, typename StringType>
|
||||
auto verbatim(StringType&& s) -> verbatim_t<ValueType>
|
||||
{
|
||||
@ -93,26 +97,31 @@ namespace sqlpp
|
||||
{
|
||||
using _container_t = Container;
|
||||
using _value_type = typename operand_t<typename _container_t::value_type, is_value_t>::type::_value_type;
|
||||
using _iterator = decltype(std::begin(std::declval<_container_t>()));
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, const Db& db) const
|
||||
{
|
||||
bool first = true;
|
||||
for (const auto& entry: _container)
|
||||
{
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
os << ',';
|
||||
|
||||
value(entry).serialize(os, db);
|
||||
}
|
||||
}
|
||||
|
||||
_container_t _container;
|
||||
};
|
||||
|
||||
template<typename Context, typename Container>
|
||||
struct interpreter_t<Context, value_list_t<Container>>
|
||||
{
|
||||
using T = value_list_t<Container>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
bool first = true;
|
||||
for (const auto& entry: t._container)
|
||||
{
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
context << ',';
|
||||
|
||||
interpret(value(entry), context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Container>
|
||||
auto value_list(Container&& c) -> value_list_t<typename std::decay<Container>::type>
|
||||
{
|
||||
|
@ -70,20 +70,24 @@ namespace sqlpp
|
||||
max_t& operator=(max_t&&) = default;
|
||||
~max_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_max, "max not supported by current database");
|
||||
os << "MAX(";
|
||||
_expr.serialize(os, db);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Expr _expr;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Context, typename Expr>
|
||||
struct interpreter_t<Context, detail::max_t<Expr>>
|
||||
{
|
||||
using T = detail::max_t<Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "MAX(";
|
||||
interpret(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto max(T&& t) -> typename detail::max_t<typename operand_t<T, is_value_t>::type>
|
||||
{
|
||||
|
@ -70,20 +70,24 @@ namespace sqlpp
|
||||
min_t& operator=(min_t&&) = default;
|
||||
~min_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_min, "min not supported by current database");
|
||||
os << "MIN(";
|
||||
_expr.serialize(os, db);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Expr _expr;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Context, typename Expr>
|
||||
struct interpreter_t<Context, detail::min_t<Expr>>
|
||||
{
|
||||
using T = detail::min_t<Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "MIN(";
|
||||
interpret(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto min(T&& t) -> typename detail::min_t<typename operand_t<T, is_value_t>::type>
|
||||
{
|
||||
|
@ -71,20 +71,24 @@ namespace sqlpp
|
||||
some_t& operator=(some_t&&) = default;
|
||||
~some_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_some, "some() not supported by current database");
|
||||
os << "SOME(";
|
||||
_select.serialize(os, db);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Select _select;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Context, typename Select>
|
||||
struct interpreter_t<Context, detail::some_t<Select>>
|
||||
{
|
||||
using T = detail::some_t<Select>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "SOME(";
|
||||
interpret(t._select, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto some(T&& t) -> typename detail::some_t<typename operand_t<T, is_select_t>::type>
|
||||
{
|
||||
|
@ -70,20 +70,24 @@ namespace sqlpp
|
||||
sum_t& operator=(sum_t&&) = default;
|
||||
~sum_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_sum, "sum not supported by current database");
|
||||
os << "SUM(";
|
||||
_expr.serialize(os, db);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Expr _expr;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Context, typename Expr>
|
||||
struct interpreter_t<Context, detail::sum_t<Expr>>
|
||||
{
|
||||
using T = detail::sum_t<Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "SUM(";
|
||||
interpret(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto sum(T&& t) -> typename detail::sum_t<typename operand_t<T, is_value_t>::type>
|
||||
{
|
||||
|
@ -27,8 +27,7 @@
|
||||
#ifndef SQLPP_TABLE_H
|
||||
#define SQLPP_TABLE_H
|
||||
|
||||
#include <ostream>
|
||||
#include <sqlpp11/alias.h>
|
||||
#include <sqlpp11/table_alias.h>
|
||||
#include <sqlpp11/no_value.h>
|
||||
#include <sqlpp11/column.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
@ -81,40 +80,7 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
template<typename AliasProvider>
|
||||
struct alias_t: public ColumnSpec::_name_t::template _member_t<column_t<AliasProvider, ColumnSpec>>...
|
||||
{
|
||||
using _is_table = std::true_type;
|
||||
using _table_set = detail::set<alias_t>;
|
||||
|
||||
struct _value_type: Table::_value_type
|
||||
{
|
||||
using _is_expression = std::false_type;
|
||||
using _is_named_expression = copy_type_trait<Table, is_value_t>;
|
||||
using _is_alias = std::true_type;
|
||||
};
|
||||
|
||||
using _name_t = typename AliasProvider::_name_t;
|
||||
using _all_of_t = std::tuple<column_t<AliasProvider, ColumnSpec>...>;
|
||||
|
||||
alias_t(const Table& table):
|
||||
_table(table)
|
||||
{}
|
||||
|
||||
alias_t(Table&& table):
|
||||
_table(std::move(table))
|
||||
{}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << "("; _table.serialize(os, db); os << ") AS " << _name_t::_get_name();
|
||||
}
|
||||
|
||||
Table _table;
|
||||
};
|
||||
|
||||
template<typename AliasProvider>
|
||||
alias_t<AliasProvider> as(const AliasProvider&) const
|
||||
table_alias_t<typename std::decay<AliasProvider>::type, Table, ColumnSpec...> as(const AliasProvider&) const
|
||||
{
|
||||
return {*static_cast<const Table*>(this)};
|
||||
}
|
||||
|
88
include/sqlpp11/table_alias.h
Normal file
88
include/sqlpp11/table_alias.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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_TABLE_ALIAS_H
|
||||
#define SQLPP_TABLE_ALIAS_H
|
||||
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
#include <sqlpp11/column.h>
|
||||
#include <sqlpp11/alias.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
struct table_alias_base_t {};
|
||||
|
||||
template<typename AliasProvider, typename Table, typename... ColumnSpec>
|
||||
struct table_alias_t: public table_alias_base_t, public ColumnSpec::_name_t::template _member_t<column_t<AliasProvider, ColumnSpec>>...
|
||||
{
|
||||
//FIXME: Need to add join functionality
|
||||
using _is_table = std::true_type;
|
||||
using _table_set = detail::set<table_alias_t>;
|
||||
|
||||
struct _value_type: Table::_value_type
|
||||
{
|
||||
using _is_expression = std::false_type;
|
||||
using _is_named_expression = copy_type_trait<Table, is_value_t>;
|
||||
using _is_alias = std::true_type;
|
||||
};
|
||||
|
||||
using _name_t = typename AliasProvider::_name_t;
|
||||
using _all_of_t = std::tuple<column_t<AliasProvider, ColumnSpec>...>;
|
||||
|
||||
table_alias_t(Table table):
|
||||
_table(table)
|
||||
{}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << "("; _table.serialize(os, db); os << ") AS " << _name_t::_get_name();
|
||||
}
|
||||
|
||||
Table _table;
|
||||
};
|
||||
|
||||
template<typename Context, typename X>
|
||||
struct interpreter_t<Context, X, typename std::enable_if<std::is_base_of<table_alias_base_t, X>::value, void>::type>
|
||||
{
|
||||
using T = X;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
interpret(t._table, context);
|
||||
context << ") AS " << T::_name_t::_get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -80,12 +80,6 @@ namespace sqlpp
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << value();
|
||||
}
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
return _is_null;
|
||||
@ -142,12 +136,6 @@ namespace sqlpp
|
||||
_len = 0;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << value();
|
||||
}
|
||||
|
||||
bool operator==(const _cpp_value_type& rhs) const { return value() == rhs; }
|
||||
bool operator!=(const _cpp_value_type& rhs) const { return not operator==(rhs); }
|
||||
|
||||
|
@ -62,15 +62,22 @@ namespace sqlpp
|
||||
verbatim_table_t& operator=(verbatim_table_t&& rhs) = default;
|
||||
~verbatim_table_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << _name;
|
||||
}
|
||||
|
||||
std::string _name;
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct interpreter_t<Context, verbatim_table_t>
|
||||
{
|
||||
using T = verbatim_table_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << t._name;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
verbatim_table_t verbatim_table(std::string name)
|
||||
{
|
||||
return { name };
|
||||
|
@ -58,11 +58,6 @@ namespace sqlpp
|
||||
_dynamic_expressions.emplace_back(std::forward<E>(expr));
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
}
|
||||
|
||||
_parameter_tuple_t _expressions;
|
||||
detail::serializable_list<Database> _dynamic_expressions;
|
||||
};
|
||||
|
@ -75,5 +75,22 @@ int main()
|
||||
interpret(remove_from(t).where(t.alpha == sqlpp::tvin(0)), printer).flush();
|
||||
interpret(remove_from(t).using_(t).where(t.alpha == sqlpp::tvin(0)), printer).flush();
|
||||
|
||||
// functions
|
||||
interpret(sqlpp::value(7), printer).flush();
|
||||
interpret(sqlpp::verbatim<sqlpp::detail::integral>("irgendwas integrales"), printer).flush();
|
||||
interpret(sqlpp::value_list(std::vector<int>({1,2,3,4,5,6,8})), printer).flush();
|
||||
interpret(exists(select(t.alpha).from(t)), printer).flush();
|
||||
interpret(any(select(t.alpha).from(t)), printer).flush();
|
||||
interpret(some(select(t.alpha).from(t)), printer).flush();
|
||||
interpret(count(t.alpha), printer).flush();
|
||||
interpret(min(t.alpha), printer).flush();
|
||||
interpret(max(t.alpha), printer).flush();
|
||||
interpret(avg(t.alpha), printer).flush();
|
||||
interpret(sum(t.alpha), printer).flush();
|
||||
interpret(sqlpp::verbatim_table("whatever"), printer).flush();
|
||||
|
||||
interpret(t.as(t.alpha), printer).flush();
|
||||
interpret(t.as(t.alpha).beta, printer).flush();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user