From cd0e07f6a4f18672dc0b934c512366acb1098c31 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Tue, 9 Jan 2024 20:45:04 -0500 Subject: [PATCH] LibSQL: Add a helper to convert a SQL::Value to a UnixDateTime Support for constructing a Value from a UnixDateTime was added in commit effcd080ca802515ddce8392c70df512b509f57c. That constructor just stores the value as the number of milliseconds since epoch. There's no way for outside users to know this, so this adds a helper to retrieve the value as a UnixDateTime and let SQL::Value be the source of truth for how the value is encoded/decoded. --- Tests/LibSQL/TestSqlValueAndTuple.cpp | 34 +++++++++++++++++++++++++++ Userland/Libraries/LibSQL/Value.cpp | 9 +++++++ Userland/Libraries/LibSQL/Value.h | 1 + 3 files changed, 44 insertions(+) diff --git a/Tests/LibSQL/TestSqlValueAndTuple.cpp b/Tests/LibSQL/TestSqlValueAndTuple.cpp index 6526353133..970716895d 100644 --- a/Tests/LibSQL/TestSqlValueAndTuple.cpp +++ b/Tests/LibSQL/TestSqlValueAndTuple.cpp @@ -7,6 +7,7 @@ #include +#include #include #include #include @@ -471,6 +472,39 @@ TEST_CASE(serialize_boolean_value) EXPECT_EQ(v, v2); } +TEST_CASE(unix_date_time_value) +{ + auto now = UnixDateTime::now(); + { + SQL::Value value(now); + EXPECT_EQ(value.type(), SQL::SQLType::Integer); + + auto result = value.to_unix_date_time(); + VERIFY(result.has_value()); + EXPECT_EQ(result->milliseconds_since_epoch(), now.milliseconds_since_epoch()); + } + { + auto now_plus_10s = now + Duration::from_seconds(10); + + SQL::Value value(now_plus_10s); + EXPECT_EQ(value.type(), SQL::SQLType::Integer); + + auto result = value.to_unix_date_time(); + VERIFY(result.has_value()); + EXPECT_EQ(result->milliseconds_since_epoch(), now_plus_10s.milliseconds_since_epoch()); + } + { + auto now_minus_10s = now - Duration::from_seconds(10); + + SQL::Value value(now_minus_10s); + EXPECT_EQ(value.type(), SQL::SQLType::Integer); + + auto result = value.to_unix_date_time(); + VERIFY(result.has_value()); + EXPECT_EQ(result->milliseconds_since_epoch(), now_minus_10s.milliseconds_since_epoch()); + } +} + TEST_CASE(tuple_value) { NonnullRefPtr descriptor = adopt_ref(*new SQL::TupleDescriptor); diff --git a/Userland/Libraries/LibSQL/Value.cpp b/Userland/Libraries/LibSQL/Value.cpp index a1da0aa0bd..83db129778 100644 --- a/Userland/Libraries/LibSQL/Value.cpp +++ b/Userland/Libraries/LibSQL/Value.cpp @@ -277,6 +277,15 @@ Optional Value::to_bool() const }); } +Optional Value::to_unix_date_time() const +{ + auto time = to_int(); + if (!time.has_value()) + return {}; + + return UnixDateTime::from_milliseconds_since_epoch(*time); +} + Optional> Value::to_vector() const { if (is_null() || (type() != SQLType::Tuple)) diff --git a/Userland/Libraries/LibSQL/Value.h b/Userland/Libraries/LibSQL/Value.h index 98852819aa..54654447b1 100644 --- a/Userland/Libraries/LibSQL/Value.h +++ b/Userland/Libraries/LibSQL/Value.h @@ -77,6 +77,7 @@ public: [[nodiscard]] ByteString to_byte_string() const; [[nodiscard]] Optional to_double() const; [[nodiscard]] Optional to_bool() const; + [[nodiscard]] Optional to_unix_date_time() const; [[nodiscard]] Optional> to_vector() const; template