mirror of
https://github.com/rbock/sqlpp11.git
synced 2026-02-06 05:39:19 -06:00
Several minor date/time fixes, new tests
This commit is contained in:
@@ -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>
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -32,6 +32,7 @@ endif ()
|
||||
set(test_names
|
||||
BooleanExpression
|
||||
CustomQuery
|
||||
DateTime
|
||||
Interpret
|
||||
Insert
|
||||
Remove
|
||||
|
||||
68
tests/DateTime.cpp
Normal file
68
tests/DateTime.cpp
Normal 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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user