Lightweight 0.1.0
Loading...
Searching...
No Matches
SqlDate.hpp
1// SPDX-License-Identifier: Apache-2.0
2
3#pragma once
4
5#include "../SqlColumnTypeDefinitions.hpp"
6#include "Core.hpp"
7
8#include <chrono>
9#include <format>
10
11/// Represents a date to efficiently write to or read from a database.
12///
13/// @ingroup DataTypes
14struct SqlDate
15{
16 SQL_DATE_STRUCT sqlValue {};
17
18 constexpr SqlDate() noexcept = default;
19 constexpr SqlDate(SqlDate&&) noexcept = default;
20 constexpr SqlDate& operator=(SqlDate&&) noexcept = default;
21 constexpr SqlDate(SqlDate const&) noexcept = default;
22 constexpr SqlDate& operator=(SqlDate const&) noexcept = default;
23 constexpr ~SqlDate() noexcept = default;
24
25 /// Returns the current date.
26 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE constexpr std::chrono::year_month_day value() const noexcept
27 {
28 return ConvertToNative(sqlValue);
29 }
30
31 LIGHTWEIGHT_FORCE_INLINE constexpr bool operator==(SqlDate const& other) const noexcept
32 {
33 return sqlValue.year == other.sqlValue.year && sqlValue.month == other.sqlValue.month
34 && sqlValue.day == other.sqlValue.day;
35 }
36
37 LIGHTWEIGHT_FORCE_INLINE constexpr bool operator!=(SqlDate const& other) const noexcept
38 {
39 return !(*this == other);
40 }
41
42 /// Constructs a date from individual std::chrono::year_month_day.
43 constexpr SqlDate(std::chrono::year_month_day value) noexcept:
44 sqlValue { SqlDate::ConvertToSqlValue(value) }
45 {
46 }
47
48 /// Constructs a date from individual components.
49 constexpr SqlDate(std::chrono::year year, std::chrono::month month, std::chrono::day day) noexcept:
50 SqlDate(std::chrono::year_month_day { year, month, day })
51 {
52 }
53
54 /// Returns the current date.
55 [[nodiscard]] static LIGHTWEIGHT_FORCE_INLINE SqlDate Today() noexcept
56 {
57 return SqlDate { std::chrono::year_month_day {
58 std::chrono::floor<std::chrono::days>(std::chrono::system_clock::now()),
59 } };
60 }
61
62 static LIGHTWEIGHT_FORCE_INLINE constexpr SQL_DATE_STRUCT ConvertToSqlValue(std::chrono::year_month_day value) noexcept
63 {
64 return SQL_DATE_STRUCT {
65 .year = (SQLSMALLINT) (int) value.year(),
66 .month = (SQLUSMALLINT) (unsigned) value.month(),
67 .day = (SQLUSMALLINT) (unsigned) value.day(),
68 };
69 }
70
71 static LIGHTWEIGHT_FORCE_INLINE constexpr std::chrono::year_month_day ConvertToNative(
72 SQL_DATE_STRUCT const& value) noexcept
73 {
74 return std::chrono::year_month_day { std::chrono::year { value.year },
75 std::chrono::month { static_cast<unsigned>(value.month) },
76 std::chrono::day { static_cast<unsigned>(value.day) } };
77 }
78};
79
80template <>
81struct std::formatter<SqlDate>: std::formatter<std::string>
82{
83 auto format(SqlDate const& value, std::format_context& ctx) const -> std::format_context::iterator
84 {
85 return std::formatter<std::string>::format(
86 std::format("{:04}-{:02}-{:02}", value.sqlValue.year, value.sqlValue.month, value.sqlValue.day), ctx);
87 }
88};
89
90template <>
91struct SqlDataBinder<SqlDate>
92{
93 static constexpr auto ColumnType = SqlColumnTypeDefinitions::Date {};
94
95 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN InputParameter(SQLHSTMT stmt,
96 SQLUSMALLINT column,
97 SqlDate const& value,
98 SqlDataBinderCallback& /*cb*/) noexcept
99 {
100 return SQLBindParameter(
101 stmt, column, SQL_PARAM_INPUT, SQL_C_TYPE_DATE, SQL_TYPE_DATE, 0, 0, (SQLPOINTER) &value.sqlValue, 0, nullptr);
102 }
103
104 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN OutputColumn(
105 SQLHSTMT stmt, SQLUSMALLINT column, SqlDate* result, SQLLEN* indicator, SqlDataBinderCallback& /*cb*/) noexcept
106 {
107 return SQLBindCol(stmt, column, SQL_C_TYPE_DATE, &result->sqlValue, sizeof(result->sqlValue), indicator);
108 }
109
110 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN GetColumn(
111 SQLHSTMT stmt, SQLUSMALLINT column, SqlDate* result, SQLLEN* indicator, SqlDataBinderCallback const& /*cb*/) noexcept
112 {
113 return SQLGetData(stmt, column, SQL_C_TYPE_DATE, &result->sqlValue, sizeof(result->sqlValue), indicator);
114 }
115
116 static LIGHTWEIGHT_FORCE_INLINE std::string Inspect(SqlDate const& value) noexcept
117 {
118 return std::format("{}", value);
119 }
120};
constexpr SqlDate(std::chrono::year year, std::chrono::month month, std::chrono::day day) noexcept
Constructs a date from individual components.
Definition SqlDate.hpp:49
LIGHTWEIGHT_FORCE_INLINE constexpr std::chrono::year_month_day value() const noexcept
Returns the current date.
Definition SqlDate.hpp:26
static LIGHTWEIGHT_FORCE_INLINE SqlDate Today() noexcept
Returns the current date.
Definition SqlDate.hpp:55
constexpr SqlDate(std::chrono::year_month_day value) noexcept
Constructs a date from individual std::chrono::year_month_day.
Definition SqlDate.hpp:43