this is a draft message, it will be updated with additional information. K.O.
Back in 2007, Stefan implemented the very useful feature, ODB links to array elements,
https://daq00.triumf.ca/elog-midas/Midas/418
This is handy for "Edit On Start", for history links, for feepics and other places.
If you have an array in ODB:
ia5 INT32 5 4 12m 0 RWD
[0] 10
[1] 11
[2] 12
[3] 13
[4] 14
a normal ODB link works as a UNIX filesystem symlink, whereas an ODB link that includes an array index refers to just one element of the link target array:
symlink_to_ia5_2 -> /test_odb/ia5[2]
INT32 1 4 12m 0 RWD 12
Because there was some confusion over how it works and how it is actually implements,
some ODB functions do not implement this feature consistently.
Here, I explain how it actually works:
0) expected syntax is: "link name" -> "/link/target/array[12345]":
- "/link/target/array" is the absolute ODB path to the link target (must start with "/", relative links are not permitted)
- array index "12345" should be an integer (converted using atoi())
- there should be nothing after final "]"
- there should be nothing between the "[" and the array index decimal numeric value
1) db_get_data():
- before calling db_get_data() we must call db_find_key()
- db_find_key() will resolve ODB links and return the final destination (or an error if dangling link or circular link or too many nested links)
- db_get_data() will return the data from this ODB key. this is the path for normal symlinks.
- if db_find_key() encounters an ODB link to an array element (target path contains "["), it returns this key (of type TID_LINK).
- db_get_data() checks the key type (normally it would be TID_INT, TID_STRING, etc). if it is TID_LINK, it means we have a link to an array index (as identified by db_find_key())
- in this case, ODB link is resolved using db_find_key(), array index is extracted from the link
- and db_get_data() returns data for the corresponding array element
If db_get_data() is called using an hKey returned by db_find_link() (instead of db_find_key())
and it happens to be an ODB link (TID_LINK), we have an inconsistent result:
- if it's a normal link, db_get_data() will return a type mismatch error
- db_get_data(TID_LINK) will return the link target string (NUL-terminated)
- if it's a link to an array element, db_get_data() will resolve it and return data from the link target array element.
- db_get_data(TID_LINK) will return a type mismatch error because it will resolve the link, then fail the type check as link target cannot be TID_LINK
2) db_get_value(), db_get_data_index()
- normal links work, resolved by db_find_key()
- links to array elements not implemented, will return a type mismatch error (i.e. TID_LINK vs user requested TID_STRING, TID_INT, etc)
3) mhttpd obsolete "jcopy"
- broken, returns malformed json (old code), returns the complete array, not just the linked array element (new code)
4) odbedit save odb.json
- broken, output file odb.json is empty (new code)
K.O. |