Libelektra: YAJL: Plugin speichert keinen Wert direkt unter dem Mountpoint

Erstellt am 27. Juli 2018  ·  17Kommentare  ·  Quelle: ElektraInitiative/libelektra

Schritte zum Reproduzieren des Problems

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 

erwartetes Ergebnis

Der letzte Befehl sollte den Text This May Be the Year I Disappear drucken.

Tatsächliche Ergebnis

Der letzte Befehl gibt eine leere Zeile aus.

System Information

  • Elektra Version: Meister
  • Betriebssystem: macOS 10.13.6
bug good first issue usability

Alle 17 Kommentare

Vielen Dank, dass Sie das Problem gemeldet haben!

Wie würde ein solches JSON-Dokument aussehen? Wir benötigen auch Dokumentation für die spezielle Semantik von Konfigurationsdateien, die nur den übergeordneten Schlüssel enthalten.

Wie würde ein solches JSON-Dokument aussehen?

Das Dokument würde in diesem Fall nur eine Zeichenfolge enthalten:

"This May Be the Year I Disappear"

. Das Plugin liest bereits den richtigen Wert, wenn ich die Konfigurationsdatei durch den obigen Inhalt ersetze:

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

.

Muss also nur das Set repariert werden? Das klingt ganz einfach!

Muss also nur das Set repariert werden?

Soweit ich das beurteilen kann, ja.

Ich denke, ich kann dies als meine erste Ausgabe betrachten. Können Sie mir ein paar Hinweise geben, wo ich anfangen soll, @ markus2330 zu suchen? Vielen Dank.

Die Quelle befindet sich in src / plugins / yajl / yajl_gen.c und src / plugins / yajl / yajl_parse.c

Glücklicherweise hat @sanssecours ein hervorragendes Tutorial geschrieben, das beschreibt, wie sich die Speicher-Plugins verhalten sollen (siehe doc / tutorials / storage-plugins.md). Sie könnten also als nächste Ausgabe # 2132 (# 2477 ist möglicherweise ein Ergebnis davon) und andere Probleme im Zusammenhang mit Yajl nehmen. Ihre Hauptarbeit könnte die Validierung von Arrays im yajl-Plugin oder - noch besser - als externes Plugin sein (siehe # 1862).

Wenn ich ein leeres JSON-Dokument einbinde (dh es enthält nur {} ), geschieht Folgendes, wenn ich kdb set system/lvas/cm/yajl "test" .
elektraYajlSet wird mit einem KeySet aufgerufen, dessen Werte nur (system/lvas/cm/yajl,test) sind.

Beim Aufruf von elektraGenEmpty die zweite Klausel ausgeführt, da die KeySets-Größe 1 beträgt.
Der strcmp ist auch erfolgreich, weil der parentKey denselben Wert wie der letzte Schlüssel im Keyset hat.

Eine leere Karte wird generiert und elektraYajlSet wird beendet. Die Funktion empfängt also den Wert, macht aber nichts damit.

An dem Punkt, an dem die leere Map generiert wird, könnte ich Code hinzufügen, der den Schlüsselwert in ein JSON-Dokument ausgibt, wie hier von @sanssecours beschrieben.
Dies würde funktionieren, da kdb get diesen Wert korrekt liest und ein Aufruf wie kdb set system/lvas/cm/yajl/second "hi" ein JSON-Dokument wie dieses {"__dirdata": "test", "second": "hi"} , das die Schlüssel wie erwartet zuordnet.

Ich denke, diese Lösung würde funktionieren, aber ich würde es sauberer finden, wenn ich das json-Dokument direkt auf {"__dirdata": "test"} , was semantisch dasselbe wäre.

Aber ich bin mir nicht sicher, wie ich das machen würde. Ich gehe davon aus, dass der richtige Weg darin besteht, dass das Verzeichniswert-Plugin das Keyset ändert, das elektraYajlSet empfängt. Oder ich denke, ich könnte das KeySet selbst in elektraYajlSet ändern.

Haben Sie einen Vorschlag @ markus2330?

Ja, der Verzeichniswert ändert das empfangene KeySet elektraYajlSet. Dies ist jedoch nicht der Fall, wenn nur der parentKey vorhanden ist (da er dann nicht als "Verzeichnis" betrachtet wird). Wenn Sie also, wie Sie bereits herausgefunden haben, nur den übergeordneten Schlüssel festlegen, wird elektraGenEmpty ausgeführt und strcmp gelingt es.

Aber elektraGenEmpty hat einige Annahmen, die jetzt nicht mehr zutreffen (es wurde geschrieben, bevor es einen Verzeichniswert gab). Es gibt also andere Fehler, z. B. # 2132

Ich denke, diese Lösung würde funktionieren, aber ich würde sie sauberer finden, wenn ich das json-Dokument direkt auf {"__dirdata": "test"} setzen könnte, was semantisch dasselbe wäre.

Wäre {"": "test"} nicht das minimale Dokument, das einen einzelnen Wert beschreibt? Dies scheint auch das Verhalten des "Kamel" -Plugins zu sein.

@sanssecours Können Sie das Speicher-Tutorial vielleicht erweitern, um auch parentKeys und "leere Schlüssel" (%) (oder zumindest vorerst als TODO) zu beschreiben?

Können Sie das Speicher-Tutorial vielleicht erweitern, um auch parentKeys zu beschreiben?

Ich denke, das Plugin-Tutorial beschreibt bereits

  • den Wert der übergeordneten Schlüssel (Dateipfad) und
  • Diese übergeordneten Schlüssel werden verwendet, um Fehler- und Warninformationen auszugeben

