$darkmode
Elektra 0.11.0
Plugin: type

This plugin is a type checker plugin using the CORBA data types.

A common and successful type system happens to be CORBA. The system is well suited because of the many well-defined mappings it provides to other programming languages.

The type checker plugin supports these types: short, unsigned_short, long, unsigned_long, long_long, unsigned_long_long, float, double, char, wchar, boolean, any, enum, string, wstring and octet.

Enums

If a key is set to the type enum the plugin will look for the metadata array check/enum/#.

For example:

1 check/enum = #3
2 check/enum/#0 = small
3 check/enum/#1 = middle
4 check/enum/#2 = large
5 check/enum/#3 = huge

Only the values listed in this array will be accepted. The array indices don't have to be continuous, using e.g. only #1, #2 and #4 is also allowed. Just make sure check/enum is set to the largest index in the array.

Furthermore check/enum/delimiter may contain a separator character, that separates multiple allowed occurrences. If check/enum/delimiter contain more than a single character validation will fail.

For example:

1 check/enum/delimiter = _

Then the value middle_small would validate. middle_small_small would be allowed as well, because multi-values are treated like bitfields.

Normalization

Some types support normalization in addition to the standard type checking. This means that an extended set of allowed values is normalized into a different (in most cases standardized) set before type checking. The normalized values will be passed on from kdbGet to the rest of Elektra and your application. During kdbSet changed values are also normalized before type checking and at the end of kdbSet, if everything was successful, the values are restored to the ones originally provided by the user (no matter if they were changed before kdbSet or already present in kdbGet).

The full normalization/restore procedure can be described by the following cases:

Note: If normalization is used, often times you will get a normalization error instead of a type checking error.

Booleans

The values that are accepted as booleans are configured during mounting:

1 sudo kdb mount typetest.dump user:/tests/type dump type booleans=#1 booleans/#0/true=a booleans/#0/false=b booleans/#1/true=t booleans/#1/false=f

The above line defines that the array of allowed boolean pairs. booleans=#1 defines the last element of the array as #1. For each element # the keys booleans/#/true and booleans/#/false define the true and false value respectively. True values are normalized to 1, false values to 0.

Even though we didn't specify them the values 1 and 0 are still accepted. The normalized values are always okay to use. If no configuration is given, the allowed values default to 1, yes, on, true, enabled and enable as true values and 0, no, off, false, disabled and disable as false values.

The accepted values can also be overridden on a per-key-basis. Simply add the metakey check/boolean/true and check/boolean/false to set the accepted true and false values. Only a single true/false value can be chosen. This is intended for use cases, where normally you prefer to use only e.g. 1, 0 and true, false, but what to override that for a key where e.g. enabled and disabled make more sense contextually (e.g. for something like /log/debug). Because of this intention restoring also works differently, when check/boolean/true and check/boolean/false are used. In this case we will always restore to the chosen override values.

Note: The values 1 and 0 are accepted, even if overrides are used. This means you can set a key with overrides to 0 (or 1) and during kdbSet it will be restored to the false (or true) override value. (This is useful for the high-level API.)

It is an error to specify only one of booleans/#/true and booleans/#/false or check/boolean/true and check/boolean/false. Boolean always come in pairs!

You can also change how values shall be restored in kdbSet:

1 sudo kdb mount typetest.dump user:/tests/type dump type booleans=#0 booleans/#0/true=true booleans/#0/false=false boolean/restoreas=#0

The config key boolean/restoreas must be a valid index of the booleans array or the special value none. If boolean/restoreas was set to an index, the chosen boolean pair will be used when values are restored in kdbSet. So in the above example the plugin accepts 1, true, 0 and false as boolean values, on kdbGet it turns true into 1 and false into 0 and on kdbSet it turns 1 into true and 0 into false.

If no booleans array was given the allowed values for boolean/restoreas are:

The special value boolean/restoreas=none completely disables the restore procedure. In other words, kdbSet will always return either 0 or 1 for boolean values. This is useful, if a storage format with built-in support for boolean values is used.

Enums

Enums also support normalization. Contrary to boolean normalization, enum normalization is always configured on a per-key-basis.

Simply set the metakey check/enum/normalize to 1 in order to normalize the string values to there indexes. Any other value is ignored.

Take for example a key with the following enum configuration:

1 check/enum = #3
2 check/enum/#0 = small
3 check/enum/#1 = medium
4 check/enum/#3 = huge

The value small will be normalized to 0, medium to 1 and huge to 3. During restore the values 0, 1 and 3 will be restored to small, medium and huge.

If you use normalization, you can pass string values or indices to kdbGet and kdbSet, but you will always get back indices from kdbGet and string values from kdbSet. (Therefore you can seamlessly use elektraGetUnsignedLongLong from high-level API for normalized enums.)

