mirror of
https://github.com/rbock/sqlpp11.git
synced 2026-01-01 18:51:15 -06:00
Continued to implement standard serializing interpreters
Everything that is interpreted also has to move out of detail namespace, because it might have to be specialized for a database connector
This commit is contained in:
@@ -85,9 +85,10 @@ namespace sqlpp
|
||||
{
|
||||
using T = column_t<Args...>;
|
||||
template<typename Context>
|
||||
static void _(const T& t, Context& context)
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << T::_table::_name_t::_get_name() << '.' << T::_name_t::_get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -29,12 +29,11 @@
|
||||
|
||||
#include <sstream>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/interpret_tuple.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename First, typename... Args>
|
||||
struct concat_t: public First::_value_type::template operators<concat_t<First, Args...>>
|
||||
{
|
||||
@@ -71,31 +70,27 @@ namespace sqlpp
|
||||
concat_t& operator=(concat_t&&) = default;
|
||||
~concat_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_use_concat_operator or Db::_use_concat_function, "neither concat operator nor concat function supported by current database");
|
||||
if (Db::_use_concat_operator)
|
||||
{
|
||||
os << "(";
|
||||
detail::serialize_tuple(os, db, _args, "||");
|
||||
os << ")";
|
||||
}
|
||||
else if (Db::_use_concat_function)
|
||||
{
|
||||
os << "CONCAT(";
|
||||
detail::serialize_tuple(os, db, _args, ',');
|
||||
os << ")";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::tuple<First, Args...> _args;
|
||||
};
|
||||
}
|
||||
|
||||
//FIXME: Write partial specialization for mysql
|
||||
template<typename Db, typename First, typename... Args>
|
||||
struct interpreter_t<Db, concat_t<First, Args...>>
|
||||
{
|
||||
using T = concat_t<First, Args...>;
|
||||
template<typename Context>
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
interpret_tuple(t._args, "||", context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename... T>
|
||||
auto concat(T&&... t) -> typename detail::concat_t<typename operand_t<T, is_text_t>::type...>
|
||||
auto concat(T&&... t) -> concat_t<typename operand_t<T, is_text_t>::type...>
|
||||
{
|
||||
return { std::forward<T>(t)... };
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#ifndef SQLPP_DETAIL_BASIC_OPERATORS_H
|
||||
#define SQLPP_DETAIL_BASIC_OPERATORS_H
|
||||
|
||||
#include <sqlpp11/expression.h>
|
||||
#include <sqlpp11/expression_fwd.h>
|
||||
#include <sqlpp11/alias.h>
|
||||
#include <sqlpp11/sort_order.h>
|
||||
#include <sqlpp11/in.h>
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* 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_DETAIL_SERIALIZE_TUPLE_H
|
||||
#define SQLPP_DETAIL_SERIALIZE_TUPLE_H
|
||||
|
||||
#include <tuple>
|
||||
#include <ostream>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<std::size_t begin, std::size_t index, std::size_t end>
|
||||
struct tuple_serializer_impl
|
||||
{
|
||||
template<typename Db, typename Tuple, typename Separator>
|
||||
static void serialize(std::ostream& os, Db& db, const Tuple& flags_and_columns, const Separator& separator)
|
||||
{
|
||||
if (index > begin)
|
||||
os << separator;
|
||||
const auto& entry = std::get<index>(flags_and_columns);
|
||||
using entry_type = typename std::tuple_element<index, Tuple>::type;
|
||||
if (requires_braces_t<entry_type>::value)
|
||||
os << "(";
|
||||
entry.serialize(os, db);
|
||||
if (requires_braces_t<entry_type>::value)
|
||||
os << ")";
|
||||
tuple_serializer_impl<begin, index + 1, end>::serialize(os, db, flags_and_columns, separator);
|
||||
}
|
||||
};
|
||||
template<std::size_t begin, std::size_t end>
|
||||
struct tuple_serializer_impl<begin, end, end>
|
||||
{
|
||||
template<typename Db, typename Tuple, typename Separator>
|
||||
static void serialize(std::ostream& os, Db& db, const Tuple& flags_and_columns, const Separator& separator)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Db, typename Tuple, typename Separator>
|
||||
static void serialize_tuple(std::ostream& os, Db& db, const Tuple& flags_and_columns, const Separator& separator)
|
||||
{
|
||||
tuple_serializer_impl<0, 0, std::tuple_size<Tuple>::value>::serialize(os, db, flags_and_columns, separator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -27,7 +27,6 @@
|
||||
#ifndef SQLPP_DETAIL_WRAP_OPERAND_H
|
||||
#define SQLPP_DETAIL_WRAP_OPERAND_H
|
||||
|
||||
#include <ostream>
|
||||
#include <sqlpp11/interpreter.h>
|
||||
|
||||
// FIXME: must leave detail, since it is interpreted (and might require specializations)
|
||||
@@ -42,63 +41,48 @@ namespace sqlpp
|
||||
struct text;
|
||||
}
|
||||
|
||||
struct bool_operand
|
||||
struct boolean_operand
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = detail::boolean;
|
||||
|
||||
bool_operand(bool t): _t(t) {}
|
||||
bool_operand(const bool_operand&) = default;
|
||||
bool_operand(bool_operand&&) = default;
|
||||
bool_operand& operator=(const bool_operand&) = default;
|
||||
bool_operand& operator=(bool_operand&&) = default;
|
||||
~bool_operand() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << _t;
|
||||
}
|
||||
|
||||
bool _is_trivial() const { return _t == false; }
|
||||
|
||||
bool _t;
|
||||
};
|
||||
|
||||
template<typename Db>
|
||||
struct interpreter_t<Db, boolean_operand>
|
||||
{
|
||||
using Operand = boolean_operand;
|
||||
template<typename Context>
|
||||
static void _(const Operand& t, Context& context)
|
||||
{
|
||||
context << t._t;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct integral_operand
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = detail::integral;
|
||||
|
||||
integral_operand(T t): _t(t) {}
|
||||
integral_operand(const integral_operand&) = default;
|
||||
integral_operand(integral_operand&&) = default;
|
||||
integral_operand& operator=(const integral_operand&) = default;
|
||||
integral_operand& operator=(integral_operand&&) = default;
|
||||
~integral_operand() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << _t;
|
||||
}
|
||||
|
||||
bool _is_trivial() const { return _t == 0; }
|
||||
|
||||
T _t;
|
||||
};
|
||||
|
||||
template<typename Db, typename T>
|
||||
struct interpreter_t<Db, integral_operand<T>>
|
||||
{
|
||||
using Operand = integral_operand<T>;
|
||||
template<typename Context>
|
||||
static void _(const Operand& t, Context& context)
|
||||
{
|
||||
context << t._t;
|
||||
}
|
||||
};
|
||||
template<typename Db, typename T>
|
||||
struct interpreter_t<Db, integral_operand<T>>
|
||||
{
|
||||
using Operand = integral_operand<T>;
|
||||
template<typename Context>
|
||||
static void _(const Operand& t, Context& context)
|
||||
{
|
||||
context << t._t;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
@@ -107,48 +91,43 @@ namespace sqlpp
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = detail::floating_point;
|
||||
|
||||
floating_point_operand(T t): _t(t) {}
|
||||
floating_point_operand(const floating_point_operand&) = default;
|
||||
floating_point_operand(floating_point_operand&&) = default;
|
||||
floating_point_operand& operator=(const floating_point_operand&) = default;
|
||||
floating_point_operand& operator=(floating_point_operand&&) = default;
|
||||
~floating_point_operand() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << _t;
|
||||
}
|
||||
|
||||
bool _is_trivial() const { return _t == 0; }
|
||||
|
||||
T _t;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
template<typename Db, typename T>
|
||||
struct interpreter_t<Db, floating_point_operand<T>>
|
||||
{
|
||||
using Operand = floating_point_operand<T>;
|
||||
template<typename Context>
|
||||
static void _(const Operand& t, Context& context)
|
||||
{
|
||||
context << t._t;
|
||||
}
|
||||
};
|
||||
|
||||
struct text_operand
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = detail::text;
|
||||
|
||||
text_operand(const T& t): _t(t) {}
|
||||
text_operand(const text_operand&) = default;
|
||||
text_operand(text_operand&&) = default;
|
||||
text_operand& operator=(const text_operand&) = default;
|
||||
text_operand& operator=(text_operand&&) = default;
|
||||
~text_operand() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << '\'' << db.escape(_t) << '\'';
|
||||
}
|
||||
|
||||
bool _is_trivial() const { return _t.empty(); }
|
||||
|
||||
std::string _t;
|
||||
};
|
||||
|
||||
template<typename Db>
|
||||
struct interpreter_t<Db, text_operand>
|
||||
{
|
||||
using Operand = text_operand;
|
||||
template<typename Context>
|
||||
static void _(const Operand& t, Context& context)
|
||||
{
|
||||
context << '\'' << context.escape(t._t) << '\'';
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename Enable = void>
|
||||
struct wrap_operand
|
||||
{
|
||||
@@ -158,7 +137,7 @@ namespace sqlpp
|
||||
template<>
|
||||
struct wrap_operand<bool, void>
|
||||
{
|
||||
using type = bool_operand;
|
||||
using type = boolean_operand;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@@ -176,7 +155,7 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_convertible<T, std::string>::value>::type>
|
||||
{
|
||||
using type = text_operand<T>;
|
||||
using type = text_operand;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,9 @@
|
||||
#define SQLPP_EXPRESSION_H
|
||||
|
||||
#include <sqlpp11/alias.h>
|
||||
#include <sqlpp11/boolean.h>
|
||||
#include <sqlpp11/noop.h>
|
||||
#include <sqlpp11/expression_fwd.h>
|
||||
#include <sqlpp11/interpreter.h>
|
||||
#include <sqlpp11/detail/wrap_operand.h>
|
||||
#include <sqlpp11/detail/serialize_tuple.h>
|
||||
@@ -51,7 +53,7 @@ namespace sqlpp
|
||||
{
|
||||
using T = assignment_t<Lhs, Rhs>;
|
||||
template<typename Context>
|
||||
static void _(const T& t, Context& context)
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
interpret(t._lhs, context);
|
||||
if (trivial_value_is_null_t<Lhs>::value and t._rhs._is_trivial())
|
||||
@@ -63,14 +65,15 @@ namespace sqlpp
|
||||
context << "=";
|
||||
interpret(t._rhs, context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Lhs, typename Rhs, typename ValueType = detail::boolean>
|
||||
struct equal_t: public ValueType::template operators<equal_t<Lhs, Rhs>>
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct equal_t: public detail::boolean::template operators<equal_t<Lhs, Rhs>>
|
||||
{
|
||||
using _value_type = ValueType; // FIXME: Can we use boolean directly here?
|
||||
using _value_type = detail::boolean;
|
||||
|
||||
template<typename L, typename R>
|
||||
equal_t(L&& l, R&& r):
|
||||
@@ -89,16 +92,16 @@ namespace sqlpp
|
||||
Rhs _rhs;
|
||||
};
|
||||
|
||||
template<typename Db, typename... Args>
|
||||
struct interpreter_t<Db, equal_t<Args...>>
|
||||
template<typename Db, typename Lhs, typename Rhs>
|
||||
struct interpreter_t<Db, equal_t<Lhs, Rhs>>
|
||||
{
|
||||
using T = equal_t<Args...>;
|
||||
using T = equal_t<Lhs, Rhs>;
|
||||
template<typename Context>
|
||||
static void interpret(const T& t, Context& context)
|
||||
static Context& interpret(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
interpret(t._lhs, context);
|
||||
if (trivial_value_is_null_t<typename T::Lhs>::value and t._rhs._is_trivial())
|
||||
if (trivial_value_is_null_t<Lhs>::value and t._rhs._is_trivial())
|
||||
{
|
||||
context << "IS NULL";
|
||||
}
|
||||
@@ -108,13 +111,14 @@ namespace sqlpp
|
||||
interpret(t._rhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename ValueType = detail::boolean>
|
||||
struct not_equal_t: public ValueType::template operators<not_equal_t<Lhs, Rhs>>
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct not_equal_t: public detail::boolean::template operators<not_equal_t<Lhs, Rhs>>
|
||||
{
|
||||
using _value_type = ValueType;
|
||||
using _value_type = detail::boolean;
|
||||
|
||||
template<typename L, typename R>
|
||||
not_equal_t(L&& l, R&& r):
|
||||
@@ -132,16 +136,16 @@ namespace sqlpp
|
||||
Rhs _rhs;
|
||||
};
|
||||
|
||||
template<typename Db, typename... Args>
|
||||
struct interpreter_t<Db, not_equal_t<Args...>>
|
||||
template<typename Db, typename Lhs, typename Rhs>
|
||||
struct interpreter_t<Db, not_equal_t<Lhs, Rhs>>
|
||||
{
|
||||
using T = not_equal_t<Args...>;
|
||||
using T = not_equal_t<Lhs, Rhs>;
|
||||
template<typename Context>
|
||||
static void interpret(const T& t, Context& context)
|
||||
static Context& interpret(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
interpret(t._lhs, context);
|
||||
if (trivial_value_is_null_t<typename T::Lhs>::value and t._rhs._is_trivial())
|
||||
if (trivial_value_is_null_t<Lhs>::value and t._rhs._is_trivial())
|
||||
{
|
||||
context << "IS NOT NULL";
|
||||
}
|
||||
@@ -151,13 +155,14 @@ namespace sqlpp
|
||||
interpret(t._rhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename ValueType = detail::boolean>
|
||||
struct not_t: public ValueType::template operators<not_t<Lhs>>
|
||||
template<typename Lhs>
|
||||
struct not_t: public detail::boolean::template operators<not_t<Lhs>>
|
||||
{
|
||||
using _value_type = ValueType;
|
||||
using _value_type = detail::boolean;
|
||||
|
||||
not_t(Lhs l):
|
||||
_lhs(l)
|
||||
@@ -172,15 +177,15 @@ namespace sqlpp
|
||||
Lhs _lhs;
|
||||
};
|
||||
|
||||
template<typename Db, typename... Args>
|
||||
struct interpreter_t<Db, not_t<Args...>>
|
||||
template<typename Db, typename Lhs>
|
||||
struct interpreter_t<Db, not_t<Lhs>>
|
||||
{
|
||||
using T = not_t<Args...>;
|
||||
using T = not_t<Lhs>;
|
||||
template<typename Context>
|
||||
static void interpret(const T& t, Context& context)
|
||||
static Context& interpret(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
if (trivial_value_is_null_t<typename T::Lhs>::value and t._lhs._is_trivial())
|
||||
if (trivial_value_is_null_t<Lhs>::value and t._lhs._is_trivial())
|
||||
{
|
||||
interpret(t._lhs, context);
|
||||
context << "IS NULL";
|
||||
@@ -191,6 +196,7 @@ namespace sqlpp
|
||||
interpret(t._lhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -214,18 +220,19 @@ namespace sqlpp
|
||||
Rhs _rhs;
|
||||
};
|
||||
|
||||
template<typename Db, typename... Args>
|
||||
struct interpreter_t<Db, binary_expression_t<Args...>>
|
||||
template<typename Db, typename Lhs, typename O, typename Rhs>
|
||||
struct interpreter_t<Db, binary_expression_t<Lhs, O, Rhs>>
|
||||
{
|
||||
using T = binary_expression_t<Args...>;
|
||||
using T = binary_expression_t<Lhs, O, Rhs>;
|
||||
template<typename Context>
|
||||
static void interpret(const T& t, Context& context)
|
||||
static Context& interpret(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
interpret(t._lhs, context);
|
||||
context << T::O::_name;
|
||||
interpret(t._rhs, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -29,11 +29,20 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename T>
|
||||
struct is_expression_t;
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct assignment_t;
|
||||
|
||||
template<typename T>
|
||||
struct is_named_expression_t;
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct equal_t;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct not_equal_t;
|
||||
|
||||
template<typename Lhs>
|
||||
struct not_t;
|
||||
|
||||
template<typename Lhs, typename O, typename Rhs>
|
||||
struct binary_expression_t;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace sqlpp
|
||||
or (_inverted and Db::_supports_not_in), "in() and/or not_in() not supported by current database");
|
||||
_operand.serialize(os, db);
|
||||
os << (_inverted ? " NOT IN(" : " IN(");
|
||||
detail::serialize_tuple(os, db, _args, ',');
|
||||
serialize_tuple(os, db, _args, ',');
|
||||
os << ")";
|
||||
}
|
||||
|
||||
|
||||
77
include/sqlpp11/interpret_tuple.h
Normal file
77
include/sqlpp11/interpret_tuple.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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_INTERPRET_TUPLE_H
|
||||
#define SQLPP_INTERPRET_TUPLE_H
|
||||
|
||||
#include <tuple>
|
||||
#include <ostream>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Db, typename Tuple>
|
||||
struct tuple_interpreter_t
|
||||
{
|
||||
template<typename Separator, typename Context>
|
||||
static void _(const Tuple& t, const Separator& separator, Context& context)
|
||||
{
|
||||
_impl(t, separator, context, type<0>());
|
||||
};
|
||||
|
||||
private:
|
||||
template<size_t> struct type {};
|
||||
|
||||
template<typename Separator, typename Context, size_t index>
|
||||
static void _impl(const Tuple& t, const Separator& separator, Context& context, const type<index>&)
|
||||
{
|
||||
if (index)
|
||||
context << separator;
|
||||
const auto& entry = std::get<index>(t);
|
||||
using entry_type = typename std::tuple_element<index, Tuple>::type;
|
||||
if (requires_braces_t<entry_type>::value)
|
||||
context << "(";
|
||||
interpret(entry, context);
|
||||
if (requires_braces_t<entry_type>::value)
|
||||
context << ")";
|
||||
_impl(t, separator, context, type<index + 1>());
|
||||
}
|
||||
|
||||
template<typename Separator, typename Context>
|
||||
static void _impl(const Tuple& t, const Separator& separator, Context& context, const type<std::tuple_size<Tuple>::value>&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Tuple, typename Separator, typename Context>
|
||||
auto interpret_tuple(const Tuple& t, const Separator& separator, Context& context)
|
||||
-> decltype(tuple_interpreter_t<typename std::decay<Context>::type::_database_t, typename std::decay<Tuple>::type>::_(t, separator, context))
|
||||
{
|
||||
return tuple_interpreter_t<typename std::decay<Context>::type::_database_t, typename std::decay<Tuple>::type>::_(t, separator, context);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -42,11 +42,11 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context, typename T>
|
||||
void interpret(const T& t, Context& context)
|
||||
template<typename T, typename Context>
|
||||
auto interpret(const T& t, Context& context)
|
||||
-> decltype(interpreter_t<typename std::decay<Context>::type::_database_t, typename std::decay<T>::type>::_(t, context))
|
||||
{
|
||||
using Db = typename std::decay<Context>::type::_database_t;
|
||||
interpreter_t<Db, typename std::decay<T>::type>::_(t, context);
|
||||
return interpreter_t<typename std::decay<Context>::type::_database_t, typename std::decay<T>::type>::_(t, context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -196,10 +196,10 @@ namespace sqlpp
|
||||
struct operators: public basic_operators<Base, _constraint>
|
||||
{
|
||||
template<typename T>
|
||||
detail::concat_t<Base, typename _constraint<T>::type> operator+(T&& t) const
|
||||
concat_t<Base, typename _constraint<T>::type> operator+(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -36,8 +36,10 @@ int main()
|
||||
{
|
||||
TabSample t;
|
||||
|
||||
interpret(t.alpha, printer);
|
||||
interpret(t.alpha = 7, printer);
|
||||
interpret(t.alpha, printer).flush();
|
||||
interpret(t.alpha = 7, printer).flush();
|
||||
sqlpp::text_operand o = {"kaesekuchen"};
|
||||
interpret(t.beta + "kaesekuchen", printer).flush();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -39,11 +39,21 @@ public:
|
||||
{}
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(const T& t)
|
||||
std::ostream& operator<<(T t)
|
||||
{
|
||||
return _os << t;
|
||||
}
|
||||
|
||||
void flush()
|
||||
{
|
||||
_os << std::endl;
|
||||
}
|
||||
|
||||
std::string escape(std::string arg)
|
||||
{
|
||||
return arg;
|
||||
}
|
||||
|
||||
std::ostream& _os;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user