. Ich weiß nichts Besonderes über Elternschlüssel.

und "leere Schlüssel" (%) (oder zumindest als TODO für jetzt)?

Da ich zum ersten Mal von leeren Schlüsseln gehört habe, glaube ich nicht, dass ich die richtige Person dafür bin.

Ich könnte Code hinzufügen, der den Schlüsselwert in ein JSON-Dokument ausgibt, wie hier von @sanssecours beschrieben.

Ich bin nicht sicher, ob dies für YAJL die richtige Methode ist, um das Problem zu lösen, da für ein gültiges JSON-Dokument immer ein Array oder Objekt auf der obersten Ebene erforderlich zu sein scheint.

Ich weiß nichts Besonderes über Elternschlüssel.

Es gibt auch nichts Besonderes, außer dass einige Konfigurationsdateiformate keine Möglichkeit haben, einen Wert ohne Schlüssel einfach zu beschreiben.

"leere Schlüssel" (%)

Mit leeren Schlüsseln können Sie Dokumente wie {"root": {"": "something"}} . Wie ordnet man dies aktuell einem KeySet zu?

Ich bin nicht sicher, ob dies für YAJL die richtige Methode ist, um das Problem zu lösen, da für ein gültiges JSON-Dokument immer ein Array oder Objekt auf der obersten Ebene erforderlich zu sein scheint.

Dies scheint sich geändert zu haben: https://stackoverflow.com/questions/13318420/is-a-single-string-value-considered-valid-json

In https://www.ietf.org/rfc/rfc7159.txt gibt es sogar Beispiele, die zeigen, dass "nur Werte" zulässig sind. Aber es scheint, dass yajl dies nicht unterstützt ... (yajl 2.1.0-2 + ​​b3 ergibt den Fehler Expected “{” but found “"” )

Mit der Funktion von RFC 7159 konnten wir Folgendes abbilden:

"some value" -> parent = "irgendein Wert"
{"", "some value"} -> parent /% = "irgendein Wert"

Aber dann müssten wir yajl umgehen ... (das ChangeLog zeigt auch nicht an, dass diese Funktion später hinzugefügt wurde).

Mit leeren Schlüsseln können Sie Dokumente wie {"root": {"": "etwas"}} zuordnen. Wie ordnet man dies aktuell einem KeySet zu?

Scheint, als würde YAML CPP diese Daten richtig verarbeiten:

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

. Ich habe das Plugin setBaseName in einem Speicher-Plugin mit dem richtigen Zeichenfolgenwert ( "" ) sollte ausreichen, um diese Funktion zu unterstützen.

Schön zu sehen, dass dies ohne besondere Handhabung sofort funktioniert: +1:

@sanssecours Wollen wir jetzt RFC 7159 unterstützen? Was machen Ihre Plugins, wenn nur der parentKey gesetzt ist?

Wollen wir jetzt RFC 7159 unterstützen?

Meiner Meinung nach ist es sinnvoll, jeden Datentyp auf oberster Ebene zu unterstützen.

Was machen Ihre Plugins, wenn nur der parentKey gesetzt ist?

Sie speichern nur den Text (ohne Schlüssel):

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

.

Ich habe in diesem Commit eine spezielle Behandlung für die oberste Ebene hinzugefügt.
Das bricht einen Test im yajl-Modul ab, aber bevor ich Zeit damit verbringe, zu reparieren, dass ich zuerst einchecken wollte, ob das eine akzeptable Lösung wäre @ markus2330?

Nur um ein wenig näher darauf einzugehen: Wenn die Größe des KeySet 1 ist, kann ich sicher sein, dass nur der Schlüssel der obersten Ebene darin enthalten ist. Dann generiere ich den Wert dieses Schlüssels. In diesem Fall muss ich jedoch verhindern, dass elektraGenOpenValue aufgerufen wird, da sonst der Schlüssel als Zeichenfolge generiert wird.

Scheint, als würde YAML CPP diese Daten richtig verarbeiten:
...

Dieses Beispiel funktioniert bei mir mit yajl. Vermisse ich etwas

Das bricht einen Test im Yajl-Modul

Welcher Test? (siehe auch unten)

Ich wollte zuerst einchecken, ob das eine akzeptable Lösung wäre

Es ist einfacher zu erkennen, ob etwas eine akzeptable Lösung ist, wenn:

  • Sie haben eine PR erstellt (die dann alle Testfälle ausführt).
  • Beschreiben Sie in einem Test und anhand von Beispielen, welches Verhalten Sie jetzt implementieren möchten

Dieses Beispiel funktioniert bei mir mit yajl. Vermisse ich etwas

Nein, dieses Beispiel zeigt nur, dass {"", "some value"} kein idealer Weg ist, um den Wert des parentKey darzustellen.

Wollen wir jetzt RFC 7159 unterstützen?
Meiner Meinung nach ist es sinnvoll, jeden Datentyp auf oberster Ebene zu unterstützen.

Ich stimme vollkommen zu.

Sie speichern nur den Text (ohne Schlüssel):

Lassen Sie uns dasselbe mit yajl implementieren.

Es funktioniert jetzt perfekt für mich!

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

markus2330 picture markus2330  ·  4Kommentare

markus2330 picture markus2330  ·  3Kommentare

markus2330 picture markus2330  ·  4Kommentare

mpranj picture mpranj  ·  3Kommentare

dominicjaeger picture dominicjaeger  ·  3Kommentare