MongoDB internally defines a database as a set of collections, with each collection consisting of a set of documents, each of which is essentially a JSON object. Additional python code has been written to use MongoDB as a configuration database. These classes and routines can be imported as:
from psalg.configdb.typed_json import * import psalg.configdb.configdb as configdb
Typed JSON
JSON does not provide any type information for the values it contains. For a configuration database, this can be problematic, as some numeric values might be limited to integers or even a small set of integers. Therefore, additional information is added to the JSON configuration object to provide type information. Any field name ending in ":RO" is considered to be read-only and will not be displayed by the graphical editor. An additional key, ":types:" will be added to the top level dictionary. This key maps to a dictionary with roughly the same structure as the JSON object, except that instead of containing values, the dictionary contains type information. This information is either:
- A basic type: one of "UINT8", "UINT16", "UINT32", "UINT64", "INT8", "INT16", "INT32", "INT64", "FLOAT", "DOUBLE" or "CHARSTR".
- A string denoting an enumeration type.
- A list, the first element is either a basic or enumeration type, and the other elements are integers denoting array sizes.
The ":types:" dictionary also has an ":enum:" entry defining all of the enumeration types. The keys of the ":enum:" dictionary are the enumeration types, and the value is a dictionary mapping enumeration names to integer values.
It is also assumed that any lists in the JSON object contain objects of the same type, so the ":types:" dictionary does not contain a list at that level but the type information for every element of the list.
A few top-level keys have predefined types, reflecting their use in configuration objects. These reserved keys are:
- "detType:RO", a mandatory CHARSTR.
- "detName:RO", a mandatory CHARSTR.
- "detId:RO", a mandatory CHARSTR.
- "doc:RO", an optional CHARSTR.
- "alg:RO", an optional dictionary containing:
- "alg:RO", a mandatory CHARSTR.
- "doc:RO", an optional CHARSTR.
- "version:RO", a mandatory ["INT32", 3].
The cdict Class
In order to simplify the creation of typed JSON objects, the typed_json module defines the cdict class. The constructor for this class takes an optional argument which is either an instance of another cdict or a dictionary representing a typed JSON object that is used to initialize the new cdict. The main methods for this class are:
- setInfo(detType=None, detName=None, detId=None, doc=None)
Set the top-level reserved keys to the specified values. - setAlg(alg, version=[0,0,0], doc="")
Set the top-level reserved "alg" key to a dictionary containing the arguments. - set(name, value, type="INT32", override=False, append=False)
The "name" parameter is a "flattened" name with dot-separated fields. Each field is used as a dictionary key or list index in turn to describe a particular value in the JSON object. (As a bit of syntactic sugar, list indices may be separated from the previous field by an underscore or a dot. That is "a.6.b" or "a_6.b" are equivalent.) This routine sets the referred to value to the value parameter with the specified type. If the hierarchy already exists and has a different type, an exception is thrown unless override is True, in which case the hierarchy and type is overwritten. In the event that name refers to a list, append controls whether the list should be overwritten or appended to. - typed_json()
Return a dictionary representing a typed JSON object (with the ":types:" key, etc.). - get(name, withtype=False)
The "name" parameter is a flattened name as described for the set method. The current value of this name in the hierarchy is returned. If withtype is True, values that are basic types will return a tuple, the first element of which is a string which names the basic type and the second element is the value. - getenumdict(name, reverse=False)
If name is not a defined enumeration type, return None. Otherwise, return a dictionary with the enumeration mapping. If reverse is False, the mapping is from names to integers, and if it is True, the mapping is fromintegers to names. - define_enum(name,value)
This method defines a new enumeration type, name. value is a dictionary mapping names of the enumeration type to integer values.
The typed_json module also has a few helper functions to deal with typed JSON dictionaries.
- getType(dict, name) returns the type of the value referred to by the flattened name, throwing an error if dict does not have any such value.
- getValue(dict, name) returns the value referred to by the flattened name, throwing an error if dict does not have any such value.
- updateValue(dict, name, value) stores a new value into the typed JSON dict referred to by name. value is always a string. Numeric values are converted, and array values are space-separated. 0 is returned on success, and non-zero values indicate an error.