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 |
|
|
|