.TH "md_doc_help_elektra-meta-data" 3elektra "Sun May 29 2016" "Version 0.8.14" "Elektra" \" -*- nroff -*- .ad l .nh .SH NAME md_doc_help_elektra-meta-data \- elektra-meta-data(7) -- meta data \fBmetadata\fP is data about data\&. Up to now, there has been a limited number of metadata entries suited for \fCfilesys\fP\&. For \fCfilesys\fP this was efficient, but it was of limited use for every other backend\&. This situation has now changed fundamentally by introducing arbitrary metadata\&. .PP In Elektra, \fImetakeys\fP represent metadata\&. They can be stored in a key database, often within the representation of the \fCKey\fP\&. Metakey is a \fCKey\fP that is part of the data structure \fCKey\fP\&. It can be looked up using a \fBmetaname\fP\&. Metanames are unique within a \fCKey\fP\&. Metakeys can also carry a value, called \fBmetavalue\fP\&. It is possible to iterate over all metakeys of a \fCKey\fP, but it is impossible for a metakey to hold other metakeys recursively\&. The purpose of metakeys next to keys is to distinguish between configuration and information about settings\&. .PP Metadata has different purposes: .PP .IP "\(bu" 2 Traditionally Elektra used metadata to carry file system semantics\&. The backend \fCfilesys\fP stores file metadata (File metadata in POSIX is returned by \fCstat()\fP) in a \fIstruct\fP with the same name\&. It contains a file type (directory, symbolic link,\&.\&.) as well as other metadata like uid, gid, owner, mode, atime, mtime and ctime\&. into the \fCKey\fP objects\&. This solution, however, only makes sense when each file shelters only one \fCKey\fP object\&. .IP "\(bu" 2 The metaname \fCbinary\fP shows if a \fCKey\fP object contains binary data\&. Otherwise it has a null-terminated C string\&. .IP "\(bu" 2 An application can set and get a flag in \fCKey\fP objects\&. .IP "\(bu" 2 Comments and owner, together with the items above, were the only metadata possible before arbitrary metadata was introduced\&. .IP "\(bu" 2 Further metadata can hold information on how to check and validate keys using types or regular expressions\&. Additional constraints concerning the validity of values can be convenient\&. Maximum length, forbidden characters and a specified range are examples of further constraints\&. .IP "\(bu" 2 They can denote when the value has changed or can be informal comments about the content or the character set being used\&. .IP "\(bu" 2 They can express the information the user has about the key, for example, comments in different languages\&. Language specific information can be supported by simply adding a unique language code to the metaname\&. .IP "\(bu" 2 They can represent information to be used by storage plugins\&. Information can be stored as syntactic, semantic or additional information rather than text in the key database\&. This could be ordering or version information\&. .IP "\(bu" 2 They can be interpreted by plugins, which is the most important purpose of metadata\&. Nearly all kinds of metadata mentioned above can belong to this category\&. .IP "\(bu" 2 Metadata is used to pass error or warning information from plugins to the application\&. The application can decide to present it to the user\&. The information is uniquely identified by numerical codes\&. Metadata can also embed descriptive text specifying a reason for the error\&. .IP "\(bu" 2 Applications can remember something about keys in metadata\&. Such metadata generalises the application-defined flag\&. .IP "\(bu" 2 A more advanced idea is to use metadata to generate forms in a programmatic way\&. While it is certainly possible to store the necessary expressive metadata, it is plenty of work to define the semantics needed to do that\&. .PP .PP .SS "Implementation" .PP In this document, we discuss the implementation of metadata\&. Metakey is implemented directly in a \fCKey\fP: Every metakey belongs to a key \fBinseparable\fP\&. Unlike normal key names there is no absolute path for it in the hierarchy, but a relative one only valid within the key\&. .PP The advantage of embedding metadata into a key is that functions can operate on a key's metadata if a key is passed as a parameter\&. Because of this, \fC\fBkeyNew()\fP\fP directly supports adding metadata\&. A key with metadata is self-contained\&. When the key is passed to a function, the metadata is always passed with it\&. Because of the tight integration into a \fCKey\fP, the metadata does not disturb the user\&. .PP A disadvantage of this approach is that storage plugins are more likely to ignore metadata because metakeys are distinct from keys and have to be handled separately\&. It is not possible to iterate over all keys and their metadata in a single loop\&. Instead only a nested loop provides full iteration over all keys and metakeys\&. .PP The metakey itself is also represented by a \fCKey\fP\&. So the data structure \fCKey\fP is nested directly into a \fCKey\fP\&. The reason for this is to make the concept easier for the user who already knows how to work with a \fCKey\fP\&. But even new users need to learn only one interface\&. During iteration the metakeys, represented through a \fCKey\fP object, contain both the metaname and the metavalue\&. The metaname is shorter than a key name because the name is unique only in the \fCKey\fP and not for the whole global configuration\&. .PP The implementation adds no significant memory overhead per \fCKey\fP if no metadata is used\&. For embedded systems it is useful to have keys without metadata\&. Special plugins can help for systems that have very limited memory capacity\&. Also for systems with enough memory we should consider that adding the first metadata to a key has some additional overhead\&. In the current implementation a new \fCKeySet\fP is allocated in this situation\&. .PP .SS "Interface" .PP The interface to access metadata consists of the following functions: .PP Interface of metadata: .PP .nf const Key *keyGetMeta(const Key *key, const char* metaName); ssize_t keySetMeta(Key *key, const char* metaName, const char *newMetaString); .fi .PP .PP Inside a \fCKey\fP, metadata with a given metaname and a metavalue can be set using \fC\fBkeySetMeta()\fP\fP and retrieved using \fC\fBkeyGetMeta()\fP\fP\&. Iteration over metadata is possible with: .PP Interface for iterating metadata: .PP .nf int keyRewindMeta(Key *key); const Key *keyNextMeta(Key *key); const Key *keyCurrentMeta(const Key *key); .fi .PP .PP Rewinding and forwarding to the next key works as for the \fCKeySet\fP\&. Programmers used to Elektra will immediately be familiar with the interface\&. Tiny wrapper functions still support the old metadata interface\&. .PP .SS "Sharing of Metakey" .PP Usually substantial amounts of metadata are shared between keys\&. For example, many keys have the type \fCint\fP\&. To avoid the problem that every key with this metadata occupies additional space, \fC\fBkeyCopyMeta()\fP\fP was invented\&. It copies metadata from one key to another\&. Only one metakey resides in memory as long as the metadata is not changed with \fC\fBkeySetMeta()\fP\fP\&. To copy metadata, the following functions can be used: .PP .nf int keyCopyMeta(Key *dest, const Key *source, const char *metaName); int keyCopyAllMeta(Key *dest, const Key *source); .fi .PP .PP The name \fCcopy\fP is used because the information is copied from one key to another\&. It has the same meaning as in \fC\fBksCopy()\fP\fP\&. In both cases it is a flat copy\&. \fC\fBkeyCopyAllMeta()\fP\fP copies all metadata from one key to another\&. It is more efficient than a loop with the same effect\&. .PP \fC\fBkeyDup()\fP\fP copies all metadata as expected\&. Sharing metadata makes no difference from the user's point of view\&. Whenever a metavalue is changed a new metakey is generated\&. It does not matter if the old metakey was shared or not\&. This is the reason why a const pointer is always passed back\&. The metakey must not be changed because it can be used within another key\&.