1 // Copyright 2018 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_INTERNAL_COMMON_METADATA_H 16 #define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_INTERNAL_COMMON_METADATA_H 17 18 #include "google/cloud/storage/version.h" 19 #include "google/cloud/status_or.h" 20 #include "absl/types/optional.h" 21 #include <chrono> 22 #include <map> 23 #include <utility> 24 #include <vector> 25 26 namespace google { 27 namespace cloud { 28 namespace storage { 29 inline namespace STORAGE_CLIENT_NS { 30 /// A simple wrapper for the `owner` field in `internal::CommonMetadata`. 31 struct Owner { 32 std::string entity; 33 std::string entity_id; 34 }; 35 36 inline bool operator==(Owner const& lhs, Owner const& rhs) { 37 return std::tie(lhs.entity, lhs.entity_id) == 38 std::tie(rhs.entity, rhs.entity_id); 39 } 40 41 inline bool operator<(Owner const& lhs, Owner const& rhs) { 42 return std::tie(lhs.entity, lhs.entity_id) < 43 std::tie(rhs.entity, rhs.entity_id); 44 } 45 46 inline bool operator!=(Owner const& lhs, Owner const& rhs) { 47 return std::rel_ops::operator!=(lhs, rhs); 48 } 49 50 inline bool operator>(Owner const& lhs, Owner const& rhs) { 51 return std::rel_ops::operator>(lhs, rhs); 52 } 53 54 inline bool operator<=(Owner const& lhs, Owner const& rhs) { 55 return std::rel_ops::operator<=(lhs, rhs); 56 } 57 58 inline bool operator>=(Owner const& lhs, Owner const& rhs) { 59 return std::rel_ops::operator>=(lhs, rhs); 60 } 61 62 namespace internal { 63 class GrpcClient; 64 template <typename Derived> 65 struct CommonMetadataParser; 66 67 /** 68 * Defines common attributes to both `BucketMetadata` and `ObjectMetadata`. 69 * 70 * @tparam Derived a class derived from CommonMetadata<Derived>. This class uses 71 * the Curiously recurring template pattern. 72 * 73 * @see https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern 74 */ 75 template <typename Derived> 76 class CommonMetadata { 77 public: 78 CommonMetadata() = default; 79 etag()80 std::string const& etag() const { return etag_; } id()81 std::string const& id() const { return id_; } kind()82 std::string const& kind() const { return kind_; } metageneration()83 std::int64_t metageneration() const { return metageneration_; } 84 name()85 std::string const& name() const { return name_; } 86 // NOLINTNEXTLINE(performance-unnecessary-value-param) TODO(#4112) set_name(std::string value)87 void set_name(std::string value) { name_ = std::move(value); } 88 has_owner()89 bool has_owner() const { return owner_.has_value(); } owner()90 Owner const& owner() const { return owner_.value(); } 91 self_link()92 std::string const& self_link() const { return self_link_; } 93 storage_class()94 std::string const& storage_class() const { return storage_class_; } 95 // NOLINTNEXTLINE(performance-unnecessary-value-param) TODO(#4112) set_storage_class(std::string value)96 void set_storage_class(std::string value) { 97 storage_class_ = std::move(value); 98 } 99 time_created()100 std::chrono::system_clock::time_point time_created() const { 101 return time_created_; 102 } updated()103 std::chrono::system_clock::time_point updated() const { return updated_; } 104 105 private: 106 friend class GrpcClient; 107 template <typename ParserDerived> 108 friend struct CommonMetadataParser; 109 110 // Keep the fields in alphabetical order. 111 std::string etag_; 112 std::string id_; 113 std::string kind_; 114 std::int64_t metageneration_{0}; 115 std::string name_; 116 absl::optional<Owner> owner_; 117 std::string self_link_; 118 std::string storage_class_; 119 std::chrono::system_clock::time_point time_created_; 120 std::chrono::system_clock::time_point updated_; 121 }; 122 123 template <typename T> 124 inline bool operator==(CommonMetadata<T> const& lhs, 125 CommonMetadata<T> const& rhs) { 126 // etag changes each time the metadata changes, so that is the best field 127 // to short-circuit this comparison. The check the name, project number, 128 // and metadata generation, which have the next best chance to 129 // short-circuit. The rest just put in alphabetical order. 130 return lhs.name() == rhs.name() && 131 lhs.metageneration() == rhs.metageneration() && lhs.id() == rhs.id() && 132 lhs.etag() == rhs.etag() && lhs.kind() == rhs.kind() && 133 lhs.self_link() == rhs.self_link() && 134 lhs.storage_class() == rhs.storage_class() && 135 lhs.time_created() == rhs.time_created() && 136 lhs.updated() == rhs.updated() && lhs.has_owner() == rhs.has_owner() && 137 (!lhs.has_owner() || lhs.owner() == rhs.owner()); 138 } 139 140 template <typename T> 141 inline bool operator!=(CommonMetadata<T> const& lhs, 142 CommonMetadata<T> const& rhs) { 143 return std::rel_ops::operator!=(lhs, rhs); 144 } 145 146 } // namespace internal 147 } // namespace STORAGE_CLIENT_NS 148 } // namespace storage 149 } // namespace cloud 150 } // namespace google 151 152 #endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_INTERNAL_COMMON_METADATA_H 153