Libelektra: YAJL: le plug-in n'enregistre pas de valeur directement sous le point de montage

Créé le 27 juil. 2018  ·  17Commentaires  ·  Source: ElektraInitiative/libelektra

Étapes pour reproduire le problème

kdb mount config.json user/tests/yajl yajl
kdb set user/tests/yajl 'This May Be the Year I Disappear'
kdb ls user/tests/yajl
#> user/tests/yajl
kdb get user/tests/yajl 

résultat attendu

La dernière commande devrait afficher le texte This May Be the Year I Disappear .

Résultat actuel

La dernière commande imprime une ligne vide.

Information système

  • Version Elektra: maître
  • Système d'exploitation: macOS 10.13.6
bug good first issue usability

Tous les 17 commentaires

Merci d'avoir signalé le problème!

À quoi ressemblerait un tel document JSON? Nous avons également besoin de documentation pour la sémantique spéciale des fichiers de configuration contenant uniquement la clé parente.

À quoi ressemblerait un tel document JSON?

Le document ne contiendrait qu'une chaîne dans ce cas:

"This May Be the Year I Disappear"

. Le plugin lit déjà la valeur correcte, si je remplace le fichier de configuration par le contenu ci-dessus:

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

.

Donc, seul le jeu doit être corrigé? Cela semble assez simple!

Donc, seul le jeu doit être corrigé?

Autant que je sache, oui.

Je pense que je peux examiner cela comme mon premier problème. Pouvez-vous me donner quelques conseils sur lesquels je devrais commencer à chercher @ markus2330? Merci.

La source se trouve dans src / plugins / yajl / yajl_gen.c et src / plugins / yajl / yajl_parse.c

Heureusement, @sanssecours a écrit un excellent tutoriel décrivant comment les plugins de stockage devraient se comporter (voir doc / tutorials / storage-plugins.md). Donc, vous pouvez prendre comme prochain numéro # 2132 (# 2477 est peut-être le résultat de cela) et d'autres problèmes liés au yajl. Votre travail principal pourrait être la validation des tableaux dans le plugin yajl ou - encore mieux - en tant que plugin externe (voir # 1862).

