My update of db_get_data_vec() got delayed because I had to figure out
how the links to array elements work and fix a number of places
where they are not handled correctly or consistently.
Current status after the db_get_data_vec() merge:
1) db_get_data(), db_get_data_vec(): links to array elements work
2) db_get_value(), db_get_data_index(), db_get_data_index(): not implemented, will return a type mismatch
3) mhttpd obsolete "jcopy": works correctly now (previously produced invalid json)
4) odbedit save odb.json: works correctly now (prevously produced invalid json)
I think for consistency, I should implement links to array elements in db_get_value(), db_get_value_string() and db_get_value_vec().
K.O.
> 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. |