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