Si je monte un document json vide (ce qui signifie qu'il ne contient que {} ), alors ce qui suit se produit lorsque j'appelle kdb set system/lvas/cm/yajl "test" .
elektraYajlSet est appelé avec un KeySet qui a des valeurs de jus (system/lvas/cm/yajl,test) .

Dans l'appel à elektraGenEmpty la deuxième clause est exécutée, car la taille des KeySets est 1.
Le strcmp réussit également car le parentKey a la même valeur que la dernière clé du jeu de clés.

Une carte vide est générée et elektraYajlSet se termine. La fonction reçoit donc la valeur, mais ne fait rien avec elle.

Donc, à ce stade où la carte vide est générée, je pourrais ajouter du code qui génère la valeur des clés dans un document json comme décrit par @sanssecours ici .
Cela fonctionnerait, car kdb get lit correctement cette valeur et un appel comme kdb set system/lvas/cm/yajl/second "hi" produit un document json comme celui-ci {"__dirdata": "test", "second": "hi"} , qui mappe les clés comme prévu.

Je pense que cette solution fonctionnerait, mais je la trouverais plus propre si je pouvais définir le document json directement sur {"__dirdata": "test"} , ce qui serait la même sémantique.

Mais je ne sais pas comment je ferais cela. Je suppose que la manière correcte serait que le plugin directoryvalue modifie le Keyset que reçoit elektraYajlSet. Ou je suppose que je pourrais modifier le KeySet moi-même dans elektraYajlSet.

Avez-vous une suggestion @ markus2330?

Oui, la valeur de répertoire modifie le KeySet que reçoit elektraYajlSet. Cela ne se produit pas, cependant, si seule la clé parentKey est présente (car elle n'est pas considérée comme un "répertoire" alors.) Donc, si vous ne définissez que la clé parent, comme vous l'avez déjà découvert, elektraGenEmpty sera exécuté et le strcmp réussit.

Mais elektraGenEmpty a des hypothèses qui ne sont plus vraies maintenant (elles ont été écrites avant que directoryvalue n'existe). Donc d'autres bugs sont là, par exemple # 2132

Je pense que cette solution fonctionnerait, mais je la trouverais plus propre si je pouvais définir le document json directement sur {"__dirdata": "test"}, ce qui serait la même sémantique.

{"": "test"} serait-il pas le document minimal décrivant une valeur unique? Cela semble également être le comportement du plugin "camel".

@sanssecours Pouvez-vous étendre le tutoriel de stockage pour décrire également les parentKeys et les "clés vides" (%) (ou du moins comme TODO pour le moment)?

Pouvez-vous étendre le tutoriel de stockage pour décrire également parentKeys…

Je pense que le tutoriel du

  • la valeur des clés parentes (chemin du fichier), et
  • que les clés parentes sont utilisées pour émettre des informations d'erreur et d'avertissement

. Je ne connais rien de spécial à propos des clés parentales.

et "clés vides" (%) (ou du moins comme TODO pour l'instant)?

Puisque c'est la première fois que j'entends parler de clés vides, je ne pense pas être la bonne personne pour faire ça.

Je pourrais ajouter du code qui génère la valeur des clés dans un document json comme décrit par @sanssecours ici .

Je ne suis pas certain que ce soit la manière correcte pour YAJL de gérer le problème, car un document JSON valide semble toujours nécessiter un tableau ou un objet au niveau supérieur.

Je ne connais rien de spécial à propos des clés parentales.

Il n'y a rien d'autre de spécial à ce sujet si ce n'est que certains formats de fichiers de configuration n'ont pas de moyen de décrire simplement une valeur sans clé.

"clés vides" (%)

Les touches vides vous permettent de mapper des documents comme {"root": {"": "something"}} . Comment le mappez-vous actuellement à un KeySet?

Je ne suis pas certain que ce soit la manière correcte pour YAJL de gérer le problème, car un document JSON valide semble toujours nécessiter un tableau ou un objet au niveau supérieur.

Cela semble avoir changé: https://stackoverflow.com/questions/13318420/is-a-single-string-value-consemed-valid-json

Dans https://www.ietf.org/rfc/rfc7159.txt, il y a même des exemples montrant que «seules les valeurs» sont autorisées. Mais il semble que yajl ne supporte pas cela ... (yajl 2.1.0-2 + ​​b3 donne l'erreur Expected “{” but found “"” )

Avec la fonctionnalité de la RFC 7159, nous pourrions mapper:

"some value" -> parent = "une valeur"
{"", "some value"} -> parent /% = "une valeur"

Mais il faudrait alors contourner Yajl ... (le ChangeLog n'indique pas non plus que cette fonctionnalité a été ajoutée plus tard).

Les clés vides vous permettent de mapper des documents comme {"root": {"": "something"}}. Comment le mappez-vous actuellement à un KeySet?

On dirait que YAML CPP gère correctement ces données:

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

. Je n'ai cependant pas adapté le plugin pour les clés vides. L'appel de setBaseName dans un plugin de stockage, en utilisant la valeur de chaîne correcte ( "" ), devrait être suffisant pour prendre en charge cette fonctionnalité.

C'est bien de voir que cela fonctionne prêt à l'emploi sans traitement spécial: +1:

@sanssecours Voulons -nous maintenant prendre en charge la RFC 7159? Que font vos plugins si seule la clé parentKey est définie?

Voulons-nous maintenant prendre en charge la RFC 7159?

À mon avis, il est logique de soutenir chaque type de données au plus haut niveau.

Que font vos plugins si seule la clé parentKey est définie?

Ils stockent simplement le texte (sans la clé):

kdb mount config.yaml user/tests/yaml yamlcpp
kdb set user/tests/yaml value
kdb file user/tests/yaml | xargs cat
#> value

.

J'ai ajouté une gestion spéciale pour le niveau supérieur dans ce commit .
Cela rompt un test dans le module yajl, mais avant de passer du temps à réparer ce que je voulais vérifier en premier, si ce serait une solution acceptable @ markus2330?

Juste pour élaborer un peu: si la taille du KeySet est 1, alors je peux être sûr que seule la clé de niveau supérieur est dedans. Ensuite, je génère la valeur de cette clé. Mais dans ce cas, je dois empêcher elektraGenOpenValue d'être appelé, car sinon, cela générerait la clé sous forme de chaîne.

On dirait que YAML CPP gère correctement ces données:
...

Cet exemple fonctionne pour moi avec yajl. Est-ce que je manque quelque chose?

Qui rompt un test dans le module yajl

Quel test? (voir aussi ci-dessous)

Je voulais d'abord m'enregistrer, si cela pouvait être une solution acceptable

Il est plus facile de voir si quelque chose est une solution acceptable si:

  • vous avez créé un PR (qui exécutera ensuite tous les cas de test)
  • décrire dans un test et avec des exemples le comportement que vous voulez maintenant implémenter

Cet exemple fonctionne pour moi avec yajl. Est-ce que je manque quelque chose?

Non, cet exemple montre uniquement que {"", "some value"} n'est pas un moyen idéal de représenter la valeur de parentKey.

Voulons-nous maintenant prendre en charge la RFC 7159?
À mon avis, il est logique de soutenir chaque type de données au plus haut niveau.

Je suis complètement d'accord.

Ils stockent simplement le texte (sans la clé):

Alors, implémentons la même chose avec yajl.

Cela fonctionne parfaitement pour moi maintenant!

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

mpranj picture mpranj  ·  3Commentaires

sanssecours picture sanssecours  ·  3Commentaires

markus2330 picture markus2330  ·  4Commentaires

mpranj picture mpranj  ·  4Commentaires

markus2330 picture markus2330  ·  3Commentaires