New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
YAJL: Plugin Does Not Save Value Directly Below Mountpoint #2129
Comments
Thank you for reporting the problem! How would such a JSON document look like? We also need documentation for the special semantics of configuration files only containing the parent key. |
The document would only contain a string in this case: "This May Be the Year I Disappear" . The plugin already reads the correct value, if I replace the configuration file with the content above: printf '"This May Be the Year I Disappear"' > (kdb file user/tests/yajl/)
kdb get user/tests/yajl
#> This May Be the Year I Disappear . |
So only set needs to be fixed? This sounds quite easy! |
As far as I can tell, yes. |
I think I can look into this as my first issue. Can you give me a few pointers where I should start to look @markus2330? Thanks. |
The source is in src/plugins/yajl/yajl_gen.c and src/plugins/yajl/yajl_parse.c Luckily @sanssecours wrote an excellent tutorial describing how the storage plugins should behave (see doc/tutorials/storage-plugins.md). So you could take as next issue #2132 (#2477 is maybe a result of this) and other yajl related problems. Your main work could be the validation of arrays in the yajl plugin or -- even better -- as external plugin (see #1862). |
If I mount an empty json document (meaning it contains just In the call to An empty map is generated and elektraYajlSet terminates. So the function receives the value, but does not do anything with it. So at that point where the empty map is generated, I could add code that outputs the keys value into a json document as described by @sanssecours here. I think this solution would work, but I'd find it cleaner if I could set the json document directly to But I'm not sure how I would do that. I assume the correct way would be that the directoryvalue plugin would modify the Keyset which elektraYajlSet receives. Or I guess I could modify the KeySet myself in elektraYajlSet. Do you have a suggestion @markus2330? |
Yes, the directoryvalue modifies the KeySet elektraYajlSet receives. This does not happen, however, if only the parentKey is present (as it is not considered to be a "directory" then.) So if you only set the parent key, as you already found out, elektraGenEmpty will be executed and the strcmp succeeds. But elektraGenEmpty has some assumptions which are now not true anymore (it was written before directoryvalue existed). So other bugs are there, e.g. #2132
Wouldn't @sanssecours Can you maybe extend the storage-tutorial to also describe parentKeys and "empty keys" (%) (or at least as TODO for now)? |
I think the plugin tutorial already describes
. I do not know anything else that is special about parent keys.
Since this is the first time I heard about empty keys, I do not think I am the right person to do that.
I am not certain that this is the correct way for YAJL to handle the problem any more, since a valid JSON document seems to always require an array or object at the top-level. |
There is also nothing else special about it except that some configuration file formats do not have a way to simply describe a value without a key.
Empty keys allow you to map documents like
This seems to have changed: https://stackoverflow.com/questions/13318420/is-a-single-string-value-considered-valid-json In https://www.ietf.org/rfc/rfc7159.txt there are even examples showing that "only values" are allowed. But it seems like yajl does not support this... (yajl 2.1.0-2+b3 yields the error With the feature from RFC 7159 we could map:
But we would need to work around yajl then... (the ChangeLog also does not indicate that this feature was added later). |
Seems like YAML CPP handles this data properly: kdb mount config.yaml user/tests/yaml yamlcpp
printf '{"root": {"": "something"}}' > "$(kdb file user/tests/yaml)"
kdb ls user/tests/yaml
#> user/tests/yaml/root/%
kdb get user/tests/yaml/root/%
#> something . I did not adapt the plugin for empty keys though. Just calling |
Nice to see that this works out-of-the-box without special handling 👍 @sanssecours Do we now want to support RFC 7159? What do your plugins do if only the parentKey is set? |
In my opinion supporting every data type at the top-level makes sense.
They just store the text (without the key): kdb mount config.yaml user/tests/yaml yamlcpp
kdb set user/tests/yaml value
kdb file user/tests/yaml | xargs cat
#> value . |
I added special handling for the top-level in this commit. Just to elaborate a little bit: If the size of the KeySet is 1, then I can be sure that only the top-level key is in it. Then I generate the value of that key. But in that case I have to prevent
This example works for me with yajl. Am I missing something? |
Which test? (see also below)
It is easier to see if something is an acceptable solution if:
No, this example only demonstrates that |
I fully agree.
So let us implement the same with yajl. |
It works perfectly for me now! |
Steps to Reproduce the Problem
Expected Result
The last command should print the text
This May Be the Year I Disappear
.Actual Result
The last command prints an empty line.
System Information
The text was updated successfully, but these errors were encountered: