Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ if(WASM)
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_SOURCE_DIR}/wasm/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake")
endif()

project(mgclient VERSION 1.4.6)
project(mgclient VERSION 1.5.0)
# Minor version increase can also mean ABI incompatibility with previous
# versions. IMPORTANT: Take care of the SO version manually.
set(mgclient_SOVERSION 2)
Expand Down
17 changes: 14 additions & 3 deletions include/mgclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -946,9 +946,9 @@ mg_date_time_zone_id_seconds(const mg_date_time_zone_id *date_time_zone_id);
MGCLIENT_EXPORT int64_t
mg_date_time_zone_id_nanoseconds(const mg_date_time_zone_id *date_time_zone_id);

/// Returns time zone represented by the identifier.
MGCLIENT_EXPORT int64_t
mg_date_time_zone_id_tz_id(const mg_date_time_zone_id *date_time_zone_id);
/// Returns time zone name.
MGCLIENT_EXPORT const mg_string *mg_date_time_zone_id_timezone_name(
const mg_date_time_zone_id *date_time_zone_id);

/// Creates a copy of the given date and time.
///
Expand All @@ -960,6 +960,17 @@ MGCLIENT_EXPORT mg_date_time_zone_id *mg_date_time_zone_id_copy(
MGCLIENT_EXPORT void mg_date_time_zone_id_destroy(
mg_date_time_zone_id *date_time_zone_id);

/// Creates mg_date_time from seconds, nanoseconds and timezone offset.
/// \return a pointer to mg_date_time or NULL if an error occurred.
MGCLIENT_EXPORT mg_date_time *mg_date_time_make(int64_t seconds,
int64_t nanoseconds,
int32_t tz_offset_minutes);

/// Creates mg_date_time_zone_id from seconds, nanoseconds, and timezone name.
/// \return a pointer to mg_date_time_zone_id or NULL if an error occurred.
MGCLIENT_EXPORT mg_date_time_zone_id *mg_date_time_zone_id_make(
int64_t seconds, int64_t nanoseconds, const char *timezone_name);

/// Creates mg_local_date_time from seconds and nanoseconds.
/// \return a pointer to mg_local_date_time or NULL if an error occurred.
MGCLIENT_EXPORT mg_local_date_time *mg_local_date_time_make(
Expand Down
24 changes: 20 additions & 4 deletions mgclient_cpp/include/mgclient-value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ TDest MemcpyCast(TSrc src) {
std::memcpy(&dest, &src, sizeof(src));
return dest;
}

} // namespace detail

// Forward declarations:
Expand Down Expand Up @@ -1041,7 +1042,10 @@ class DateTimeZoneId final {
/// Returns nanoseconds since midnight.
int64_t nanoseconds() const { return mg_date_time_zone_id_nanoseconds(ptr_); }
/// Returns time zone represented by the identifier.
int64_t tzId() const { return mg_date_time_zone_id_tz_id(ptr_); }
std::string_view timezoneName() const {
const mg_string *name = mg_date_time_zone_id_timezone_name(ptr_);
return std::string_view{mg_string_data(name), mg_string_size(name)};
}

ConstDateTimeZoneId AsConstDateTimeZoneId() const;

Expand Down Expand Up @@ -1072,7 +1076,10 @@ class ConstDateTimeZoneId final {
return mg_date_time_zone_id_nanoseconds(const_ptr_);
}
/// Returns time zone represented by the identifier.
int64_t tzId() const { return mg_date_time_zone_id_tz_id(const_ptr_); }
std::string_view timezoneName() const {
const mg_string *name = mg_date_time_zone_id_timezone_name(const_ptr_);
return std::string_view{mg_string_data(name), mg_string_size(name)};
}

bool operator==(const ConstDateTimeZoneId &other) const;
bool operator==(const DateTimeZoneId &other) const;
Expand Down Expand Up @@ -1681,6 +1688,14 @@ inline Value::Type ConvertType(mg_value_type type) {

inline bool AreValuesEqual(const mg_value *value1, const mg_value *value2);

inline bool AreStringsEqual(const mg_string *s1, const mg_string *s2) {
if (s1 == s2) return true;
if (!s1 || !s2) return false;
return mg_string_size(s1) == mg_string_size(s2) &&
memcmp(mg_string_data(s1), mg_string_data(s2), mg_string_size(s1)) ==
0;
}

inline bool AreListsEqual(const mg_list *list1, const mg_list *list2) {
if (list1 == list2) {
return true;
Expand Down Expand Up @@ -1840,8 +1855,9 @@ inline bool AreDateTimeZoneIdsEqual(
mg_date_time_zone_id_seconds(date_time_zone_id2) &&
mg_date_time_zone_id_nanoseconds(date_time_zone_id1) ==
mg_date_time_zone_id_nanoseconds(date_time_zone_id2) &&
mg_date_time_zone_id_tz_id(date_time_zone_id1) ==
mg_date_time_zone_id_tz_id(date_time_zone_id2);
detail::AreStringsEqual(
mg_date_time_zone_id_timezone_name(date_time_zone_id1),
mg_date_time_zone_id_timezone_name(date_time_zone_id2));
}

inline bool AreLocalDateTimesEqual(const mg_local_date_time *local_date_time1,
Expand Down
6 changes: 5 additions & 1 deletion src/mgsession-decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,11 @@ int mg_session_read_date_time_zone_id(
goto cleanup;
}

status = mg_session_read_integer(session, &date_time_zone_id_tmp->tz_id);
status =
mg_session_read_string(session, &date_time_zone_id_tmp->timezone_name);
if (status != 0) {
goto cleanup;
}

*date_time_zone_id = date_time_zone_id_tmp;
return 0;
Expand Down
32 changes: 27 additions & 5 deletions src/mgsession-encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,30 @@ int mg_session_write_local_date_time(mg_session *session,
return 0;
}

int mg_session_write_date_time(mg_session *session, const mg_date_time *dt) {
MG_RETURN_IF_FAILED(
mg_session_write_uint8(session, (uint8_t)(MG_MARKER_TINY_STRUCT3)));
MG_RETURN_IF_FAILED(mg_session_write_uint8(session, MG_SIGNATURE_DATE_TIME));
MG_RETURN_IF_FAILED(mg_session_write_integer(session, dt->seconds));
MG_RETURN_IF_FAILED(mg_session_write_integer(session, dt->nanoseconds));
MG_RETURN_IF_FAILED(
mg_session_write_integer(session, dt->tz_offset_minutes * 60));
return 0;
}

int mg_session_write_date_time_zone_id(mg_session *session,
const mg_date_time_zone_id *dtz) {
MG_RETURN_IF_FAILED(
mg_session_write_uint8(session, (uint8_t)(MG_MARKER_TINY_STRUCT3)));
MG_RETURN_IF_FAILED(
mg_session_write_uint8(session, MG_SIGNATURE_DATE_TIME_ZONE_ID));
MG_RETURN_IF_FAILED(mg_session_write_integer(session, dtz->seconds));
MG_RETURN_IF_FAILED(mg_session_write_integer(session, dtz->nanoseconds));
MG_RETURN_IF_FAILED(mg_session_write_string2(
session, dtz->timezone_name->size, dtz->timezone_name->data));
return 0;
}

int mg_session_write_duration(mg_session *session, const mg_duration *dur) {
MG_RETURN_IF_FAILED(
mg_session_write_uint8(session, (uint8_t)(MG_MARKER_TINY_STRUCT4)));
Expand Down Expand Up @@ -228,12 +252,10 @@ int mg_session_write_value(mg_session *session, const mg_value *value) {
case MG_VALUE_TYPE_LOCAL_TIME:
return mg_session_write_local_time(session, value->local_time_v);
case MG_VALUE_TYPE_DATE_TIME:
mg_session_set_error(session, "tried to send value of type 'date_time'");
return MG_ERROR_INVALID_VALUE;
return mg_session_write_date_time(session, value->date_time_v);
case MG_VALUE_TYPE_DATE_TIME_ZONE_ID:
mg_session_set_error(session,
"tried to send value of type 'date_time_zone_id'");
return MG_ERROR_INVALID_VALUE;
return mg_session_write_date_time_zone_id(session,
value->date_time_zone_id_v);
case MG_VALUE_TYPE_LOCAL_DATE_TIME:
return mg_session_write_local_date_time(session,
value->local_date_time_v);
Expand Down
52 changes: 48 additions & 4 deletions src/mgvalue.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ mg_date_time_zone_id *mg_date_time_zone_id_alloc(mg_allocator *allocator) {
return NULL;
}
mg_date_time_zone_id *date_time_zone_id = (mg_date_time_zone_id *)block;
date_time_zone_id->seconds = 0;
date_time_zone_id->nanoseconds = 0;
date_time_zone_id->timezone_name = NULL;
return date_time_zone_id;
}

Expand Down Expand Up @@ -1279,9 +1282,9 @@ int64_t mg_date_time_zone_id_nanoseconds(
return date_time_zone_id->nanoseconds;
}

int64_t mg_date_time_zone_id_tz_id(
const mg_string *mg_date_time_zone_id_timezone_name(
const mg_date_time_zone_id *date_time_zone_id) {
return date_time_zone_id->tz_id;
return date_time_zone_id->timezone_name;
}

int64_t mg_local_date_time_seconds(const mg_local_date_time *local_date_time) {
Expand Down Expand Up @@ -1442,7 +1445,14 @@ mg_date_time_zone_id *mg_date_time_zone_id_copy_ca(
if (!date_time_zone_id) {
return NULL;
}
memcpy(date_time_zone_id, src, sizeof(mg_date_time_zone_id));
date_time_zone_id->seconds = src->seconds;
date_time_zone_id->nanoseconds = src->nanoseconds;
date_time_zone_id->timezone_name =
mg_string_copy_ca(src->timezone_name, allocator);
if (!date_time_zone_id->timezone_name) {
mg_date_time_zone_id_destroy_ca(date_time_zone_id, allocator);
return NULL;
}
return date_time_zone_id;
}

Expand All @@ -1456,6 +1466,7 @@ void mg_date_time_zone_id_destroy_ca(mg_date_time_zone_id *date_time_zone_id,
if (!date_time_zone_id) {
return;
}
mg_string_destroy_ca(date_time_zone_id->timezone_name, allocator);
mg_allocator_free(allocator, date_time_zone_id);
}

Expand Down Expand Up @@ -1657,6 +1668,39 @@ mg_local_time *mg_local_time_make(int64_t nanoseconds) {
return lt;
}

mg_date_time *mg_date_time_make(int64_t seconds, int64_t nanoseconds,
int32_t tz_offset_minutes) {
mg_date_time *dt = mg_date_time_alloc(&mg_system_allocator);
if (!dt) {
return NULL;
}
dt->seconds = seconds;
dt->nanoseconds = nanoseconds;
dt->tz_offset_minutes = tz_offset_minutes;
return dt;
}

mg_date_time_zone_id *mg_date_time_zone_id_make(int64_t seconds,
int64_t nanoseconds,
const char *timezone_name) {
mg_date_time_zone_id *dt_zone_id =
mg_date_time_zone_id_alloc(&mg_system_allocator);
if (!dt_zone_id) {
return NULL;
}

mg_string *tz_name = mg_string_make(timezone_name);
if (!tz_name) {
mg_date_time_zone_id_destroy_ca(dt_zone_id, &mg_system_allocator);
return NULL;
}

dt_zone_id->seconds = seconds;
dt_zone_id->nanoseconds = nanoseconds;
dt_zone_id->timezone_name = tz_name;
return dt_zone_id;
}

mg_local_date_time *mg_local_date_time_make(int64_t seconds,
int64_t nanoseconds) {
mg_local_date_time *ldt = mg_local_date_time_alloc(&mg_system_allocator);
Expand Down Expand Up @@ -1814,7 +1858,7 @@ int mg_local_date_time_equal(const mg_local_date_time *lhs,
int mg_date_time_zone_id_equal(const mg_date_time_zone_id *lhs,
const mg_date_time_zone_id *rhs) {
return lhs->seconds == rhs->seconds && lhs->nanoseconds == rhs->nanoseconds &&
lhs->tz_id == rhs->tz_id;
mg_string_equal(lhs->timezone_name, rhs->timezone_name);
}

int mg_duration_equal(const mg_duration *lhs, const mg_duration *rhs) {
Expand Down
2 changes: 1 addition & 1 deletion src/mgvalue.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ typedef struct mg_date_time {
typedef struct mg_date_time_zone_id {
int64_t seconds;
int64_t nanoseconds;
int64_t tz_id;
mg_string *timezone_name;
} mg_date_time_zone_id;

typedef struct mg_local_date_time {
Expand Down
5 changes: 3 additions & 2 deletions tests/bolt-testdata.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,13 +445,14 @@ std::vector<ValueTestParam> DateTimeZoneIdTestCases() {

date_time_zone_id->seconds = 1;
date_time_zone_id->nanoseconds = 1;
date_time_zone_id->tz_id = 1;
date_time_zone_id->timezone_name = mg_string_make("Europe/Zagreb");

std::string encoded_date_time_zone_id;
encoded_date_time_zone_id += "\xB3\x66"s;
encoded_date_time_zone_id += "\x01"s;
encoded_date_time_zone_id += "\x01"s;
encoded_date_time_zone_id += "\x01"s;
encoded_date_time_zone_id += "\x8D"s;
encoded_date_time_zone_id += "Europe/Zagreb"s;

inputs.push_back({mg_value_make_date_time_zone_id(date_time_zone_id),
encoded_date_time_zone_id});
Expand Down
3 changes: 3 additions & 0 deletions tests/encoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,9 @@ INSTANTIATE_TEST_CASE_P(LocalTime, ValueTest,
INSTANTIATE_TEST_CASE_P(LocalDateTime, ValueTest,
::testing::ValuesIn(LocalDateTimeTestCases()), );

INSTANTIATE_TEST_CASE_P(DateTime, ValueTest,
::testing::ValuesIn(DateTimeTestCases()), );

INSTANTIATE_TEST_CASE_P(Duration, ValueTest,
::testing::ValuesIn((DurationTestCases())), );

Expand Down
12 changes: 7 additions & 5 deletions tests/value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,22 +522,24 @@ TEST(Value, DateTimeZoneId) {
mg_date_time_zone_id_alloc(&mg_system_allocator);
date_time_zone_id->seconds = 1;
date_time_zone_id->nanoseconds = 1;
date_time_zone_id->tz_id = 1;
date_time_zone_id->timezone_name = mg_string_make("Europe/Zagreb");
EXPECT_EQ(mg_date_time_zone_id_seconds(date_time_zone_id),
static_cast<int64_t>(1));
EXPECT_EQ(mg_date_time_zone_id_nanoseconds(date_time_zone_id),
static_cast<int64_t>(1));
EXPECT_EQ(mg_date_time_zone_id_tz_id(date_time_zone_id),
static_cast<int64_t>(1));
const mg_string *tz_name =
mg_date_time_zone_id_timezone_name(date_time_zone_id);
EXPECT_TRUE(Equal(tz_name, "Europe/Zagreb"s));
mg_date_time_zone_id *date_time_zone_id2 =
mg_date_time_zone_id_copy(date_time_zone_id);
mg_date_time_zone_id_destroy(date_time_zone_id);
EXPECT_EQ(mg_date_time_zone_id_seconds(date_time_zone_id2),
static_cast<int64_t>(1));
EXPECT_EQ(mg_date_time_zone_id_nanoseconds(date_time_zone_id2),
static_cast<int64_t>(1));
EXPECT_EQ(mg_date_time_zone_id_tz_id(date_time_zone_id2),
static_cast<int64_t>(1));
const mg_string *tz_name2 =
mg_date_time_zone_id_timezone_name(date_time_zone_id2);
EXPECT_TRUE(Equal(tz_name2, "Europe/Zagreb"s));
mg_date_time_zone_id_destroy(date_time_zone_id2);
}
}
Expand Down
Loading