0
0
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:
rbock 2014-01-15 19:42:14 +01:00
parent 277ce51fb5
commit afcc62fc75
16 changed files with 266 additions and 174 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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,24 +97,29 @@ 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
_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: _container)
for (const auto& entry: t._container)
{
if (first)
first = false;
else
os << ',';
context << ',';
value(entry).serialize(os, db);
interpret(value(entry), context);
}
return context;
}
_container_t _container;
};
template<typename Container>

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View File

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