diff --git a/src/iceberg/arrow/arrow_error_transform_internal.h b/src/iceberg/arrow/arrow_error_transform_internal.h index 588bab549..73255c039 100644 --- a/src/iceberg/arrow/arrow_error_transform_internal.h +++ b/src/iceberg/arrow/arrow_error_transform_internal.h @@ -22,8 +22,8 @@ #include #include -#include "iceberg/error.h" #include "iceberg/expected.h" +#include "iceberg/result.h" namespace iceberg::arrow { diff --git a/src/iceberg/arrow/arrow_fs_file_io.cc b/src/iceberg/arrow/arrow_fs_file_io.cc index 270ecb78e..535230954 100644 --- a/src/iceberg/arrow/arrow_fs_file_io.cc +++ b/src/iceberg/arrow/arrow_fs_file_io.cc @@ -26,8 +26,8 @@ namespace iceberg::arrow { /// \brief Read the content of the file at the given location. -expected ArrowFileSystemFileIO::ReadFile( - const std::string& file_location, std::optional length) { +Result ArrowFileSystemFileIO::ReadFile(const std::string& file_location, + std::optional length) { ::arrow::fs::FileInfo file_info(file_location); if (length.has_value()) { file_info.set_size(length.value()); @@ -52,8 +52,8 @@ expected ArrowFileSystemFileIO::ReadFile( } /// \brief Write the given content to the file at the given location. -expected ArrowFileSystemFileIO::WriteFile(const std::string& file_location, - std::string_view content) { +Status ArrowFileSystemFileIO::WriteFile(const std::string& file_location, + std::string_view content) { ICEBERG_ARROW_ASSIGN_OR_RETURN(auto file, arrow_fs_->OpenOutputStream(file_location)); ICEBERG_ARROW_RETURN_NOT_OK(file->Write(content.data(), content.size())); ICEBERG_ARROW_RETURN_NOT_OK(file->Flush()); @@ -62,8 +62,7 @@ expected ArrowFileSystemFileIO::WriteFile(const std::string& file_l } /// \brief Delete a file at the given location. -expected ArrowFileSystemFileIO::DeleteFile( - const std::string& file_location) { +Status ArrowFileSystemFileIO::DeleteFile(const std::string& file_location) { ICEBERG_ARROW_RETURN_NOT_OK(arrow_fs_->DeleteFile(file_location)); return {}; } diff --git a/src/iceberg/arrow/arrow_fs_file_io.h b/src/iceberg/arrow/arrow_fs_file_io.h index e79e75fea..b55af5d6a 100644 --- a/src/iceberg/arrow/arrow_fs_file_io.h +++ b/src/iceberg/arrow/arrow_fs_file_io.h @@ -37,15 +37,14 @@ class ICEBERG_BUNDLE_EXPORT ArrowFileSystemFileIO : public FileIO { ~ArrowFileSystemFileIO() override = default; /// \brief Read the content of the file at the given location. - expected ReadFile(const std::string& file_location, - std::optional length) override; + Result ReadFile(const std::string& file_location, + std::optional length) override; /// \brief Write the given content to the file at the given location. - expected WriteFile(const std::string& file_location, - std::string_view content) override; + Status WriteFile(const std::string& file_location, std::string_view content) override; /// \brief Delete a file at the given location. - expected DeleteFile(const std::string& file_location) override; + Status DeleteFile(const std::string& file_location) override; private: std::shared_ptr<::arrow::fs::FileSystem> arrow_fs_; diff --git a/src/iceberg/catalog.h b/src/iceberg/catalog.h index 8ab51dd0b..121b0da36 100644 --- a/src/iceberg/catalog.h +++ b/src/iceberg/catalog.h @@ -19,14 +19,13 @@ #pragma once -#include #include #include #include +#include #include -#include "iceberg/error.h" -#include "iceberg/expected.h" +#include "iceberg/result.h" #include "iceberg/table_identifier.h" #include "iceberg/type_fwd.h" @@ -48,8 +47,7 @@ class ICEBERG_EXPORT Catalog { /// \param ns a namespace /// \return a list of identifiers for tables or ErrorKind::kNoSuchNamespace /// if the namespace does not exist - virtual expected, Error> ListTables( - const Namespace& ns) const = 0; + virtual Result> ListTables(const Namespace& ns) const = 0; /// \brief Create a table /// @@ -59,10 +57,10 @@ class ICEBERG_EXPORT Catalog { /// \param location a location for the table; leave empty if unspecified /// \param properties a string map of table properties /// \return a Table instance or ErrorKind::kAlreadyExists if the table already exists - virtual expected, Error> CreateTable( + virtual Result> CreateTable( const TableIdentifier& identifier, const Schema& schema, const PartitionSpec& spec, const std::string& location, - const std::map& properties) = 0; + const std::unordered_map& properties) = 0; /// \brief Update a table /// @@ -70,7 +68,7 @@ class ICEBERG_EXPORT Catalog { /// \param requirements a list of table requirements /// \param updates a list of table updates /// \return a Table instance or ErrorKind::kAlreadyExists if the table already exists - virtual expected, Error> UpdateTable( + virtual Result> UpdateTable( const TableIdentifier& identifier, const std::vector>& requirements, const std::vector>& updates) = 0; @@ -84,10 +82,10 @@ class ICEBERG_EXPORT Catalog { /// \param properties a string map of table properties /// \return a Transaction to create the table or ErrorKind::kAlreadyExists if the table /// already exists - virtual expected, Error> StageCreateTable( + virtual Result> StageCreateTable( const TableIdentifier& identifier, const Schema& schema, const PartitionSpec& spec, const std::string& location, - const std::map& properties) = 0; + const std::unordered_map& properties) = 0; /// \brief Check whether table exists /// @@ -110,7 +108,7 @@ class ICEBERG_EXPORT Catalog { /// \param identifier a table identifier /// \return instance of Table implementation referred to by identifier or /// ErrorKind::kNoSuchTable if the table does not exist - virtual expected, Error> LoadTable( + virtual Result> LoadTable( const TableIdentifier& identifier) const = 0; /// \brief Register a table with the catalog if it does not exist @@ -118,7 +116,7 @@ class ICEBERG_EXPORT Catalog { /// \param identifier a table identifier /// \param metadata_file_location the location of a metadata file /// \return a Table instance or ErrorKind::kAlreadyExists if the table already exists - virtual expected, Error> RegisterTable( + virtual Result> RegisterTable( const TableIdentifier& identifier, const std::string& metadata_file_location) = 0; /// \brief Initialize a catalog given a custom name and a map of catalog properties @@ -129,8 +127,9 @@ class ICEBERG_EXPORT Catalog { /// /// \param name a custom name for the catalog /// \param properties catalog properties - virtual void Initialize(const std::string& name, - const std::map& properties) = 0; + virtual void Initialize( + const std::string& name, + const std::unordered_map& properties) = 0; /// \brief Instantiate a builder to either create a table or start a create/replace /// transaction @@ -169,7 +168,7 @@ class ICEBERG_EXPORT Catalog { /// \param properties key/value properties /// \return this for method chaining virtual TableBuilder& WithProperties( - const std::map& properties) = 0; + const std::unordered_map& properties) = 0; /// \brief Adds a key/value property to the table /// diff --git a/src/iceberg/file_io.h b/src/iceberg/file_io.h index 03922f654..c31d39bb3 100644 --- a/src/iceberg/file_io.h +++ b/src/iceberg/file_io.h @@ -23,9 +23,8 @@ #include #include -#include "iceberg/error.h" -#include "iceberg/expected.h" #include "iceberg/iceberg_export.h" +#include "iceberg/result.h" namespace iceberg { @@ -50,8 +49,8 @@ class ICEBERG_EXPORT FileIO { /// the length to read, e.g. S3 `GetObject` has a Range parameter. /// \return The content of the file if the read succeeded, an error code if the read /// failed. - virtual expected ReadFile(const std::string& file_location, - std::optional length) { + virtual Result ReadFile(const std::string& file_location, + std::optional length) { // We provide a default implementation to avoid Windows linker error LNK2019. return unexpected{ {.kind = ErrorKind::kNotImplemented, .message = "ReadFile not implemented"}}; @@ -64,8 +63,7 @@ class ICEBERG_EXPORT FileIO { /// \param overwrite If true, overwrite the file if it exists. If false, fail if the /// file exists. /// \return void if the write succeeded, an error code if the write failed. - virtual expected WriteFile(const std::string& file_location, - std::string_view content) { + virtual Status WriteFile(const std::string& file_location, std::string_view content) { return unexpected{ {.kind = ErrorKind::kNotImplemented, .message = "WriteFile not implemented"}}; } @@ -74,7 +72,7 @@ class ICEBERG_EXPORT FileIO { /// /// \param file_location The location of the file to delete. /// \return void if the delete succeeded, an error code if the delete failed. - virtual expected DeleteFile(const std::string& file_location) { + virtual Status DeleteFile(const std::string& file_location) { return unexpected{ {.kind = ErrorKind::kNotImplemented, .message = "DeleteFile not implemented"}}; } diff --git a/src/iceberg/json_internal.cc b/src/iceberg/json_internal.cc index 6847b3ac9..5307aa562 100644 --- a/src/iceberg/json_internal.cc +++ b/src/iceberg/json_internal.cc @@ -24,8 +24,8 @@ #include -#include "iceberg/error.h" #include "iceberg/expected.h" +#include "iceberg/result.h" #include "iceberg/schema.h" #include "iceberg/schema_internal.h" #include "iceberg/sort_order.h" @@ -69,7 +69,7 @@ constexpr std::string_view kElementRequired = "element-required"; constexpr std::string_view kValueRequired = "value-required"; template -expected GetJsonValue(const nlohmann::json& json, std::string_view key) { +Result GetJsonValue(const nlohmann::json& json, std::string_view key) { if (!json.contains(key)) { return unexpected({ .kind = ErrorKind::kJsonParseError, @@ -109,8 +109,7 @@ nlohmann::json ToJson(const SortOrder& sort_order) { return json; } -expected, Error> SortFieldFromJson( - const nlohmann::json& json) { +Result> SortFieldFromJson(const nlohmann::json& json) { ICEBERG_ASSIGN_OR_RAISE(auto source_id, GetJsonValue(json, kSourceId)); ICEBERG_ASSIGN_OR_RAISE( auto transform, @@ -125,8 +124,7 @@ expected, Error> SortFieldFromJson( null_order); } -expected, Error> SortOrderFromJson( - const nlohmann::json& json) { +Result> SortOrderFromJson(const nlohmann::json& json) { ICEBERG_ASSIGN_OR_RAISE(auto order_id, GetJsonValue(json, kOrderId)); ICEBERG_ASSIGN_OR_RAISE(auto fields, GetJsonValue(json, kFields)); @@ -232,7 +230,7 @@ nlohmann::json SchemaToJson(const Schema& schema) { namespace { -expected, Error> StructTypeFromJson(const nlohmann::json& json) { +Result> StructTypeFromJson(const nlohmann::json& json) { ICEBERG_ASSIGN_OR_RAISE(auto json_fields, GetJsonValue(json, kFields)); std::vector fields; @@ -244,7 +242,7 @@ expected, Error> StructTypeFromJson(const nlohmann::json& return std::make_unique(std::move(fields)); } -expected, Error> ListTypeFromJson(const nlohmann::json& json) { +Result> ListTypeFromJson(const nlohmann::json& json) { ICEBERG_ASSIGN_OR_RAISE(auto element_type, TypeFromJson(json[kElement])); ICEBERG_ASSIGN_OR_RAISE(auto element_id, GetJsonValue(json, kElementId)); ICEBERG_ASSIGN_OR_RAISE(auto element_required, @@ -255,7 +253,7 @@ expected, Error> ListTypeFromJson(const nlohmann::json& js std::move(element_type), !element_required)); } -expected, Error> MapTypeFromJson(const nlohmann::json& json) { +Result> MapTypeFromJson(const nlohmann::json& json) { ICEBERG_ASSIGN_OR_RAISE( auto key_type, GetJsonValue(json, kKey).and_then(TypeFromJson)); ICEBERG_ASSIGN_OR_RAISE( @@ -274,7 +272,7 @@ expected, Error> MapTypeFromJson(const nlohmann::json& jso } // namespace -expected, Error> TypeFromJson(const nlohmann::json& json) { +Result> TypeFromJson(const nlohmann::json& json) { if (json.is_string()) { std::string type_str = json.get(); if (type_str == "boolean") { @@ -346,7 +344,7 @@ expected, Error> TypeFromJson(const nlohmann::json& json) } } -expected, Error> FieldFromJson(const nlohmann::json& json) { +Result> FieldFromJson(const nlohmann::json& json) { ICEBERG_ASSIGN_OR_RAISE( auto type, GetJsonValue(json, kType).and_then(TypeFromJson)); ICEBERG_ASSIGN_OR_RAISE(auto field_id, GetJsonValue(json, kId)); @@ -357,7 +355,7 @@ expected, Error> FieldFromJson(const nlohmann::json !required); } -expected, Error> SchemaFromJson(const nlohmann::json& json) { +Result> SchemaFromJson(const nlohmann::json& json) { ICEBERG_ASSIGN_OR_RAISE(auto schema_id, GetJsonValue(json, kSchemaId)); ICEBERG_ASSIGN_OR_RAISE(auto type, TypeFromJson(json)); diff --git a/src/iceberg/json_internal.h b/src/iceberg/json_internal.h index c23eec743..5ea4d4750 100644 --- a/src/iceberg/json_internal.h +++ b/src/iceberg/json_internal.h @@ -24,8 +24,8 @@ #include -#include "iceberg/error.h" #include "iceberg/expected.h" +#include "iceberg/result.h" #include "iceberg/type_fwd.h" namespace iceberg { @@ -59,7 +59,7 @@ nlohmann::json ToJson(const SortOrder& sort_order); /// \param json The JSON object representing a `SortField`. /// \return An `expected` value containing either a `SortField` object or an error. If the /// JSON is malformed or missing expected fields, an error will be returned. -expected, Error> SortFieldFromJson(const nlohmann::json& json); +Result> SortFieldFromJson(const nlohmann::json& json); /// \brief Deserializes a JSON object into a `SortOrder` object. /// @@ -70,7 +70,7 @@ expected, Error> SortFieldFromJson(const nlohmann::js /// \param json The JSON object representing a `SortOrder`. /// \return An `expected` value containing either a `SortOrder` object or an error. If the /// JSON is malformed or missing expected fields, an error will be returned. -expected, Error> SortOrderFromJson(const nlohmann::json& json); +Result> SortOrderFromJson(const nlohmann::json& json); /// \brief Convert an Iceberg Schema to JSON. /// @@ -94,18 +94,18 @@ nlohmann::json FieldToJson(const SchemaField& field); /// /// \param[in] json The JSON representation of the schema. /// \return The Iceberg schema or an error if the conversion fails. -expected, Error> SchemaFromJson(const nlohmann::json& json); +Result> SchemaFromJson(const nlohmann::json& json); /// \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. -expected, Error> TypeFromJson(const nlohmann::json& json); +Result> TypeFromJson(const nlohmann::json& json); /// \brief Convert JSON to an Iceberg SchemaField. /// /// \param[in] json The JSON representation of the field. /// \return The Iceberg field or an error if the conversion fails. -expected, Error> FieldFromJson(const nlohmann::json& json); +Result> FieldFromJson(const nlohmann::json& json); } // namespace iceberg diff --git a/src/iceberg/error.h b/src/iceberg/result.h similarity index 82% rename from src/iceberg/error.h rename to src/iceberg/result.h index a296fcc0c..7d12f367d 100644 --- a/src/iceberg/error.h +++ b/src/iceberg/result.h @@ -21,6 +21,7 @@ #include +#include "iceberg/expected.h" #include "iceberg/iceberg_export.h" namespace iceberg { @@ -47,4 +48,16 @@ struct ICEBERG_EXPORT [[nodiscard]] Error { std::string message; }; +/// /brief Default error trait +template +struct DefaultError { + using type = Error; +}; + +/// \brief Result alias +template ::type> +using Result = expected; + +using Status = Result; + } // namespace iceberg diff --git a/src/iceberg/schema_internal.cc b/src/iceberg/schema_internal.cc index 5a9620e57..a00c0a1e3 100644 --- a/src/iceberg/schema_internal.cc +++ b/src/iceberg/schema_internal.cc @@ -169,7 +169,7 @@ ArrowErrorCode ToArrowSchema(const Type& type, bool optional, std::string_view n } // namespace -expected ToArrowSchema(const Schema& schema, ArrowSchema* out) { +Status ToArrowSchema(const Schema& schema, ArrowSchema* out) { if (out == nullptr) [[unlikely]] { return unexpected{{.kind = ErrorKind::kInvalidArgument, .message = "Output Arrow schema cannot be null"}}; @@ -206,9 +206,9 @@ int32_t GetFieldId(const ArrowSchema& schema) { return std::stoi(std::string(field_id_value.data, field_id_value.size_bytes)); } -expected, Error> FromArrowSchema(const ArrowSchema& schema) { +Result> FromArrowSchema(const ArrowSchema& schema) { auto to_schema_field = - [](const ArrowSchema& schema) -> expected, Error> { + [](const ArrowSchema& schema) -> Result> { auto field_type_result = FromArrowSchema(schema); if (!field_type_result) { return unexpected(field_type_result.error()); @@ -341,8 +341,8 @@ std::unique_ptr FromStructType(StructType&& struct_type, int32_t schema_ return std::make_unique(schema_id, std::move(fields)); } -expected, Error> FromArrowSchema(const ArrowSchema& schema, - int32_t schema_id) { +Result> FromArrowSchema(const ArrowSchema& schema, + int32_t schema_id) { auto type_result = FromArrowSchema(schema); if (!type_result) { return unexpected(type_result.error()); diff --git a/src/iceberg/schema_internal.h b/src/iceberg/schema_internal.h index ab7f1ab1f..de0283ff7 100644 --- a/src/iceberg/schema_internal.h +++ b/src/iceberg/schema_internal.h @@ -23,8 +23,8 @@ #include -#include "iceberg/error.h" #include "iceberg/expected.h" +#include "iceberg/result.h" #include "iceberg/type_fwd.h" namespace iceberg { @@ -39,15 +39,15 @@ constexpr std::string_view kFieldIdKey = "ICEBERG:field_id"; /// \param[in] schema The Iceberg schema to convert. /// \param[out] out The Arrow schema to convert to. /// \return An error if the conversion fails. -expected ToArrowSchema(const Schema& schema, ArrowSchema* out); +Status ToArrowSchema(const Schema& schema, ArrowSchema* out); /// \brief Convert an Arrow schema to an Iceberg schema. /// /// \param[in] schema The Arrow schema to convert. /// \param[in] schema_id The schema ID of the Iceberg schema. /// \return The Iceberg schema or an error if the conversion fails. -expected, Error> FromArrowSchema(const ArrowSchema& schema, - int32_t schema_id); +Result> FromArrowSchema(const ArrowSchema& schema, + int32_t schema_id); /// \brief Convert a struct type to an Iceberg schema. /// diff --git a/src/iceberg/sort_field.h b/src/iceberg/sort_field.h index f02aef4b2..6037cec72 100644 --- a/src/iceberg/sort_field.h +++ b/src/iceberg/sort_field.h @@ -28,9 +28,9 @@ #include #include -#include "iceberg/error.h" #include "iceberg/expected.h" #include "iceberg/iceberg_export.h" +#include "iceberg/result.h" #include "iceberg/type_fwd.h" #include "iceberg/util/formattable.h" @@ -55,7 +55,7 @@ ICEBERG_EXPORT constexpr std::string_view SortDirectionToString(SortDirection di } } /// \brief Get the relative sort direction from name -ICEBERG_EXPORT constexpr expected SortDirectionFromString( +ICEBERG_EXPORT constexpr Result SortDirectionFromString( std::string_view str) { if (str == "asc") return SortDirection::kAscending; if (str == "desc") return SortDirection::kDescending; @@ -82,8 +82,7 @@ ICEBERG_EXPORT constexpr std::string_view NullOrderToString(NullOrder null_order } } /// \brief Get the relative null order from name -ICEBERG_EXPORT constexpr expected NullOrderFromString( - std::string_view str) { +ICEBERG_EXPORT constexpr Result NullOrderFromString(std::string_view str) { if (str == "nulls-first") return NullOrder::kFirst; if (str == "nulls-last") return NullOrder::kLast; return unexpected({.kind = ErrorKind::kInvalidArgument, diff --git a/src/iceberg/table.h b/src/iceberg/table.h index a62b41b57..11a9fc982 100644 --- a/src/iceberg/table.h +++ b/src/iceberg/table.h @@ -19,14 +19,13 @@ #pragma once -#include #include #include +#include #include -#include "iceberg/error.h" -#include "iceberg/expected.h" #include "iceberg/iceberg_export.h" +#include "iceberg/result.h" #include "iceberg/type_fwd.h" namespace iceberg { @@ -43,28 +42,30 @@ class ICEBERG_EXPORT Table { virtual const std::string& uuid() const = 0; /// \brief Refresh the current table metadata - virtual expected Refresh() = 0; + virtual Status Refresh() = 0; /// \brief Return the schema for this table virtual const std::shared_ptr& schema() const = 0; /// \brief Return a map of schema for this table - virtual const std::map>& schemas() const = 0; + virtual const std::unordered_map>& schemas() const = 0; /// \brief Return the partition spec for this table virtual const std::shared_ptr& spec() const = 0; /// \brief Return a map of partition specs for this table - virtual const std::map>& specs() const = 0; + virtual const std::unordered_map>& specs() + const = 0; /// \brief Return the sort order for this table virtual const std::shared_ptr& sort_order() const = 0; /// \brief Return a map of sort order IDs to sort orders for this table - virtual const std::map>& sort_orders() const = 0; + virtual const std::unordered_map>& sort_orders() + const = 0; /// \brief Return a map of string properties for this table - virtual const std::map& properties() const = 0; + virtual const std::unordered_map& properties() const = 0; /// \brief Return the table's base location virtual const std::string& location() const = 0; @@ -77,8 +78,7 @@ class ICEBERG_EXPORT Table { /// /// \param snapshot_id the ID of the snapshot to get /// \return the Snapshot with the given id - virtual expected, Error> snapshot( - int64_t snapshot_id) const = 0; + virtual Result> snapshot(int64_t snapshot_id) const = 0; /// \brief Get the snapshots of this table virtual const std::vector>& snapshots() const = 0; diff --git a/src/iceberg/transform.h b/src/iceberg/transform.h index f948a450b..4e8ecfc0d 100644 --- a/src/iceberg/transform.h +++ b/src/iceberg/transform.h @@ -25,9 +25,9 @@ #include #include "iceberg/arrow_c_data.h" -#include "iceberg/error.h" #include "iceberg/expected.h" #include "iceberg/iceberg_export.h" +#include "iceberg/result.h" #include "iceberg/type_fwd.h" #include "iceberg/util/formattable.h" diff --git a/test/matchers.h b/test/matchers.h index eca3b6fb2..f04d4a51b 100644 --- a/test/matchers.h +++ b/test/matchers.h @@ -22,7 +22,7 @@ #include #include -#include "iceberg/error.h" +#include "iceberg/result.h" /* * \brief Define custom matchers for expected values