The plugin also supports normalizing enums that use check/enum/delimiter, however be careful which indexes you use in this case. The indexes of all values are simple bitwise or-ed (using |). In the above example small_medium would be normalized to 1 (0 | 1 == 1), the same value as medium. This means during restore the value emitted will be medium.

A version that would work with delimiter and normalization is:

1 check/enum = #4
2 check/enum/#0 = none
3 check/enum/#1 = small
4 check/enum/#2 = medium
5 check/enum/#4 = huge

Here small_medium is normalized to 3, which is a unique value. During restore with delimiters the values might not be restored to there original form, but may be restored to an equivalent representation. e.g. small_none may be restored to just small or small_medium may be restored to medium_small This has technical reasons and we do not guarantee any restriction on what representation is produced during restore, other than the normalized value being the same as for the user provided representation.

**_IMPORTANT:_** Do not use normalization together with enums, whose string values start with digits (e.g. check/enum/#0 = 1abc). This breaks normalization! Indices are differentiated from string value by whether they start with a digit.

Example

1 #Mount the plugin
2 sudo kdb mount typetest.dump user:/tests/type dump type
3 
4 #Store a character value
5 kdb set user:/tests/type/key a
6 
7 #Only allow character values
8 kdb meta-set user:/tests/type/key type char
9 kdb get user:/tests/type/key
10 #> a
11 
12 #If we store another character everything works fine
13 kdb set user:/tests/type/key b
14 kdb get user:/tests/type/key
15 #> b
16 
17 #If we try to store a string Elektra will not change the value
18 kdb set user:/tests/type/key 'Not a char'
19 # RET:5
20 # ERROR:C03200
21 kdb get user:/tests/type/key
22 #> b
23 
24 #Undo modifications to the database
25 kdb rm user:/tests/type/key
26 sudo kdb umount user:/tests/type

For enums:

1 # Backup-and-Restore:/tests/enum
2 
3 sudo kdb mount typeenum.ecf user:/tests/type dump type
4 
5 # valid initial value + setup valid enum list
6 kdb set user:/tests/type/value middle
7 kdb meta-set user:/tests/type/value check/enum '#2'
8 kdb meta-set user:/tests/type/value 'check/enum/#0' 'low'
9 kdb meta-set user:/tests/type/value 'check/enum/#1' 'middle'
10 kdb meta-set user:/tests/type/value 'check/enum/#2' 'high'
11 kdb meta-set user:/tests/type/value type enum
12 
13 # should succeed
14 kdb set user:/tests/type/value low
15 
16 # should fail with error C03200
17 kdb set user:/tests/type/value no
18 # RET:5
19 # ERROR:C03200

Or with multi-enums:

1 # valid initial value + setup array with valid enums
2 kdb set user:/tests/type/multivalue middle_small
3 kdb meta-set user:/tests/type/multivalue check/enum/#0 small
4 kdb meta-set user:/tests/type/multivalue check/enum/#1 middle
5 kdb meta-set user:/tests/type/multivalue check/enum/#2 large
6 kdb meta-set user:/tests/type/multivalue check/enum/#3 huge
7 kdb meta-set user:/tests/type/multivalue check/enum/delimiter _
8 kdb meta-set user:/tests/type/multivalue check/enum "#3"
9 kdb meta-set user:/tests/type/multivalue type enum
10 
11 # should succeed
12 kdb set user:/tests/type/multivalue small_middle
13 
14 # should fail with error C03200
15 kdb set user:/tests/type/multivalue all_small
16 # RET:5
17 # ERROR:C03200
18 
19 # cleanup
20 kdb rm -r user:/tests/type
21 sudo kdb umount user:/tests/type

For booleans:

1 # Mount plugin
2 sudo kdb mount config.ecf user:/tests/type dump type
3 
4 # By default the plugin uses `1` (true) and `0` (false) to represent boolean values
5 kdb set user:/tests/type/truthiness false
6 kdb meta-set user:/tests/type/truthiness type boolean
7 kdb get user:/tests/type/truthiness
8 #> 0
9 
10 # The plugin does not change ordinary values
11 kdb set user:/tests/type/key value
12 kdb get user:/tests/type/key
13 #> value
14 
15 # Undo changes
16 kdb rm -r user:/tests/type
17 sudo kdb umount user:/tests/type
1 sudo kdb mount config.ecf user:/tests/type dump type
2 kdb set user:/tests/type/truthiness 0
3 kdb meta-set user:/tests/type/truthiness type boolean
4  kdb set user:/tests/type/truthiness yes
5 # RET: 0
6  # Undo changes
7 kdb rm -r user:/tests/type
8 sudo kdb umount user:/tests/type

Limitations

Records are part of other plugins.

The CORBA type system also has its limits. The types string and enum can be unsatisfactory. While string is too general and makes no limit on how the sequence of characters is structured, the enumeration is too finite. For example, it is not possible to say that a string is not allowed to have a specific symbol in it. Combine this plugin with other type checker plugins to circumvent such limitations.