mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-16 04:47:18 +08:00
Merge branch 'feature/date_time2' into develop
This commit is contained in:
commit
d25ed57972
@ -29,7 +29,14 @@ enable_testing()
|
||||
|
||||
add_library(sqlpp11 INTERFACE)
|
||||
|
||||
set(DATE_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../date" CACHE FILEPATH "Path to Howard Hinnant's date library")
|
||||
|
||||
if(NOT EXISTS ${DATE_INCLUDE_DIR}/date.h)
|
||||
message(SEND_ERROR "Can't find date.h in ${DATE_INCLUDE_DIR}")
|
||||
endif()
|
||||
|
||||
target_include_directories(sqlpp11 INTERFACE
|
||||
$<BUILD_INTERFACE:${DATE_INCLUDE_DIR}>
|
||||
$<BUILD_INTERFACE:${sqlpp11_SOURCE_DIR}/include>
|
||||
)
|
||||
|
||||
|
@ -28,6 +28,9 @@
|
||||
#define SQLPP_DETAIL_BASIC_EXPRESSION_OPERATORS_H
|
||||
|
||||
#include <sqlpp11/value_type_fwd.h>
|
||||
#include <sqlpp11/bad_statement.h>
|
||||
#include <sqlpp11/portable_static_assert.h>
|
||||
#include <sqlpp11/consistent.h>
|
||||
#include <sqlpp11/alias.h>
|
||||
#include <sqlpp11/sort_order.h>
|
||||
#include <sqlpp11/expression_fwd.h>
|
||||
@ -38,72 +41,145 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
SQLPP_PORTABLE_STATIC_ASSERT(assert_valid_rhs_comparison_operand_t, "invalid rhs operand in comparison");
|
||||
|
||||
template <typename LhsValueType, typename RhsType>
|
||||
using check_rhs_comparison_operand_t =
|
||||
static_check_t<(is_expression_t<sqlpp::wrap_operand_t<RhsType>>::value // expressions are OK
|
||||
or
|
||||
is_multi_expression_t<sqlpp::wrap_operand_t<RhsType>>::value) // multi-expressions like ANY are
|
||||
// OK for comparisons, too
|
||||
and
|
||||
LhsValueType::template _is_valid_operand<
|
||||
sqlpp::wrap_operand_t<RhsType>>::value, // the correct value type is required, of course
|
||||
assert_valid_rhs_comparison_operand_t>;
|
||||
|
||||
SQLPP_PORTABLE_STATIC_ASSERT(assert_valid_in_arguments_t, "at least one operand of in() is not valid");
|
||||
|
||||
template <typename LhsValueType, typename... InTypes>
|
||||
using check_rhs_in_arguments_t =
|
||||
static_check_t<logic::all_t<check_rhs_comparison_operand_t<LhsValueType, InTypes>::value...>::value,
|
||||
assert_valid_in_arguments_t>;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <bool Enable, template <typename Lhs> class Expr, typename Lhs>
|
||||
struct new_unary_expression_impl
|
||||
{
|
||||
using type = bad_statement;
|
||||
};
|
||||
|
||||
template <template <typename Lhs> class Expr, typename Lhs>
|
||||
struct new_unary_expression_impl<true, Expr, Lhs>
|
||||
{
|
||||
using type = Expr<Lhs>;
|
||||
};
|
||||
}
|
||||
template <typename Check, template <typename Lhs> class Expr, typename Lhs>
|
||||
using new_unary_expression_t = typename detail::new_unary_expression_impl<Check::value, Expr, Lhs>::type;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <bool Enable, template <typename Lhs, typename Rhs> class Expr, typename Lhs, typename Rhs>
|
||||
struct new_binary_expression_impl
|
||||
{
|
||||
using type = bad_statement;
|
||||
};
|
||||
|
||||
template <template <typename Lhs, typename Rhs> class Expr, typename Lhs, typename Rhs>
|
||||
struct new_binary_expression_impl<true, Expr, Lhs, Rhs>
|
||||
{
|
||||
using type = Expr<Lhs, Rhs>;
|
||||
};
|
||||
}
|
||||
template <typename Check, template <typename Lhs, typename Rhs> class Expr, typename Lhs, typename Rhs>
|
||||
using new_binary_expression_t = typename detail::new_binary_expression_impl<Check::value, Expr, Lhs, Rhs>::type;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <bool Enable, template <typename Lhs, typename... Rhs> class Expr, typename Lhs, typename... Rhs>
|
||||
struct new_nary_expression_impl
|
||||
{
|
||||
using type = bad_statement;
|
||||
};
|
||||
|
||||
template <template <typename Lhs, typename... Rhs> class Expr, typename Lhs, typename... Rhs>
|
||||
struct new_nary_expression_impl<true, Expr, Lhs, Rhs...>
|
||||
{
|
||||
using type = Expr<Lhs, Rhs...>;
|
||||
};
|
||||
}
|
||||
template <typename Check, template <typename Lhs, typename... Rhs> class Expr, typename Lhs, typename... Rhs>
|
||||
using new_nary_expression_t = typename detail::new_nary_expression_impl<Check::value, Expr, Lhs, Rhs...>::type;
|
||||
|
||||
// basic operators
|
||||
template <typename Expr, typename ValueType>
|
||||
struct basic_expression_operators
|
||||
{
|
||||
template <typename T>
|
||||
struct _is_valid_comparison_operand
|
||||
{
|
||||
static constexpr bool value =
|
||||
(is_expression_t<T>::value // expressions are OK
|
||||
or
|
||||
is_multi_expression_t<T>::value) // multi-expressions like ANY are OK for comparisons, too
|
||||
and
|
||||
ValueType::template _is_valid_operand<T>::value // the correct value type is required, of course
|
||||
;
|
||||
};
|
||||
template <template <typename Lhs, typename Rhs> class NewExpr, typename T>
|
||||
using _new_binary_expression_t =
|
||||
new_binary_expression_t<check_rhs_comparison_operand_t<ValueType, wrap_operand_t<T>>,
|
||||
NewExpr,
|
||||
Expr,
|
||||
wrap_operand_t<T>>;
|
||||
|
||||
template <template <typename Lhs, typename... Rhs> class NewExpr, typename... T>
|
||||
using _new_nary_expression_t =
|
||||
new_nary_expression_t<logic::all_t<check_rhs_comparison_operand_t<ValueType, wrap_operand_t<T>>::value...>,
|
||||
NewExpr,
|
||||
Expr,
|
||||
wrap_operand_t<T>...>;
|
||||
|
||||
template <typename T>
|
||||
equal_to_t<Expr, wrap_operand_t<T>> operator==(T t) const
|
||||
_new_binary_expression_t<equal_to_t, T> operator==(T t) const
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
|
||||
check_rhs_comparison_operand_t<ValueType, rhs>::_();
|
||||
|
||||
return {*static_cast<const Expr*>(this), {rhs{t}}};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
not_equal_to_t<Expr, wrap_operand_t<T>> operator!=(T t) const
|
||||
_new_binary_expression_t<not_equal_to_t, T> operator!=(T t) const
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
|
||||
check_rhs_comparison_operand_t<ValueType, rhs>::_();
|
||||
|
||||
return {*static_cast<const Expr*>(this), {rhs{t}}};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
less_than_t<Expr, wrap_operand_t<T>> operator<(T t) const
|
||||
_new_binary_expression_t<less_than_t, T> operator<(T t) const
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
|
||||
check_rhs_comparison_operand_t<ValueType, rhs>::_();
|
||||
|
||||
return {*static_cast<const Expr*>(this), rhs{t}};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
less_equal_t<Expr, wrap_operand_t<T>> operator<=(T t) const
|
||||
_new_binary_expression_t<less_equal_t, T> operator<=(T t) const
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
|
||||
check_rhs_comparison_operand_t<ValueType, rhs>::_();
|
||||
|
||||
return {*static_cast<const Expr*>(this), rhs{t}};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
greater_than_t<Expr, wrap_operand_t<T>> operator>(T t) const
|
||||
_new_binary_expression_t<greater_than_t, T> operator>(T t) const
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
|
||||
check_rhs_comparison_operand_t<ValueType, rhs>::_();
|
||||
|
||||
return {*static_cast<const Expr*>(this), rhs{t}};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
greater_equal_t<Expr, wrap_operand_t<T>> operator>=(T t) const
|
||||
_new_binary_expression_t<greater_equal_t, T> operator>=(T t) const
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
|
||||
check_rhs_comparison_operand_t<ValueType, rhs>::_();
|
||||
|
||||
return {*static_cast<const Expr*>(this), rhs{t}};
|
||||
}
|
||||
@ -130,18 +206,16 @@ namespace sqlpp
|
||||
|
||||
// Hint: use value_list wrapper for containers...
|
||||
template <typename... T>
|
||||
in_t<Expr, wrap_operand_t<T>...> in(T... t) const
|
||||
_new_nary_expression_t<in_t, T...> in(T... t) const
|
||||
{
|
||||
static_assert(logic::all_t<_is_valid_comparison_operand<wrap_operand_t<T>>::value...>::value,
|
||||
"at least one operand of in() is not valid");
|
||||
check_rhs_in_arguments_t<ValueType, wrap_operand_t<T>...>::_();
|
||||
return {*static_cast<const Expr*>(this), wrap_operand_t<T>{t}...};
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
not_in_t<Expr, wrap_operand_t<T>...> not_in(T... t) const
|
||||
_new_nary_expression_t<not_in_t, T...> not_in(T... t) const
|
||||
{
|
||||
static_assert(logic::all_t<_is_valid_comparison_operand<wrap_operand_t<T>>::value...>::value,
|
||||
"at least one operand of in() is not valid");
|
||||
check_rhs_in_arguments_t<ValueType, wrap_operand_t<T>...>::_();
|
||||
return {*static_cast<const Expr*>(this), wrap_operand_t<T>{t}...};
|
||||
}
|
||||
};
|
||||
|
@ -62,6 +62,8 @@ namespace sqlpp
|
||||
|
||||
template <typename T>
|
||||
using _is_valid_operand = is_valid_operand<value_type_of<ColumnSpec>, T>;
|
||||
template <typename T>
|
||||
using _is_valid_assignment_operand = is_valid_assignment_operand<value_type_of<ColumnSpec>, T>;
|
||||
|
||||
column_t() = default;
|
||||
column_t(const column_t&) = default;
|
||||
@ -87,7 +89,7 @@ namespace sqlpp
|
||||
auto operator=(T t) const -> assignment_t<column_t, wrap_operand_t<T>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
static_assert(_is_valid_assignment_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
|
||||
return {*this, {rhs{t}}};
|
||||
}
|
||||
|
@ -28,6 +28,8 @@
|
||||
#define SQLPP_COLUMN_TYPES_H
|
||||
|
||||
#include <sqlpp11/boolean.h>
|
||||
#include <sqlpp11/day_point.h>
|
||||
#include <sqlpp11/time_point.h>
|
||||
#include <sqlpp11/integral.h>
|
||||
#include <sqlpp11/floating_point.h>
|
||||
#include <sqlpp11/text.h>
|
||||
|
43
include/sqlpp11/consistent.h
Normal file
43
include/sqlpp11/consistent.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, 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_CONSISTENT_H
|
||||
#define SQLPP_CONSISTENT_H
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
struct consistent_t
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
using type = std::true_type;
|
||||
|
||||
static void _(){};
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
46
include/sqlpp11/date_time_fwd.h
Normal file
46
include/sqlpp11/date_time_fwd.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2015, 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_DATE_FWD_H
|
||||
#define SQLPP_DATE_FWD_H
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace chrono
|
||||
{
|
||||
using days = std::chrono::duration<int, std::ratio_multiply<std::ratio<24>, std::chrono::hours::period>>;
|
||||
|
||||
using day_point = std::chrono::time_point<std::chrono::system_clock, days>;
|
||||
using mus_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::microseconds>;
|
||||
}
|
||||
|
||||
struct day_point;
|
||||
struct time_point;
|
||||
}
|
||||
|
||||
#endif
|
236
include/sqlpp11/day_point.h
Normal file
236
include/sqlpp11/day_point.h
Normal file
@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2015, 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_DAY_POINT_H
|
||||
#define SQLPP_DAY_POINT_H
|
||||
|
||||
#include <date.h>
|
||||
#include <sqlpp11/time_point.h>
|
||||
#include <sqlpp11/basic_expression_operators.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/exception.h>
|
||||
#include <sqlpp11/value_type.h>
|
||||
#include <sqlpp11/assignment.h>
|
||||
#include <sqlpp11/result_field.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
// day_point value type
|
||||
struct day_point
|
||||
{
|
||||
using _traits = make_traits<day_point, tag::is_value_type>;
|
||||
using _tag = tag::is_date;
|
||||
using _cpp_value_type = ::sqlpp::chrono::day_point;
|
||||
|
||||
template <typename T>
|
||||
using _is_valid_operand = is_time_point_t<T>;
|
||||
template <typename T>
|
||||
using _is_valid_assignment_operand = is_date_t<T>;
|
||||
};
|
||||
|
||||
// day_point parameter value
|
||||
template <>
|
||||
struct parameter_value_t<day_point>
|
||||
{
|
||||
using _value_type = day_point;
|
||||
using _cpp_value_type = typename _value_type::_cpp_value_type;
|
||||
|
||||
parameter_value_t() : _value{}, _is_null(true)
|
||||
{
|
||||
}
|
||||
|
||||
explicit parameter_value_t(const _cpp_value_type& val) : _value(val), _is_null(false)
|
||||
{
|
||||
}
|
||||
|
||||
parameter_value_t& operator=(const _cpp_value_type& val)
|
||||
{
|
||||
_value = val;
|
||||
_is_null = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
parameter_value_t& operator=(const tvin_t<wrap_operand_t<_cpp_value_type>>& t)
|
||||
{
|
||||
if (t._is_trivial())
|
||||
{
|
||||
_value = _cpp_value_type{};
|
||||
_is_null = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_value = t._value._t;
|
||||
_is_null = false;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void set_null()
|
||||
{
|
||||
_value = _cpp_value_type{};
|
||||
_is_null = true;
|
||||
}
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
const _cpp_value_type& value() const
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
operator _cpp_value_type() const
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
template <typename Target>
|
||||
void _bind(Target& target, size_t index) const
|
||||
{
|
||||
target._bind_date_parameter(index, &_value, _is_null);
|
||||
}
|
||||
|
||||
private:
|
||||
_cpp_value_type _value;
|
||||
bool _is_null;
|
||||
};
|
||||
|
||||
// day_point expression operators
|
||||
template <typename Base>
|
||||
struct expression_operators<Base, day_point> : public basic_expression_operators<Base, day_point>
|
||||
{
|
||||
template <typename T>
|
||||
using _is_valid_operand = is_valid_operand<day_point, T>;
|
||||
};
|
||||
|
||||
// day_point column operators
|
||||
template <typename Base>
|
||||
struct column_operators<Base, day_point>
|
||||
{
|
||||
template <typename T>
|
||||
using _is_valid_operand = is_valid_operand<day_point, T>;
|
||||
};
|
||||
|
||||
// day_point result field
|
||||
template <typename Db, typename FieldSpec>
|
||||
struct result_field_t<day_point, Db, FieldSpec>
|
||||
: public result_field_methods_t<result_field_t<day_point, Db, FieldSpec>>
|
||||
{
|
||||
static_assert(std::is_same<value_type_of<FieldSpec>, day_point>::value, "field type mismatch");
|
||||
using _cpp_value_type = typename sqlpp::day_point::_cpp_value_type;
|
||||
|
||||
result_field_t() : _is_valid(false), _is_null(true), _value{}
|
||||
{
|
||||
}
|
||||
|
||||
void _invalidate()
|
||||
{
|
||||
_is_valid = false;
|
||||
_is_null = true;
|
||||
_value = _cpp_value_type{};
|
||||
}
|
||||
|
||||
void _validate()
|
||||
{
|
||||
_is_valid = true;
|
||||
}
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
bool _is_trivial() const
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
|
||||
return value() == _cpp_value_type{};
|
||||
}
|
||||
|
||||
_cpp_value_type value() const
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
|
||||
if (_is_null)
|
||||
{
|
||||
if (enforce_null_result_treatment_t<Db>::value and not null_is_trivial_value_t<FieldSpec>::value)
|
||||
{
|
||||
throw exception("accessing value of NULL field");
|
||||
}
|
||||
else
|
||||
{
|
||||
return _cpp_value_type{};
|
||||
}
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
template <typename Target>
|
||||
void _bind(Target& target, size_t i)
|
||||
{
|
||||
target._bind_date_result(i, &_value, &_is_null);
|
||||
}
|
||||
|
||||
private:
|
||||
bool _is_valid;
|
||||
bool _is_null;
|
||||
_cpp_value_type _value;
|
||||
};
|
||||
|
||||
template <typename Context, typename Db, typename FieldSpec>
|
||||
struct serializer_t<Context, result_field_t<day_point, Db, FieldSpec>>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using T = result_field_t<day_point, Db, FieldSpec>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (t.is_null() and not null_is_trivial_value_t<FieldSpec>::value)
|
||||
{
|
||||
context << "NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto ymd = ::date::year_month_day{t.value()};
|
||||
context << ymd;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Db, typename FieldSpec>
|
||||
inline std::ostream& operator<<(std::ostream& os, const result_field_t<day_point, Db, FieldSpec>& e)
|
||||
{
|
||||
return serialize(e, os);
|
||||
}
|
||||
}
|
||||
#endif
|
@ -28,6 +28,7 @@
|
||||
#define SQLPP_INSERT_VALUE_LIST_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/portable_static_assert.h>
|
||||
#include <sqlpp11/logic.h>
|
||||
#include <sqlpp11/column_fwd.h>
|
||||
#include <sqlpp11/assignment.h>
|
||||
@ -127,64 +128,6 @@ namespace sqlpp
|
||||
interpretable_list_t<Database> _dynamic_values;
|
||||
};
|
||||
|
||||
#define SQLPP_PORTABLE_STATIC_ASSERT(name, message) \
|
||||
struct name \
|
||||
{ \
|
||||
static constexpr bool value = false; \
|
||||
using type = std::false_type; \
|
||||
\
|
||||
template <typename T = void> \
|
||||
static void _() \
|
||||
{ \
|
||||
static_assert(wrong_t<T>::value, message); \
|
||||
} \
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <bool Consistent, typename Assert>
|
||||
struct static_check_impl
|
||||
{
|
||||
using type = Assert;
|
||||
};
|
||||
|
||||
template <typename Assert>
|
||||
struct static_check_impl<true, Assert>
|
||||
{
|
||||
using type = consistent_t;
|
||||
};
|
||||
}
|
||||
|
||||
template <bool Consistent, typename Assert>
|
||||
using static_check_t = typename detail::static_check_impl<Consistent, Assert>::type;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename... Asserts>
|
||||
struct static_combined_check_impl;
|
||||
|
||||
template <typename Assert, typename... Rest>
|
||||
struct static_combined_check_impl<Assert, Rest...>
|
||||
{
|
||||
using type = Assert;
|
||||
};
|
||||
|
||||
template <typename... Rest>
|
||||
struct static_combined_check_impl<consistent_t, Rest...>
|
||||
{
|
||||
using type = typename static_combined_check_impl<Rest...>::type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct static_combined_check_impl<>
|
||||
{
|
||||
using type = consistent_t;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename... Asserts>
|
||||
using static_combined_check_t = typename detail::static_combined_check_impl<Asserts...>::type;
|
||||
|
||||
SQLPP_PORTABLE_STATIC_ASSERT(assert_insert_set_assignments_t, "at least one argument is not an assignment in set()");
|
||||
SQLPP_PORTABLE_STATIC_ASSERT(assert_insert_set_no_duplicates_t, "at least one duplicate column detected in set()");
|
||||
SQLPP_PORTABLE_STATIC_ASSERT(assert_insert_set_prohibited_t,
|
||||
|
91
include/sqlpp11/portable_static_assert.h
Normal file
91
include/sqlpp11/portable_static_assert.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2015, 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_PORTABLE_STATIC_ASSERT_H
|
||||
#define SQLPP_PORTABLE_STATIC_ASSERT_H
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
#define SQLPP_PORTABLE_STATIC_ASSERT(name, message) \
|
||||
struct name \
|
||||
{ \
|
||||
static constexpr bool value = false; \
|
||||
using type = std::false_type; \
|
||||
\
|
||||
template <typename T = void> \
|
||||
static void _() \
|
||||
{ \
|
||||
static_assert(wrong_t<T>::value, message); \
|
||||
} \
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <bool Consistent, typename Assert>
|
||||
struct static_check_impl
|
||||
{
|
||||
using type = Assert;
|
||||
};
|
||||
|
||||
template <typename Assert>
|
||||
struct static_check_impl<true, Assert>
|
||||
{
|
||||
using type = consistent_t;
|
||||
};
|
||||
}
|
||||
|
||||
template <bool Consistent, typename Assert>
|
||||
using static_check_t = typename detail::static_check_impl<Consistent, Assert>::type;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename... Asserts>
|
||||
struct static_combined_check_impl;
|
||||
|
||||
template <typename Assert, typename... Rest>
|
||||
struct static_combined_check_impl<Assert, Rest...>
|
||||
{
|
||||
using type = Assert;
|
||||
};
|
||||
|
||||
template <typename... Rest>
|
||||
struct static_combined_check_impl<consistent_t, Rest...>
|
||||
{
|
||||
using type = typename static_combined_check_impl<Rest...>::type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct static_combined_check_impl<>
|
||||
{
|
||||
using type = consistent_t;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename... Asserts>
|
||||
using static_combined_check_t = typename detail::static_combined_check_impl<Asserts...>::type;
|
||||
}
|
||||
|
||||
#endif
|
235
include/sqlpp11/time_point.h
Normal file
235
include/sqlpp11/time_point.h
Normal file
@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2015, 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_TIME_POINT_H
|
||||
#define SQLPP_TIME_POINT_H
|
||||
|
||||
#include <sqlpp11/date_time_fwd.h>
|
||||
#include <sqlpp11/basic_expression_operators.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/exception.h>
|
||||
#include <sqlpp11/value_type.h>
|
||||
#include <sqlpp11/assignment.h>
|
||||
#include <sqlpp11/result_field.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
// time_point value type
|
||||
struct time_point
|
||||
{
|
||||
using _traits = make_traits<time_point, tag::is_value_type>;
|
||||
using _tag = tag::is_date_time;
|
||||
using _cpp_value_type = ::sqlpp::chrono::mus_point;
|
||||
|
||||
template <typename T>
|
||||
using _is_valid_operand = is_time_point_t<T>;
|
||||
};
|
||||
|
||||
// time_point parameter value
|
||||
template <>
|
||||
struct parameter_value_t<time_point>
|
||||
{
|
||||
using _value_type = time_point;
|
||||
using _cpp_value_type = typename _value_type::_cpp_value_type;
|
||||
|
||||
parameter_value_t() : _value{}, _is_null(true)
|
||||
{
|
||||
}
|
||||
|
||||
explicit parameter_value_t(const _cpp_value_type& val) : _value(val), _is_null(false)
|
||||
{
|
||||
}
|
||||
|
||||
parameter_value_t& operator=(const _cpp_value_type& val)
|
||||
{
|
||||
_value = val;
|
||||
_is_null = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
parameter_value_t& operator=(const tvin_t<wrap_operand_t<_cpp_value_type>>& t)
|
||||
{
|
||||
if (t._is_trivial())
|
||||
{
|
||||
_value = _cpp_value_type{};
|
||||
_is_null = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_value = t._value._t;
|
||||
_is_null = false;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void set_null()
|
||||
{
|
||||
_value = _cpp_value_type{};
|
||||
_is_null = true;
|
||||
}
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
const _cpp_value_type& value() const
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
operator _cpp_value_type() const
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
template <typename Target>
|
||||
void _bind(Target& target, size_t index) const
|
||||
{
|
||||
target._bind_date_time_parameter(index, &_value, _is_null);
|
||||
}
|
||||
|
||||
private:
|
||||
_cpp_value_type _value;
|
||||
bool _is_null;
|
||||
};
|
||||
|
||||
// time_point expression operators
|
||||
template <typename Base>
|
||||
struct expression_operators<Base, time_point> : public basic_expression_operators<Base, time_point>
|
||||
{
|
||||
template <typename T>
|
||||
using _is_valid_operand = is_valid_operand<time_point, T>;
|
||||
};
|
||||
|
||||
// time_point column operators
|
||||
template <typename Base>
|
||||
struct column_operators<Base, time_point>
|
||||
{
|
||||
template <typename T>
|
||||
using _is_valid_operand = is_valid_operand<time_point, T>;
|
||||
};
|
||||
|
||||
// time_point result field
|
||||
template <typename Db, typename FieldSpec>
|
||||
struct result_field_t<time_point, Db, FieldSpec>
|
||||
: public result_field_methods_t<result_field_t<time_point, Db, FieldSpec>>
|
||||
{
|
||||
static_assert(std::is_same<value_type_of<FieldSpec>, time_point>::value, "field type mismatch");
|
||||
using _cpp_value_type = typename time_point::_cpp_value_type;
|
||||
|
||||
result_field_t() : _is_valid(false), _is_null(true), _value{}
|
||||
{
|
||||
}
|
||||
|
||||
void _invalidate()
|
||||
{
|
||||
_is_valid = false;
|
||||
_is_null = true;
|
||||
_value = _cpp_value_type{};
|
||||
}
|
||||
|
||||
void _validate()
|
||||
{
|
||||
_is_valid = true;
|
||||
}
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
bool _is_trivial() const
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
|
||||
return value() == _cpp_value_type{};
|
||||
}
|
||||
|
||||
_cpp_value_type value() const
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
|
||||
if (_is_null)
|
||||
{
|
||||
if (enforce_null_result_treatment_t<Db>::value and not null_is_trivial_value_t<FieldSpec>::value)
|
||||
{
|
||||
throw exception("accessing value of NULL field");
|
||||
}
|
||||
else
|
||||
{
|
||||
return _cpp_value_type{};
|
||||
}
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
template <typename Target>
|
||||
void _bind(Target& target, size_t i)
|
||||
{
|
||||
target._bind_date_time_result(i, &_value, &_is_null);
|
||||
}
|
||||
|
||||
private:
|
||||
bool _is_valid;
|
||||
bool _is_null;
|
||||
_cpp_value_type _value;
|
||||
};
|
||||
|
||||
template <typename Context, typename Db, typename FieldSpec>
|
||||
struct serializer_t<Context, result_field_t<time_point, Db, FieldSpec>>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using T = result_field_t<time_point, Db, FieldSpec>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (t.is_null() and not null_is_trivial_value_t<FieldSpec>::value)
|
||||
{
|
||||
context << "NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto dp = ::date::floor<::date::days>(t.value());
|
||||
const auto time = ::date::make_time(t.value() - dp);
|
||||
const auto ymd = ::date::year_month_day{dp};
|
||||
context << ymd << ' ' << time;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Db, typename FieldSpec>
|
||||
inline std::ostream& operator<<(std::ostream& os, const result_field_t<time_point, Db, FieldSpec>& e)
|
||||
{
|
||||
return serialize(e, os);
|
||||
}
|
||||
}
|
||||
#endif
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
#include <sqlpp11/consistent.h>
|
||||
#include <sqlpp11/serializer.h>
|
||||
#include <sqlpp11/detail/type_vector.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
@ -89,12 +90,18 @@ namespace sqlpp
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_value_type)
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_sql_null)
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_boolean)
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_date)
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_date_time)
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_integral)
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_floating_point)
|
||||
template <typename T>
|
||||
using is_numeric_t = logic::any_t<detail::is_element_of<tag::is_integral, typename T::_traits::_tags>::value,
|
||||
detail::is_element_of<tag::is_floating_point, typename T::_traits::_tags>::value>;
|
||||
|
||||
template <typename T>
|
||||
using is_time_point_t = logic::any_t<detail::is_element_of<tag::is_date, typename T::_traits::_tags>::value,
|
||||
detail::is_element_of<tag::is_date_time, typename T::_traits::_tags>::value>;
|
||||
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_text)
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_wrapped_value)
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_selectable)
|
||||
@ -300,14 +307,6 @@ namespace sqlpp
|
||||
template <typename Policies>
|
||||
using derived_statement_t = typename Policies::_statement_t;
|
||||
|
||||
struct consistent_t
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
using type = std::true_type;
|
||||
|
||||
static void _(){};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using is_inconsistent_t =
|
||||
typename std::conditional<std::is_same<consistent_t, T>::value, std::false_type, std::true_type>::type;
|
||||
|
@ -58,6 +58,27 @@ namespace sqlpp
|
||||
and ValueType::template _is_valid_operand<T>::value // the correct value type is required, of course
|
||||
;
|
||||
};
|
||||
|
||||
template <typename ValueType, typename T, typename Enable = void>
|
||||
struct is_valid_assignment_operand
|
||||
{
|
||||
static constexpr bool value =
|
||||
is_expression_t<T>::value // expressions are OK
|
||||
and ValueType::template _is_valid_operand<T>::value // the correct value type is required, of course
|
||||
;
|
||||
};
|
||||
|
||||
template <typename ValueType, typename T>
|
||||
struct is_valid_assignment_operand<
|
||||
ValueType,
|
||||
T,
|
||||
typename std::enable_if<std::is_class<typename ValueType::template _is_valid_assignment_operand<T>>::value>::type>
|
||||
{
|
||||
static constexpr bool value =
|
||||
is_expression_t<T>::value // expressions are OK
|
||||
and ValueType::template _is_valid_assignment_operand<T>::value // the correct value type is required, of course
|
||||
;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -27,7 +27,9 @@
|
||||
#ifndef SQLPP_DETAIL_WRAP_OPERAND_H
|
||||
#define SQLPP_DETAIL_WRAP_OPERAND_H
|
||||
|
||||
#include <date.h>
|
||||
#include <string>
|
||||
#include <sqlpp11/date_time_fwd.h>
|
||||
#include <sqlpp11/wrap_operand_fwd.h>
|
||||
#include <sqlpp11/serializer.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
@ -83,6 +85,97 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
struct day_point_operand : public alias_operators<day_point_operand>
|
||||
{
|
||||
using _traits = make_traits<day_point, tag::is_expression, tag::is_wrapped_value>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
using _is_aggregate_expression = std::true_type;
|
||||
|
||||
using _value_t = ::sqlpp::chrono::day_point;
|
||||
|
||||
day_point_operand() : _t{}
|
||||
{
|
||||
}
|
||||
|
||||
day_point_operand(_value_t t) : _t(t)
|
||||
{
|
||||
}
|
||||
|
||||
day_point_operand(const day_point_operand&) = default;
|
||||
day_point_operand(day_point_operand&&) = default;
|
||||
day_point_operand& operator=(const day_point_operand&) = default;
|
||||
day_point_operand& operator=(day_point_operand&&) = default;
|
||||
~day_point_operand() = default;
|
||||
|
||||
bool _is_trivial() const
|
||||
{
|
||||
return _t == _value_t{};
|
||||
}
|
||||
|
||||
_value_t _t;
|
||||
};
|
||||
|
||||
template <typename Context>
|
||||
struct serializer_t<Context, day_point_operand>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using Operand = day_point_operand;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
const auto ymd = ::date::year_month_day{t._t};
|
||||
context << "DATE '" << ymd << "'";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Period>
|
||||
struct time_point_operand : public alias_operators<time_point_operand<Period>>
|
||||
{
|
||||
using _traits = make_traits<time_point, tag::is_expression, tag::is_wrapped_value>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
using _is_aggregate_expression = std::true_type;
|
||||
|
||||
using _value_t = std::chrono::time_point<std::chrono::system_clock, Period>;
|
||||
|
||||
time_point_operand() : _t{}
|
||||
{
|
||||
}
|
||||
|
||||
time_point_operand(_value_t t) : _t(t)
|
||||
{
|
||||
}
|
||||
|
||||
time_point_operand(const time_point_operand&) = default;
|
||||
time_point_operand(time_point_operand&&) = default;
|
||||
time_point_operand& operator=(const time_point_operand&) = default;
|
||||
time_point_operand& operator=(time_point_operand&&) = default;
|
||||
~time_point_operand() = default;
|
||||
|
||||
bool _is_trivial() const
|
||||
{
|
||||
return _t == _value_t{};
|
||||
}
|
||||
|
||||
_value_t _t;
|
||||
};
|
||||
|
||||
template <typename Context, typename Period>
|
||||
struct serializer_t<Context, time_point_operand<Period>>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using Operand = time_point_operand<Period>;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
const auto dp = ::date::floor<::date::days>(t._t);
|
||||
const auto time = ::date::make_time(t._t - dp);
|
||||
const auto ymd = ::date::year_month_day{dp};
|
||||
context << "TIMESTAMP '" << ymd << ' ' << time << "'";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
struct integral_operand : public alias_operators<integral_operand>
|
||||
{
|
||||
using _traits = make_traits<integral, tag::is_expression, tag::is_wrapped_value>;
|
||||
@ -224,6 +317,18 @@ namespace sqlpp
|
||||
using type = boolean_operand;
|
||||
};
|
||||
|
||||
template <typename Period>
|
||||
struct wrap_operand<std::chrono::time_point<std::chrono::system_clock, Period>, void>
|
||||
{
|
||||
using type = time_point_operand<Period>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct wrap_operand<std::chrono::time_point<std::chrono::system_clock, sqlpp::chrono::days>, void>
|
||||
{
|
||||
using type = day_point_operand;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_integral<T>::value>::type>
|
||||
{
|
||||
|
@ -98,8 +98,11 @@ types = {
|
||||
'mediumblob': 'blob',
|
||||
'longblob': 'blob',
|
||||
'bool': 'boolean',
|
||||
'boolean': 'boolean',
|
||||
'double': 'floating_point',
|
||||
'float': 'floating_point',
|
||||
'date' : 'day_point',
|
||||
'datetime' : 'time_point',
|
||||
}
|
||||
|
||||
# PROCESS DDL
|
||||
@ -113,6 +116,7 @@ namespace = sys.argv[3]
|
||||
ddlFile = open(pathToDdl, 'r')
|
||||
header = open(pathToHeader, 'w')
|
||||
|
||||
print('// generated by ' + ' '.join(sys.argv), file=header)
|
||||
print('#ifndef '+get_include_guard_name(namespace, pathToHeader), file=header)
|
||||
print('#define '+get_include_guard_name(namespace, pathToHeader), file=header)
|
||||
print('', file=header)
|
||||
|
290
test_static_asserts/AssertTables.h
Normal file
290
test_static_asserts/AssertTables.h
Normal file
@ -0,0 +1,290 @@
|
||||
// generated by ../scripts/ddl2cpp ../test_static_asserts/AssertTables.sql ../test_static_asserts/AssertTables test
|
||||
#ifndef TEST_ASSERTTABLES_H
|
||||
#define TEST_ASSERTTABLES_H
|
||||
|
||||
#include <sqlpp11/table.h>
|
||||
#include <sqlpp11/column_types.h>
|
||||
#include <sqlpp11/char_sequence.h>
|
||||
|
||||
namespace test
|
||||
{
|
||||
namespace TabAllTypes_
|
||||
{
|
||||
struct SomeString
|
||||
{
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "some_string";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template <typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T someString;
|
||||
T& operator()()
|
||||
{
|
||||
return someString;
|
||||
}
|
||||
const T& operator()() const
|
||||
{
|
||||
return someString;
|
||||
}
|
||||
};
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::varchar, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
struct SomeInt
|
||||
{
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "some_int";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template <typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T someInt;
|
||||
T& operator()()
|
||||
{
|
||||
return someInt;
|
||||
}
|
||||
const T& operator()() const
|
||||
{
|
||||
return someInt;
|
||||
}
|
||||
};
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::bigint, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
struct SomeFloat
|
||||
{
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "some_float";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template <typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T someFloat;
|
||||
T& operator()()
|
||||
{
|
||||
return someFloat;
|
||||
}
|
||||
const T& operator()() const
|
||||
{
|
||||
return someFloat;
|
||||
}
|
||||
};
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::floating_point, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
struct SomeBool
|
||||
{
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "some_bool";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template <typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T someBool;
|
||||
T& operator()()
|
||||
{
|
||||
return someBool;
|
||||
}
|
||||
const T& operator()() const
|
||||
{
|
||||
return someBool;
|
||||
}
|
||||
};
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::boolean, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
struct SomeDayPoint
|
||||
{
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "some_day_point";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template <typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T someDayPoint;
|
||||
T& operator()()
|
||||
{
|
||||
return someDayPoint;
|
||||
}
|
||||
const T& operator()() const
|
||||
{
|
||||
return someDayPoint;
|
||||
}
|
||||
};
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::day_point, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
struct SomeTimePoint
|
||||
{
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "some_time_point";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template <typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T someTimePoint;
|
||||
T& operator()()
|
||||
{
|
||||
return someTimePoint;
|
||||
}
|
||||
const T& operator()() const
|
||||
{
|
||||
return someTimePoint;
|
||||
}
|
||||
};
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::time_point, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
struct OtherInt
|
||||
{
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "other_int";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template <typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T otherInt;
|
||||
T& operator()()
|
||||
{
|
||||
return otherInt;
|
||||
}
|
||||
const T& operator()() const
|
||||
{
|
||||
return otherInt;
|
||||
}
|
||||
};
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::bigint, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
struct OtherFloat
|
||||
{
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "other_float";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template <typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T otherFloat;
|
||||
T& operator()()
|
||||
{
|
||||
return otherFloat;
|
||||
}
|
||||
const T& operator()() const
|
||||
{
|
||||
return otherFloat;
|
||||
}
|
||||
};
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::floating_point, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
struct OtherBool
|
||||
{
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "other_bool";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template <typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T otherBool;
|
||||
T& operator()()
|
||||
{
|
||||
return otherBool;
|
||||
}
|
||||
const T& operator()() const
|
||||
{
|
||||
return otherBool;
|
||||
}
|
||||
};
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::boolean, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
struct OtherDayPoint
|
||||
{
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "other_day_point";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template <typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T otherDayPoint;
|
||||
T& operator()()
|
||||
{
|
||||
return otherDayPoint;
|
||||
}
|
||||
const T& operator()() const
|
||||
{
|
||||
return otherDayPoint;
|
||||
}
|
||||
};
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::day_point, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
struct OtherTimePoint
|
||||
{
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "other_time_point";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template <typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T otherTimePoint;
|
||||
T& operator()()
|
||||
{
|
||||
return otherTimePoint;
|
||||
}
|
||||
const T& operator()() const
|
||||
{
|
||||
return otherTimePoint;
|
||||
}
|
||||
};
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::time_point, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
}
|
||||
|
||||
struct TabAllTypes : sqlpp::table_t<TabAllTypes,
|
||||
TabAllTypes_::SomeString,
|
||||
TabAllTypes_::SomeInt,
|
||||
TabAllTypes_::SomeFloat,
|
||||
TabAllTypes_::SomeBool,
|
||||
TabAllTypes_::SomeDayPoint,
|
||||
TabAllTypes_::SomeTimePoint,
|
||||
TabAllTypes_::OtherInt,
|
||||
TabAllTypes_::OtherFloat,
|
||||
TabAllTypes_::OtherBool,
|
||||
TabAllTypes_::OtherDayPoint,
|
||||
TabAllTypes_::OtherTimePoint>
|
||||
{
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "tab_all_types";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template <typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T tabAllTypes;
|
||||
T& operator()()
|
||||
{
|
||||
return tabAllTypes;
|
||||
}
|
||||
const T& operator()() const
|
||||
{
|
||||
return tabAllTypes;
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
#endif
|
43
test_static_asserts/AssertTables.sql
Normal file
43
test_static_asserts/AssertTables.sql
Normal file
@ -0,0 +1,43 @@
|
||||
--
|
||||
-- Copyright (c) 2015-2015, 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.
|
||||
--
|
||||
|
||||
CREATE TABLE tab_all_types
|
||||
(
|
||||
some_string varchar(255),
|
||||
some_int bigint,
|
||||
some_float double,
|
||||
some_bool bool,
|
||||
some_date date,
|
||||
some_date_time datetime
|
||||
other_string varchar(255),
|
||||
other_int bigint,
|
||||
other_float double,
|
||||
other_bool bool,
|
||||
other_date date,
|
||||
other_date_time datetime
|
||||
);
|
||||
|
||||
|
@ -30,4 +30,6 @@ endfunction()
|
||||
|
||||
test_compile(aggregates)
|
||||
test_compile(insert)
|
||||
test_compile(date)
|
||||
test_compile(date_time)
|
||||
|
||||
|
90
test_static_asserts/date.cpp
Normal file
90
test_static_asserts/date.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2015, 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.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <MockDb.h>
|
||||
#include "AssertTables.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr auto t = test::TabAllTypes{};
|
||||
|
||||
template <typename T>
|
||||
void print_type_on_error(std::true_type)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void print_type_on_error(std::false_type)
|
||||
{
|
||||
T::_print_me_;
|
||||
}
|
||||
|
||||
template <typename Assert, typename Operand>
|
||||
void static_check_comparison(const Operand& operand)
|
||||
{
|
||||
using CheckResult = sqlpp::check_rhs_comparison_operand_t<decltype(t.someDayPoint), Operand>;
|
||||
using ExpectedCheckResult = std::is_same<CheckResult, Assert>;
|
||||
static_assert(ExpectedCheckResult::value, "Unexpected check result");
|
||||
print_type_on_error<CheckResult>(ExpectedCheckResult{});
|
||||
|
||||
using ReturnType = sqlpp::detail::make_type_set_t<
|
||||
decltype(t.someDayPoint < operand), decltype(t.someDayPoint <= operand), decltype(t.someDayPoint == operand),
|
||||
decltype(t.someDayPoint != operand), decltype(t.someDayPoint >= operand), decltype(t.someDayPoint > operand),
|
||||
decltype(t.someDayPoint.in(operand)), decltype(t.someDayPoint.in(operand, operand)),
|
||||
decltype(t.someDayPoint.not_in(operand)), decltype(t.someDayPoint.not_in(operand, operand))>;
|
||||
using ExpectedReturnType =
|
||||
sqlpp::logic::all_t<Assert::value xor
|
||||
std::is_same<ReturnType, sqlpp::detail::type_set<sqlpp::bad_statement>>::value>;
|
||||
static_assert(ExpectedReturnType::value, "Unexpected return type");
|
||||
print_type_on_error<ReturnType>(ExpectedReturnType{});
|
||||
}
|
||||
|
||||
void allowed_comparands()
|
||||
{
|
||||
static_check_comparison<sqlpp::consistent_t>(std::chrono::system_clock::now());
|
||||
static_check_comparison<sqlpp::consistent_t>(t.someDayPoint);
|
||||
static_check_comparison<sqlpp::consistent_t>(t.someTimePoint);
|
||||
}
|
||||
|
||||
void disallowed_comparands()
|
||||
{
|
||||
static_check_comparison<sqlpp::assert_valid_rhs_comparison_operand_t>(17);
|
||||
static_check_comparison<sqlpp::assert_valid_rhs_comparison_operand_t>('a');
|
||||
static_check_comparison<sqlpp::assert_valid_rhs_comparison_operand_t>(std::string("a"));
|
||||
static_check_comparison<sqlpp::assert_valid_rhs_comparison_operand_t>(t);
|
||||
static_check_comparison<sqlpp::assert_valid_rhs_comparison_operand_t>(t.someBool);
|
||||
static_check_comparison<sqlpp::assert_valid_rhs_comparison_operand_t>(t.someFloat);
|
||||
static_check_comparison<sqlpp::assert_valid_rhs_comparison_operand_t>(t.someInt);
|
||||
static_check_comparison<sqlpp::assert_valid_rhs_comparison_operand_t>(t.someString);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
allowed_comparands();
|
||||
disallowed_comparands();
|
||||
}
|
90
test_static_asserts/date_time.cpp
Normal file
90
test_static_asserts/date_time.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2015, 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.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <MockDb.h>
|
||||
#include "AssertTables.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr auto t = test::TabAllTypes{};
|
||||
|
||||
template <typename T>
|
||||
void print_type_on_error(std::true_type)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void print_type_on_error(std::false_type)
|
||||
{
|
||||
T::_print_me_;
|
||||
}
|
||||
|
||||
template <typename Assert, typename Operand>
|
||||
void static_check_comparison(const Operand& operand)
|
||||
{
|
||||
using CheckResult = sqlpp::check_rhs_comparison_operand_t<decltype(t.someTimePoint), Operand>;
|
||||
using ExpectedCheckResult = std::is_same<CheckResult, Assert>;
|
||||
static_assert(ExpectedCheckResult::value, "Unexpected check result");
|
||||
print_type_on_error<CheckResult>(ExpectedCheckResult{});
|
||||
|
||||
using ReturnType = sqlpp::detail::make_type_set_t<
|
||||
decltype(t.someTimePoint < operand), decltype(t.someTimePoint <= operand), decltype(t.someTimePoint == operand),
|
||||
decltype(t.someTimePoint != operand), decltype(t.someTimePoint >= operand), decltype(t.someTimePoint > operand),
|
||||
decltype(t.someTimePoint.in(operand)), decltype(t.someTimePoint.in(operand, operand)),
|
||||
decltype(t.someTimePoint.not_in(operand)), decltype(t.someTimePoint.not_in(operand, operand))>;
|
||||
using ExpectedReturnType =
|
||||
sqlpp::logic::all_t<Assert::value xor
|
||||
std::is_same<ReturnType, sqlpp::detail::type_set<sqlpp::bad_statement>>::value>;
|
||||
static_assert(ExpectedReturnType::value, "Unexpected return type");
|
||||
print_type_on_error<ReturnType>(ExpectedReturnType{});
|
||||
}
|
||||
|
||||
void allowed_comparands()
|
||||
{
|
||||
static_check_comparison<sqlpp::consistent_t>(std::chrono::system_clock::now());
|
||||
static_check_comparison<sqlpp::consistent_t>(t.someDayPoint);
|
||||
static_check_comparison<sqlpp::consistent_t>(t.someTimePoint);
|
||||
}
|
||||
|
||||
void disallowed_comparands()
|
||||
{
|
||||
static_check_comparison<sqlpp::assert_valid_rhs_comparison_operand_t>(17);
|
||||
static_check_comparison<sqlpp::assert_valid_rhs_comparison_operand_t>('a');
|
||||
static_check_comparison<sqlpp::assert_valid_rhs_comparison_operand_t>(std::string("a"));
|
||||
static_check_comparison<sqlpp::assert_valid_rhs_comparison_operand_t>(t);
|
||||
static_check_comparison<sqlpp::assert_valid_rhs_comparison_operand_t>(t.someBool);
|
||||
static_check_comparison<sqlpp::assert_valid_rhs_comparison_operand_t>(t.someFloat);
|
||||
static_check_comparison<sqlpp::assert_valid_rhs_comparison_operand_t>(t.someInt);
|
||||
static_check_comparison<sqlpp::assert_valid_rhs_comparison_operand_t>(t.someString);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
allowed_comparands();
|
||||
disallowed_comparands();
|
||||
}
|
@ -32,6 +32,7 @@ endif ()
|
||||
set(test_names
|
||||
BooleanExpression
|
||||
CustomQuery
|
||||
DateTime
|
||||
Interpret
|
||||
Insert
|
||||
Remove
|
||||
|
71
tests/DateTime.cpp
Normal file
71
tests/DateTime.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2015, 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.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "Sample.h"
|
||||
#include "MockDb.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
SQLPP_ALIAS_PROVIDER(now)
|
||||
|
||||
int DateTime(int, char**)
|
||||
{
|
||||
MockDb db = {};
|
||||
MockDb::_serializer_context_t printer;
|
||||
test::TabDateTime t;
|
||||
|
||||
for (const auto& row : db(select(::sqlpp::value(std::chrono::system_clock::now()).as(now))))
|
||||
{
|
||||
std::cout << row.now;
|
||||
}
|
||||
for (const auto& row : db(select(all_of(t)).from(t).where(true)))
|
||||
{
|
||||
std::cout << row.colDayPoint;
|
||||
std::cout << row.colTimePoint;
|
||||
}
|
||||
printer.reset();
|
||||
std::cerr << serialize(::sqlpp::value(std::chrono::system_clock::now()), printer).str() << std::endl;
|
||||
|
||||
db(insert_into(t).set(t.colDayPoint = ::date::floor<::sqlpp::chrono::days>(std::chrono::system_clock::now())));
|
||||
db(insert_into(t).set(t.colTimePoint = ::date::floor<::sqlpp::chrono::days>(std::chrono::system_clock::now())));
|
||||
db(insert_into(t).set(t.colTimePoint = std::chrono::system_clock::now()));
|
||||
|
||||
db(update(t)
|
||||
.set(t.colDayPoint = ::date::floor<::sqlpp::chrono::days>(std::chrono::system_clock::now()))
|
||||
.where(t.colDayPoint < std::chrono::system_clock::now()));
|
||||
db(update(t)
|
||||
.set(t.colTimePoint = ::date::floor<::sqlpp::chrono::days>(std::chrono::system_clock::now()))
|
||||
.where(t.colDayPoint < std::chrono::system_clock::now()));
|
||||
db(update(t)
|
||||
.set(t.colTimePoint = std::chrono::system_clock::now())
|
||||
.where(t.colDayPoint < std::chrono::system_clock::now()));
|
||||
|
||||
db(remove_from(t).where(t.colDayPoint == ::date::floor<::sqlpp::chrono::days>(std::chrono::system_clock::now())));
|
||||
db(remove_from(t).where(t.colDayPoint == std::chrono::system_clock::now()));
|
||||
db(remove_from(t).where(t.colTimePoint == ::date::floor<::sqlpp::chrono::days>(std::chrono::system_clock::now())));
|
||||
db(remove_from(t).where(t.colTimePoint == std::chrono::system_clock::now()));
|
||||
|
||||
return 0;
|
||||
}
|
@ -212,5 +212,75 @@ namespace test
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
namespace TabDateTime_
|
||||
{
|
||||
struct ColDayPoint
|
||||
{
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "col_day_point";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template <typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T colDayPoint;
|
||||
T& operator()()
|
||||
{
|
||||
return colDayPoint;
|
||||
}
|
||||
const T& operator()() const
|
||||
{
|
||||
return colDayPoint;
|
||||
}
|
||||
};
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::day_point, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
struct ColTimePoint
|
||||
{
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "col_time_point";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template <typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T colTimePoint;
|
||||
T& operator()()
|
||||
{
|
||||
return colTimePoint;
|
||||
}
|
||||
const T& operator()() const
|
||||
{
|
||||
return colTimePoint;
|
||||
}
|
||||
};
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::time_point, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
}
|
||||
|
||||
struct TabDateTime : sqlpp::table_t<TabDateTime, TabDateTime_::ColDayPoint, TabDateTime_::ColTimePoint>
|
||||
{
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "tab_time_point";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template <typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T tabDateTime;
|
||||
T& operator()()
|
||||
{
|
||||
return tabDateTime;
|
||||
}
|
||||
const T& operator()() const
|
||||
{
|
||||
return tabDateTime;
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user