Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
688 changes: 633 additions & 55 deletions src/iceberg/json_internal.cc

Large diffs are not rendered by default.

158 changes: 111 additions & 47 deletions src/iceberg/json_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include <nlohmann/json_fwd.hpp>

#include "iceberg/result.h"
#include "iceberg/statistics_file.h"
#include "iceberg/table_metadata.h"
#include "iceberg/type_fwd.h"

namespace iceberg {
Expand All @@ -38,16 +40,6 @@ namespace iceberg {
/// \return A JSON object representing the `SortField` in the form of key-value pairs.
nlohmann::json ToJson(const SortField& sort_field);

/// \brief Serializes a `SortOrder` object to JSON.
///
/// This function converts a `SortOrder` object into a JSON representation.
/// The resulting JSON includes the order ID and a list of `SortField` objects.
/// Each `SortField` is serialized as described in the `ToJson(SortField)` function.
///
/// \param sort_order The `SortOrder` object to be serialized.
/// \return A JSON object representing the `SortOrder` with its order ID and fields array.
nlohmann::json ToJson(const SortOrder& sort_order);

/// \brief Deserializes a JSON object into a `SortField` object.
///
/// This function parses the provided JSON and creates a `SortField` object.
Expand All @@ -59,6 +51,16 @@ nlohmann::json ToJson(const SortOrder& sort_order);
/// JSON is malformed or missing expected fields, an error will be returned.
Result<std::unique_ptr<SortField>> SortFieldFromJson(const nlohmann::json& json);

/// \brief Serializes a `SortOrder` object to JSON.
///
/// This function converts a `SortOrder` object into a JSON representation.
/// The resulting JSON includes the order ID and a list of `SortField` objects.
/// Each `SortField` is serialized as described in the `ToJson(SortField)` function.
///
/// \param sort_order The `SortOrder` object to be serialized.
/// \return A JSON object representing the `SortOrder` with its order ID and fields array.
nlohmann::json ToJson(const SortOrder& sort_order);

/// \brief Deserializes a JSON object into a `SortOrder` object.
///
/// This function parses the provided JSON and creates a `SortOrder` object.
Expand All @@ -74,44 +76,32 @@ Result<std::unique_ptr<SortOrder>> SortOrderFromJson(const nlohmann::json& json)
///
/// \param[in] schema The Iceberg schema to convert.
/// \return The JSON representation of the schema.
nlohmann::json SchemaToJson(const Schema& schema);

/// \brief Convert an Iceberg Type to JSON.
///
/// \param[in] type The Iceberg type to convert.
/// \return The JSON representation of the type.
nlohmann::json TypeToJson(const Type& type);

/// \brief Convert an Iceberg SchemaField to JSON.
///
/// \param[in] field The Iceberg field to convert.
/// \return The JSON representation of the field.
nlohmann::json FieldToJson(const SchemaField& field);

/// \brief Serializes a `SnapshotRef` object to JSON.
///
/// \param[in] snapshot_ref The `SnapshotRef` object to be serialized.
/// \return A JSON object representing the `SnapshotRef`.
nlohmann::json ToJson(const SnapshotRef& snapshot_ref);

/// \brief Serializes a `Snapshot` object to JSON.
///
/// \param[in] snapshot The `Snapshot` object to be serialized.
/// \return A JSON object representing the `snapshot`.
nlohmann::json ToJson(const Snapshot& snapshot);
nlohmann::json ToJson(const Schema& schema);

/// \brief Convert JSON to an Iceberg Schema.
///
/// \param[in] json The JSON representation of the schema.
/// \return The Iceberg schema or an error if the conversion fails.
Result<std::unique_ptr<Schema>> SchemaFromJson(const nlohmann::json& json);

/// \brief Convert an Iceberg Type to JSON.
///
/// \param[in] type The Iceberg type to convert.
/// \return The JSON representation of the type.
nlohmann::json ToJson(const Type& type);

/// \brief Convert JSON to an Iceberg Type.
///
/// \param[in] json The JSON representation of the type.
/// \return The Iceberg type or an error if the conversion fails.
Result<std::unique_ptr<Type>> TypeFromJson(const nlohmann::json& json);

/// \brief Convert an Iceberg SchemaField to JSON.
///
/// \param[in] field The Iceberg field to convert.
/// \return The JSON representation of the field.
nlohmann::json ToJson(const SchemaField& field);

/// \brief Convert JSON to an Iceberg SchemaField.
///
/// \param[in] json The JSON representation of the field.
Expand All @@ -129,18 +119,6 @@ Result<std::unique_ptr<SchemaField>> FieldFromJson(const nlohmann::json& json);
/// pairs.
nlohmann::json ToJson(const PartitionField& partition_field);

/// \brief Serializes a `PartitionSpec` object to JSON.
///
/// This function converts a `PartitionSpec` object into a JSON representation.
/// The resulting JSON includes the spec ID and a list of `PartitionField` objects.
/// Each `PartitionField` is serialized as described in the `ToJson(PartitionField)`
/// function.
///
/// \param partition_spec The `PartitionSpec` object to be serialized.
/// \return A JSON object representing the `PartitionSpec` with its order ID and fields
/// array.
nlohmann::json ToJson(const PartitionSpec& partition_spec);

/// \brief Deserializes a JSON object into a `PartitionField` object.
///
/// This function parses the provided JSON and creates a `PartitionField` object.
Expand All @@ -153,6 +131,18 @@ nlohmann::json ToJson(const PartitionSpec& partition_spec);
Result<std::unique_ptr<PartitionField>> PartitionFieldFromJson(
const nlohmann::json& json);

/// \brief Serializes a `PartitionSpec` object to JSON.
///
/// This function converts a `PartitionSpec` object into a JSON representation.
/// The resulting JSON includes the spec ID and a list of `PartitionField` objects.
/// Each `PartitionField` is serialized as described in the `ToJson(PartitionField)`
/// function.
///
/// \param partition_spec The `PartitionSpec` object to be serialized.
/// \return A JSON object representing the `PartitionSpec` with its order ID and fields
/// array.
nlohmann::json ToJson(const PartitionSpec& partition_spec);

/// \brief Deserializes a JSON object into a `PartitionSpec` object.
///
/// This function parses the provided JSON and creates a `PartitionSpec` object.
Expand All @@ -166,16 +156,90 @@ Result<std::unique_ptr<PartitionField>> PartitionFieldFromJson(
Result<std::unique_ptr<PartitionSpec>> PartitionSpecFromJson(
const std::shared_ptr<Schema>& schema, const nlohmann::json& json);

/// \brief Serializes a `SnapshotRef` object to JSON.
///
/// \param[in] snapshot_ref The `SnapshotRef` object to be serialized.
/// \return A JSON object representing the `SnapshotRef`.
nlohmann::json ToJson(const SnapshotRef& snapshot_ref);

/// \brief Deserializes a JSON object into a `SnapshotRef` object.
///
/// \param[in] json The JSON object representing a `SnapshotRef`.
/// \return A `SnapshotRef` object or an error if the conversion fails.
Result<std::unique_ptr<SnapshotRef>> SnapshotRefFromJson(const nlohmann::json& json);

/// \brief Serializes a `Snapshot` object to JSON.
///
/// \param[in] snapshot The `Snapshot` object to be serialized.
/// \return A JSON object representing the `snapshot`.
nlohmann::json ToJson(const Snapshot& snapshot);

/// \brief Deserializes a JSON object into a `Snapshot` object.
///
/// \param[in] json The JSON representation of the snapshot.
/// \return A `Snapshot` object or an error if the conversion fails.
Result<std::unique_ptr<Snapshot>> SnapshotFromJson(const nlohmann::json& json);

/// \brief Serializes a `StatisticsFile` object to JSON.
///
/// \param statistics_file The `StatisticsFile` object to be serialized.
/// \return A JSON object representing the `StatisticsFile`.
nlohmann::json ToJson(const StatisticsFile& statistics_file);

/// \brief Deserializes a JSON object into a `StatisticsFile` object.
///
/// \param json The JSON object representing a `StatisticsFile`.
/// \return A `StatisticsFile` object or an error if the conversion fails.
Result<std::unique_ptr<StatisticsFile>> StatisticsFileFromJson(
const nlohmann::json& json);

/// \brief Serializes a `PartitionStatisticsFile` object to JSON.
///
/// \param partition_statistics_file The `PartitionStatisticsFile` object to be
/// serialized. \return A JSON object representing the `PartitionStatisticsFile`.
nlohmann::json ToJson(const PartitionStatisticsFile& partition_statistics_file);

/// \brief Deserializes a JSON object into a `PartitionStatisticsFile` object.
///
/// \param json The JSON object representing a `PartitionStatisticsFile`.
/// \return A `PartitionStatisticsFile` object or an error if the conversion fails.
Result<std::unique_ptr<PartitionStatisticsFile>> PartitionStatisticsFileFromJson(
const nlohmann::json& json);

/// \brief Serializes a `SnapshotLogEntry` object to JSON.
///
/// \param snapshot_log_entry The `SnapshotLogEntry` object to be serialized.
/// \return A JSON object representing the `SnapshotLogEntry`.
nlohmann::json ToJson(const SnapshotLogEntry& snapshot_log_entry);

/// \brief Deserializes a JSON object into a `SnapshotLogEntry` object.
///
/// \param json The JSON object representing a `SnapshotLogEntry`.
/// \return A `SnapshotLogEntry` object or an error if the conversion fails.
Result<SnapshotLogEntry> SnapshotLogEntryFromJson(const nlohmann::json& json);

/// \brief Serializes a `MetadataLogEntry` object to JSON.
///
/// \param metadata_log_entry The `MetadataLogEntry` object to be serialized.
/// \return A JSON object representing the `MetadataLogEntry`.
nlohmann::json ToJson(const MetadataLogEntry& metadata_log_entry);

/// \brief Deserializes a JSON object into a `MetadataLogEntry` object.
///
/// \param json The JSON object representing a `MetadataLogEntry`.
/// \return A `MetadataLogEntry` object or an error if the conversion fails.
Result<MetadataLogEntry> MetadataLogEntryFromJson(const nlohmann::json& json);

/// \brief Serializes a `TableMetadata` object to JSON.
///
/// \param table_metadata The `TableMetadata` object to be serialized.
/// \return A JSON object representing the `TableMetadata`.
nlohmann::json ToJson(const TableMetadata& table_metadata);

/// \brief Deserializes a JSON object into a `TableMetadata` object.
///
/// \param json The JSON object representing a `TableMetadata`.
/// \return A `TableMetadata` object or an error if the conversion fails.
Result<std::unique_ptr<TableMetadata>> TableMetadataFromJson(const nlohmann::json& json);

} // namespace iceberg
17 changes: 17 additions & 0 deletions src/iceberg/result.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#pragma once

#include <format>
#include <string>

#include "iceberg/expected.h"
Expand Down Expand Up @@ -60,4 +61,20 @@ using Result = expected<T, E>;

using Status = Result<void>;

/// \brief Create an unexpected error with kNotImplemented
template <typename... Args>
auto NotImplementedError(const std::format_string<Args...> fmt, Args&&... args)
-> unexpected<Error> {
return unexpected<Error>({.kind = ErrorKind::kNotImplemented,
.message = std::format(fmt, std::forward<Args>(args)...)});
}

/// \brief Create an unexpected error with kJsonParseError
template <typename... Args>
auto JsonParseError(const std::format_string<Args...> fmt, Args&&... args)
-> unexpected<Error> {
return unexpected<Error>({.kind = ErrorKind::kJsonParseError,
.message = std::format(fmt, std::forward<Args>(args)...)});
}

} // namespace iceberg
53 changes: 27 additions & 26 deletions src/iceberg/statistics_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,26 @@

namespace iceberg {

bool BlobMetadata::Equals(const BlobMetadata& other) const {
return type == other.type && source_snapshot_id == other.source_snapshot_id &&
source_snapshot_sequence_number == other.source_snapshot_sequence_number &&
fields == other.fields && properties == other.properties;
}

std::string BlobMetadata::ToString() const {
std::string ToString(const BlobMetadata& blob_metadata) {
std::string repr = "BlobMetadata[";
std::format_to(std::back_inserter(repr),
"type='{}',sourceSnapshotId={},sourceSnapshotSequenceNumber={},", type,
source_snapshot_id, source_snapshot_sequence_number);
"type='{}',sourceSnapshotId={},sourceSnapshotSequenceNumber={},",
blob_metadata.type, blob_metadata.source_snapshot_id,
blob_metadata.source_snapshot_sequence_number);
std::format_to(std::back_inserter(repr), "fields=[");
for (auto iter = fields.cbegin(); iter != fields.cend(); ++iter) {
if (iter != fields.cbegin()) {
for (auto iter = blob_metadata.fields.cbegin(); iter != blob_metadata.fields.cend();
++iter) {
if (iter != blob_metadata.fields.cbegin()) {
std::format_to(std::back_inserter(repr), ",{}", *iter);
} else {
std::format_to(std::back_inserter(repr), "{}", *iter);
}
}
std::format_to(std::back_inserter(repr), "],properties=[");
for (auto iter = properties.cbegin(); iter != properties.cend(); ++iter) {
for (auto iter = blob_metadata.properties.cbegin();
iter != blob_metadata.properties.cend(); ++iter) {
const auto& [key, value] = *iter;
if (iter != properties.cbegin()) {
if (iter != blob_metadata.properties.cbegin()) {
std::format_to(std::back_inserter(repr), ",{}:{}", key, value);
} else {
std::format_to(std::back_inserter(repr), "{}:{}", key, value);
Expand All @@ -55,28 +52,32 @@ std::string BlobMetadata::ToString() const {
return repr;
}

bool StatisticsFile::Equals(const StatisticsFile& other) const {
return snapshot_id == other.snapshot_id && path == other.path &&
file_size_in_bytes == other.file_size_in_bytes &&
file_footer_size_in_bytes == other.file_footer_size_in_bytes &&
blob_metadata == other.blob_metadata;
}

std::string StatisticsFile::ToString() const {
std::string ToString(const StatisticsFile& statistics_file) {
std::string repr = "StatisticsFile[";
std::format_to(std::back_inserter(repr),
"snapshotId={},path={},fileSizeInBytes={},fileFooterSizeInBytes={},",
snapshot_id, path, file_size_in_bytes, file_footer_size_in_bytes);
statistics_file.snapshot_id, statistics_file.path,
statistics_file.file_size_in_bytes,
statistics_file.file_footer_size_in_bytes);
std::format_to(std::back_inserter(repr), "blobMetadata=[");
for (auto iter = blob_metadata.cbegin(); iter != blob_metadata.cend(); ++iter) {
if (iter != blob_metadata.cbegin()) {
std::format_to(std::back_inserter(repr), ",{}", iter->ToString());
for (auto iter = statistics_file.blob_metadata.cbegin();
iter != statistics_file.blob_metadata.cend(); ++iter) {
if (iter != statistics_file.blob_metadata.cbegin()) {
std::format_to(std::back_inserter(repr), ",{}", ToString(*iter));
} else {
std::format_to(std::back_inserter(repr), "{}", iter->ToString());
std::format_to(std::back_inserter(repr), "{}", ToString(*iter));
}
}
repr += "]]";
return repr;
}

std::string ToString(const PartitionStatisticsFile& partition_statistics_file) {
std::string repr = "PartitionStatisticsFile[";
std::format_to(std::back_inserter(repr), "snapshotId={},path={},fileSizeInBytes={},",
partition_statistics_file.snapshot_id, partition_statistics_file.path,
partition_statistics_file.file_size_in_bytes);
return repr;
}

} // namespace iceberg
Loading
Loading