Several minor date/time fixes, new tests

This commit is contained in:
rbock
2015-10-28 20:52:43 +01:00
parent 31b7ac4c4a
commit 73e8f04127
7 changed files with 239 additions and 5 deletions

View File

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

View File

@@ -27,6 +27,7 @@
#ifndef SQLPP_DATE_H
#define SQLPP_DATE_H
#include <date.h>
#include <sqlpp11/date_time_fwd.h>
#include <sqlpp11/basic_expression_operators.h>
#include <sqlpp11/type_traits.h>
@@ -138,7 +139,7 @@ namespace sqlpp
struct result_field_t<date, Db, FieldSpec> : public result_field_methods_t<result_field_t<date, Db, FieldSpec>>
{
static_assert(std::is_same<value_type_of<FieldSpec>, date>::value, "field type mismatch");
using _cpp_value_type = typename date::_cpp_value_type;
using _cpp_value_type = typename sqlpp::date::_cpp_value_type;
result_field_t() : _is_valid(false), _is_null(true), _value{}
{
@@ -201,5 +202,32 @@ namespace sqlpp
bool _is_null;
_cpp_value_type _value;
};
template <typename Context, typename Db, typename FieldSpec>
struct serializer_t<Context, result_field_t<date, Db, FieldSpec>>
{
using _serialize_check = consistent_t;
using T = result_field_t<date, 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<date, Db, FieldSpec>& e)
{
return serialize(e, os);
}
}
#endif

View File

@@ -202,5 +202,34 @@ namespace sqlpp
bool _is_null;
_cpp_value_type _value;
};
template <typename Context, typename Db, typename FieldSpec>
struct serializer_t<Context, result_field_t<date_time, Db, FieldSpec>>
{
using _serialize_check = consistent_t;
using T = result_field_t<date_time, 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);
const auto time = ::date::make_time(t - 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<date_time, Db, FieldSpec>& e)
{
return serialize(e, os);
}
}
#endif

View File

@@ -27,6 +27,7 @@
#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>
@@ -71,6 +72,19 @@ namespace sqlpp
_value_t _t;
};
template <typename Context>
struct serializer_t<Context, boolean_operand>
{
using _serialize_check = consistent_t;
using Operand = boolean_operand;
static Context& _(const Operand& t, Context& context)
{
context << t._t;
return context;
}
};
template <typename Period>
struct date_time_operand : public alias_operators<date_time_operand<Period>>
{
@@ -102,15 +116,32 @@ namespace sqlpp
_value_t _t;
};
template <typename Context>
struct serializer_t<Context, boolean_operand>
template <typename Context, typename Period>
struct serializer_t<Context, date_time_operand<Period>>
{
using _serialize_check = consistent_t;
using Operand = boolean_operand;
using Operand = date_time_operand<Period>;
static Context& _(const Operand& t, Context& context)
{
context << t._t;
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;
}
};
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;
}
};

View File

@@ -32,6 +32,7 @@ endif ()
set(test_names
BooleanExpression
CustomQuery
DateTime
Interpret
Insert
Remove

68
tests/DateTime.cpp Normal file
View File

@@ -0,0 +1,68 @@
/*
* 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;
}
printer.reset();
std::cerr << serialize(sqlpp::value(std::chrono::system_clock::now()), printer).str() << std::endl;
db(insert_into(t).set(t.colDate = ::date::floor<sqlpp::cpp::days>(std::chrono::system_clock::now())));
db(insert_into(t).set(t.colDate = std::chrono::system_clock::now()));
db(insert_into(t).set(t.colDateTime = ::date::floor<sqlpp::cpp::days>(std::chrono::system_clock::now())));
db(insert_into(t).set(t.colDateTime = std::chrono::system_clock::now()));
db(update(t)
.set(t.colDate = ::date::floor<sqlpp::cpp::days>(std::chrono::system_clock::now()))
.where(t.colDate < std::chrono::system_clock::now()));
db(update(t).set(t.colDate = std::chrono::system_clock::now()).where(t.colDate < std::chrono::system_clock::now()));
db(update(t)
.set(t.colDateTime = ::date::floor<sqlpp::cpp::days>(std::chrono::system_clock::now()))
.where(t.colDate < std::chrono::system_clock::now()));
db(update(t)
.set(t.colDateTime = std::chrono::system_clock::now())
.where(t.colDate < std::chrono::system_clock::now()));
db(remove_from(t).where(t.colDate == ::date::floor<sqlpp::cpp::days>(std::chrono::system_clock::now())));
db(remove_from(t).where(t.colDate == std::chrono::system_clock::now()));
db(remove_from(t).where(t.colDateTime == ::date::floor<sqlpp::cpp::days>(std::chrono::system_clock::now())));
db(remove_from(t).where(t.colDateTime == std::chrono::system_clock::now()));
return 0;
}

View File

@@ -212,5 +212,75 @@ namespace test
};
};
};
namespace TabDateTime_
{
struct ColDate
{
struct _alias_t
{
static constexpr const char _literal[] = "col_date";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T colDate;
T& operator()()
{
return colDate;
}
const T& operator()() const
{
return colDate;
}
};
};
using _traits = sqlpp::make_traits<sqlpp::date, sqlpp::tag::can_be_null>;
};
struct ColDateTime
{
struct _alias_t
{
static constexpr const char _literal[] = "col_date_time";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T colDateTime;
T& operator()()
{
return colDateTime;
}
const T& operator()() const
{
return colDateTime;
}
};
};
using _traits = sqlpp::make_traits<sqlpp::date_time, sqlpp::tag::can_be_null>;
};
}
struct TabDateTime : sqlpp::table_t<TabDateTime, TabDateTime_::ColDate, TabDateTime_::ColDateTime>
{
struct _alias_t
{
static constexpr const char _literal[] = "tab_date_time";
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