mirror of
https://github.com/rbock/sqlpp11.git
synced 2026-01-05 20:50:34 -06:00
Date/time adjustments, including date cannot be assigned with timestamp
This is inspired by sqlite's behaviour: If you have a date column (say
colDate) and update it with
colDate = DATETIME('2015-01-01T20:20:20);
colDate will contain the date time, not just the date (while the
connector would probably just read the date part). In order to prevent
this kind of inconsistencies, date can be assigned only with dates, not
with timestamps.
This commit is contained in:
@@ -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,7 +28,7 @@
|
||||
#define SQLPP_DATE_H
|
||||
|
||||
#include <date.h>
|
||||
#include <sqlpp11/date_time_fwd.h>
|
||||
#include <sqlpp11/date_time.h>
|
||||
#include <sqlpp11/basic_expression_operators.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/exception.h>
|
||||
@@ -43,10 +43,12 @@ namespace sqlpp
|
||||
{
|
||||
using _traits = make_traits<date, tag::is_value_type>;
|
||||
using _tag = tag::is_date;
|
||||
using _cpp_value_type = cpp::day_point;
|
||||
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>;
|
||||
};
|
||||
|
||||
// date parameter value
|
||||
@@ -194,7 +196,7 @@ namespace sqlpp
|
||||
template <typename Target>
|
||||
void _bind(Target& target, size_t i)
|
||||
{
|
||||
target._bind_day_point_result(i, &_value, &_is_null);
|
||||
target._bind_date_result(i, &_value, &_is_null);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace sqlpp
|
||||
{
|
||||
using _traits = make_traits<date_time, tag::is_value_type>;
|
||||
using _tag = tag::is_date_time;
|
||||
using _cpp_value_type = cpp::ms_point;
|
||||
using _cpp_value_type = ::sqlpp::chrono::mus_point;
|
||||
|
||||
template <typename T>
|
||||
using _is_valid_operand = is_time_point_t<T>;
|
||||
@@ -109,7 +109,7 @@ namespace sqlpp
|
||||
template <typename Target>
|
||||
void _bind(Target& target, size_t index) const
|
||||
{
|
||||
target._bind_date_parameter(index, &_value, _is_null);
|
||||
target._bind_date_time_parameter(index, &_value, _is_null);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -194,7 +194,7 @@ namespace sqlpp
|
||||
template <typename Target>
|
||||
void _bind(Target& target, size_t i)
|
||||
{
|
||||
target._bind_date_result(i, &_value, &_is_null);
|
||||
target._bind_date_time_result(i, &_value, &_is_null);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -217,8 +217,8 @@ namespace sqlpp
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto dp = ::date::floor<::date::days>(t);
|
||||
const auto time = ::date::make_time(t - dp);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -31,16 +31,16 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace cpp
|
||||
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 ms_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::microseconds>;
|
||||
using mus_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::microseconds>;
|
||||
}
|
||||
|
||||
struct date;
|
||||
struct date_time;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -85,10 +85,54 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
struct date_operand : public alias_operators<date_operand>
|
||||
{
|
||||
using _traits = make_traits<date, 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;
|
||||
|
||||
date_operand() : _t{}
|
||||
{
|
||||
}
|
||||
|
||||
date_operand(_value_t t) : _t(t)
|
||||
{
|
||||
}
|
||||
|
||||
date_operand(const date_operand&) = default;
|
||||
date_operand(date_operand&&) = default;
|
||||
date_operand& operator=(const date_operand&) = default;
|
||||
date_operand& operator=(date_operand&&) = default;
|
||||
~date_operand() = default;
|
||||
|
||||
bool _is_trivial() const
|
||||
{
|
||||
return _t == _value_t{};
|
||||
}
|
||||
|
||||
_value_t _t;
|
||||
};
|
||||
|
||||
template <typename Context>
|
||||
struct serializer_t<Context, date_operand>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using Operand = date_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 date_time_operand : public alias_operators<date_time_operand<Period>>
|
||||
{
|
||||
using _traits = make_traits<date, tag::is_expression, tag::is_wrapped_value>;
|
||||
using _traits = make_traits<date_time, tag::is_expression, tag::is_wrapped_value>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
using _is_aggregate_expression = std::true_type;
|
||||
|
||||
@@ -132,20 +176,6 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Context>
|
||||
struct serializer_t<Context, date_time_operand<cpp::days>>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using Operand = date_time_operand<cpp::days>;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
const auto ymd = ::date::year_month_day{t._t};
|
||||
context << "DATE '" << ymd << "'";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
struct integral_operand : public alias_operators<integral_operand>
|
||||
{
|
||||
using _traits = make_traits<integral, tag::is_expression, tag::is_wrapped_value>;
|
||||
@@ -293,6 +323,12 @@ namespace sqlpp
|
||||
using type = date_time_operand<Period>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct wrap_operand<std::chrono::time_point<std::chrono::system_clock, sqlpp::chrono::days>, void>
|
||||
{
|
||||
using type = date_operand;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_integral<T>::value>::type>
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user