GCC Code Coverage Report


Directory: libimgdoc2/
File: libimgdoc2/inc/IDocumentMetadata.h
Date: 2025-02-03 12:41:04
Exec Total Coverage
Lines: 12 12 100.0%
Functions: 9 9 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 // SPDX-FileCopyrightText: 2023 Carl Zeiss Microscopy GmbH
2 //
3 // SPDX-License-Identifier: MIT
4
5 #pragma once
6
7 #include <cstdint>
8 #include <string>
9 #include <variant>
10 #include <functional>
11 #include <limits>
12 #include <optional>
13 #include <type_traits>
14 #include "types.h"
15
16 namespace imgdoc2
17 {
18 /// Values that represent the type of a document metadata item.
19 enum class DocumentMetadataType : std::uint8_t
20 {
21 /// An enum constant representing the invalid option. This value is not legal for any call into the document metadata API.
22 kInvalid = 0,
23
24 /// An enum constant representing the default option.Default means that the type is determined from the value variant.
25 /// The mapping is as follows: If the value variant is std::monostate, the type is set to Invalid. If the value variant is a string, the type is set to Text.
26 /// If the value variant is int32_t, the type is set to Int32. If the value variant is double, the type is set to Double.
27 kDefault,
28
29 /// An enum constant representing the invalid option. This means that there is no value stored for this metadata item.
30 kNull,
31
32 /// An enum constant representing the 'text' option. The value variant must contain a string.
33 kText,
34
35 /// An enum constant representing the 'int32' option. The value variant must contain an int32.
36 kInt32,
37
38 /// An enum constant representing the 'JSON' option. The value variant must contain a string, and this string must be valid JSON.
39 kJson,
40
41 /// An enum constant representing the 'double' option. The value variant must contain a double.
42 kDouble
43 };
44
45 /// Base interface for document metadata.
46 class IDocumentMetadata
47 {
48 public:
49 /// Defines an alias representing the metadata item variant. This variant can contain a string, an int32, a double or a std::monostate.
50 typedef std::variant<std::string, std::int32_t, double, std::monostate> metadata_item_variant;
51
52 344 virtual ~IDocumentMetadata() = default;
53
54 // no copy and no move (-> https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c21-if-you-define-or-delete-any-copy-move-or-destructor-function-define-or-delete-them-all )
55 172 IDocumentMetadata() = default;
56 IDocumentMetadata(const IDocumentMetadata&) = delete; // copy constructor
57 IDocumentMetadata& operator=(const IDocumentMetadata&) = delete; // copy assignment
58 IDocumentMetadata(IDocumentMetadata&&) = delete; // move constructor
59 IDocumentMetadata& operator=(IDocumentMetadata&&) = delete; // move assignment
60 };
61
62 /// Values that represent different pieces of information that can be retrieved from a document metadata item.
63 /// The values are a bitmask, so they can be combined using the bitwise OR operator.
64 enum class DocumentMetadataItemFlags : std::uint8_t
65 {
66 None = 0, ///< An enum constant representing the "none option", meaning that no information should be retrieved or is valid.
67 kPrimaryKeyValid = 1, ///< An enum constant representing the "primary key valid" option, meaning that the primary key is valid.
68 kNameValid = 2, ///< An enum constant representing the "name valid" option, meaning that the name is valid.
69 kDocumentMetadataTypeAndValueValid = 4, ///< An enum constant representing the "type and value valid" option, meaning that the "type and value" are to be retrieved or are valid.
70 kCompletePath = 8, ///< An enum constant representing the "complete path" option, meaning that the "complete path" is to be retrieved or is valid.
71
72 kAll = kPrimaryKeyValid | kNameValid | kDocumentMetadataTypeAndValueValid,
73 kAllWithCompletePath = kAll | kCompletePath
74 };
75
76 /// Bitwise 'or' operator for DocumentMetadataItemFlags. This is needed to be able to use the flags in a bitwise fashion.
77 /// C.f. https://stackoverflow.com/a/34220050/522591.
78 /// \param x A bit-field to process.
79 /// \param y One or more bits to OR into the bit-field.
80 /// \returns The result of the operation.
81 322 inline constexpr DocumentMetadataItemFlags operator|(DocumentMetadataItemFlags x, DocumentMetadataItemFlags y)
82 {
83 322 return static_cast<DocumentMetadataItemFlags>(static_cast<std::underlying_type_t<DocumentMetadataItemFlags>>(x) | static_cast<std::underlying_type_t<DocumentMetadataItemFlags>>(y));
84 }
85
86 /// Bitwise 'and' operator for DocumentMetadataItemFlags. This is needed to be able to use the flags in a bitwise fashion.
87 /// C.f. https://stackoverflow.com/a/34220050/522591.
88 /// \param x A bit-field to process.
89 /// \param y A mask of bits to apply to the bit-field.
90 /// \returns The result of the operation.
91 1686 inline constexpr DocumentMetadataItemFlags operator&(DocumentMetadataItemFlags x, DocumentMetadataItemFlags y)
92 {
93 1686 return static_cast<DocumentMetadataItemFlags>(static_cast<std::underlying_type_t<DocumentMetadataItemFlags>>(x) & static_cast<std::underlying_type_t<DocumentMetadataItemFlags>>(y));
94 }
95
96 /// Bitwise 'ones complement' operator for DocumentMetadataItemFlags. This is needed to be able to use the flags in a bitwise fashion.
97 /// \param x The DocumentMetadataItemFlags to process.
98 /// \returns The result of the operation.
99 64 inline constexpr DocumentMetadataItemFlags operator~(DocumentMetadataItemFlags x)
100 {
101 64 return static_cast<DocumentMetadataItemFlags>(~static_cast<std::underlying_type_t<DocumentMetadataItemFlags>>(x));
102 }
103
104 /// This structure is used to return information about a document metadata item. The flags field specifies which pieces of information are valid.
105 struct DocumentMetadataItem
106 {
107 DocumentMetadataItemFlags flags{ DocumentMetadataItemFlags::None }; ///< The flags indicating which pieces of information are valid.
108 imgdoc2::dbIndex primary_key{ std::numeric_limits<imgdoc2::dbIndex>::max() }; ///< The primary key of the metadata item. Check the flags field to see if this is valid.
109 std::string name; ///< The name of the metadata item. Check the flags field to see if this is valid.
110 std::string complete_path; ///< The complete path of the metadata item. Check the flags field to see if this is valid.
111 DocumentMetadataType type{ DocumentMetadataType::kInvalid }; ///< The type of the metadata item. Check the flags field to see if this is valid.
112 IDocumentMetadata::metadata_item_variant value; ///< The value of the metadata item. Check the flags field to see if this is valid.
113 };
114
115 /// The interface for read-only access to document metadata.
116 class IDocumentMetadataRead : public IDocumentMetadata
117 {
118 public:
119 160 ~IDocumentMetadataRead() override = default;
120
121 /// Get the item identified by the specified key. The argument 'flags' specifies which pieces of information should be retrieved.
122 /// Only the information specified in the flags can be expected to be valid in the returned DocumentMetadataItem.
123 /// If the item does not exist, an exception of type imgdoc2::non_existing_item_exception is thrown.
124 ///
125 /// \param primary_key The key of the metadata item to be retrieved.
126 /// \param flags The flags.
127 ///
128 /// \returns The item.
129 virtual imgdoc2::DocumentMetadataItem GetItem(imgdoc2::dbIndex primary_key, DocumentMetadataItemFlags flags) = 0;
130
131 /// Get the item identified by the specified path. The argument 'flags' specifies which pieces of information should be retrieved.
132 /// Only the information specified in the flags can be expected to be valid in the returned DocumentMetadataItem.
133 /// If the path does not exist or is invalid, an exception of type imgdoc2::invalid_path_exception is thrown.
134 ///
135 /// \param path The path of the item to be retrieved.
136 /// \param flags The flags.
137 ///
138 /// \returns The item.
139 virtual imgdoc2::DocumentMetadataItem GetItemForPath(const std::string& path, imgdoc2::DocumentMetadataItemFlags flags) = 0;
140
141 /// Enumerate items for which the specified node 'parent' is the ancestor. If recursive is false, then only the direct children of the specified parent are enumerated.
142 /// If recursive is true, then all descendants of the specified parent are enumerated.
143 /// If the specified parent is not valid (nullopt), then all items are enumerated.
144 /// If the specified parent is valid, but does not exist, an exception of type imgdoc2::non_existing_item_exception is thrown.
145 ///
146 /// \param parent The parent node for which the children are to be enumerated. If nullopt, then all items are enumerated.
147 /// \param recursive False to enumerate only the direct children of the specified parent, true to enumerate all descendants of the specified parent.
148 /// \param flags The flags.
149 /// \param func The items found are reported to this function. If it returns false, the enumeration is stopped.
150 virtual void EnumerateItems(
151 std::optional<imgdoc2::dbIndex> parent,
152 bool recursive,
153 DocumentMetadataItemFlags flags,
154 const std::function<bool(imgdoc2::dbIndex, const DocumentMetadataItem& item)>& func) = 0;
155
156 /// Enumerate items below the specified path. If recursive is false, then only the direct children of the specified path are enumerated.
157 /// If recursive is true, then all descendants of the specified parent are enumerated.
158 /// If the path is empty, then all items are enumerated.
159 /// If the specified path does not exist, an exception of type imgdoc2::invalid_path_exception is thrown.
160 ///
161 /// \param path The path of the parent.
162 /// \param recursive False to enumerate only the direct children of the specified parent, true to enumerate all descendants of the specified parent.
163 /// \param flags The flags.
164 /// \param func The items found are reported to this function. If it returns false, the enumeration is stopped.
165 virtual void EnumerateItemsForPath(
166 const std::string& path,
167 bool recursive,
168 DocumentMetadataItemFlags flags,
169 const std::function<bool(imgdoc2::dbIndex, const DocumentMetadataItem& item)>& func) = 0;
170
171 // no copy and no move (-> https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c21-if-you-define-or-delete-any-copy-move-or-destructor-function-define-or-delete-them-all )
172 80 IDocumentMetadataRead() = default;
173 IDocumentMetadataRead(const IDocumentMetadataRead&) = delete; // copy constructor
174 IDocumentMetadataRead& operator=(const IDocumentMetadataRead&) = delete; // copy assignment
175 IDocumentMetadataRead(IDocumentMetadataRead&&) = delete; // move constructor
176 IDocumentMetadataRead& operator=(IDocumentMetadataRead&&) = delete; // move assignment
177 };
178
179 /// The interface for write access to document metadata.
180 class IDocumentMetadataWrite : public IDocumentMetadata
181 {
182 public:
183 184 ~IDocumentMetadataWrite() override = default;
184
185 /// This method updates or creates a node with the name as specified in the parameter 'name'
186 /// as a child of the node specified by 'parent'. If 'create_node_if_not_exists' is true, the
187 /// node with the name 'name' is created if it does not exist. If 'create_node_if_not_exists' is
188 /// false, the mode is not created if it does not exist. In this case, the method throws a
189 /// non_existing_item_exception.
190 ///
191 /// \param parent The parent node. If this is std::nullopt, it identifies the root node.
192 /// \param create_node_if_not_exists If true, the node is created if it does not exist.
193 /// \param name The name of the node to be updated or created.
194 /// \param type The type of the node.
195 /// \param value The value of the node.
196 ///
197 /// \returns The primary_key of the updated or created node.
198 virtual imgdoc2::dbIndex UpdateOrCreateItem(
199 std::optional<imgdoc2::dbIndex> parent,
200 bool create_node_if_not_exists,
201 const std::string& name,
202 DocumentMetadataType type,
203 const IDocumentMetadata::metadata_item_variant& value) = 0;
204
205 /// Updates or creates a node specified by the path 'path'. 'create_node_if_not_exists' controls if
206 /// the node is created if it does not exist. This controls the behavior if the last element of the
207 /// path. If 'create_path_if_not_exists' is true, all nodes in the path are created if they do not
208 /// exist.
209 ///
210 /// \param create_path_if_not_exists True to create nodes in the path if they do not exist. This refers to all nodes in the path except the last one.
211 /// \param create_node_if_not_exists True to create node if not exists. This refers to the last node in the path.
212 /// \param path The path of the node.
213 /// \param type The type of the node.
214 /// \param value The value of the node.
215 ///
216 /// \returns The primary_key of the updated or created node.
217 virtual imgdoc2::dbIndex UpdateOrCreateItemForPath(
218 bool create_path_if_not_exists,
219 bool create_node_if_not_exists,
220 const std::string& path,
221 DocumentMetadataType type,
222 const IDocumentMetadata::metadata_item_variant& value) = 0;
223
224 /// Deletes the item specified by 'primary_key'. If 'recursively' is true, all child nodes are
225 /// also deleted. If 'recursively' is false, the node is only deleted if it has no child nodes.
226 /// The method returns the number of deleted nodes - it does not throw an exception if the
227 /// primary key does not exist or if the node has child nodes and 'recursively' is false.
228 /// Note that the root node cannot be deleted - however, it is possible to delete all child nodes of the root node.
229 ///
230 /// \param primary_key Key of the node to be deleted. If this the optional has no value, this means "the root".
231 /// \param recursively True if all child nodes should be deleted, false if only the node itself should be deleted.
232 ///
233 /// \returns The number of deleted nodes as a result by this call.
234 virtual std::uint64_t DeleteItem(
235 std::optional<imgdoc2::dbIndex> primary_key,
236 bool recursively) = 0;
237
238 /// Deletes the item specified by 'path'. If 'recursively' is true, all child nodes are
239 /// also deleted. If 'recursively' is false, the node is only deleted if it has no child nodes.
240 /// The method returns the number of deleted nodes - it does not throw an exception if the
241 /// primary key does not exist or if the node has child nodes and 'recursively' is false.
242 /// Note that the root node cannot be deleted - however, it is possible to delete all child nodes of the root node.
243 ///
244 /// \param path The path of the node to be deleted. If this is an empty string, it identifies the "root".
245 /// \param recursively True if all child nodes should be deleted, false if only the node itself should be deleted.
246 ///
247 /// \returns The number of deleted nodes as a result by this call.
248 virtual std::uint64_t DeleteItemForPath(
249 const std::string& path,
250 bool recursively) = 0;
251
252 // no copy and no move (-> https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c21-if-you-define-or-delete-any-copy-move-or-destructor-function-define-or-delete-them-all )
253 92 IDocumentMetadataWrite() = default;
254 IDocumentMetadataWrite(const IDocumentMetadataWrite&) = delete; // copy constructor
255 IDocumentMetadataWrite& operator=(const IDocumentMetadataWrite&) = delete; // copy assignment
256 IDocumentMetadataWrite(IDocumentMetadataWrite&&) = delete; // move constructor
257 IDocumentMetadataWrite& operator=(IDocumentMetadataWrite&&) = delete; // move assignment
258 };
259 }
260