Libelektra: YAJL: el complemento no ahorra valor directamente debajo del punto de montaje

Creado en 27 jul. 2018  ·  17Comentarios  ·  Fuente: ElektraInitiative/libelektra

Pasos para reproducir el problema

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 

Resultado Esperado

El último comando debería imprimir el texto This May Be the Year I Disappear .

Resultado actual

El último comando imprime una línea vacía.

Información del sistema

  • Versión de Elektra: maestro
  • SO: macOS 10.13.6
bug good first issue usability

Todos 17 comentarios

¡Gracias por informar del problema!

¿Cómo se vería un documento JSON de este tipo? También necesitamos documentación para la semántica especial de los archivos de configuración que solo contienen la clave principal.

¿Cómo se vería un documento JSON de este tipo?

El documento solo contendría una cadena en este caso:

"This May Be the Year I Disappear"

. El complemento ya lee el valor correcto, si reemplazo el archivo de configuración con el contenido anterior:

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

.

Entonces, ¿solo es necesario arreglar el conjunto? ¡Esto suena bastante fácil!

Entonces, ¿solo es necesario arreglar el conjunto?

Por lo que puedo decir, sí.

Creo que puedo considerar esto como mi primer problema. ¿Puedes darme algunos consejos sobre dónde debería empezar a buscar @ markus2330? Gracias.

La fuente está en src / plugins / yajl / yajl_gen.cy src / plugins / yajl / yajl_parse.c

Afortunadamente, @sanssecours escribió un excelente tutorial que describe cómo deberían comportarse los complementos de almacenamiento (ver doc / tutorials / storage-plugins.md). Por lo tanto, podría tomar como próximo número # 2132 (# 2477 es quizás el resultado de esto) y otros problemas relacionados con yajl. Su trabajo principal podría ser la validación de matrices en el complemento yajl o, incluso mejor, como complemento externo (consulte el n. ° 1862).

Si monto un documento json vacío (lo que significa que contiene solo {} ), ocurre lo siguiente cuando llamo a kdb set system/lvas/cm/yajl "test" .
elektraYajlSet se llama con un KeySet que tiene jus (system/lvas/cm/yajl,test) como valores.

En la llamada a elektraGenEmpty se ejecuta la segunda cláusula, ya que el tamaño de los KeySets es 1.
El strcmp también tiene éxito porque parentKey tiene el mismo valor que la última clave del conjunto de claves.

Se genera un mapa vacío y elektraYajlSet termina. Entonces la función recibe el valor, pero no hace nada con él.

Entonces, en ese punto donde se genera el mapa vacío, podría agregar código que genere el valor de las claves en un documento json como lo describe @sanssecours aquí .
Esto funcionaría, ya que kdb get lee ese valor correctamente y una llamada como kdb set system/lvas/cm/yajl/second "hi" produce un documento json como este {"__dirdata": "test", "second": "hi"} , que asigna las claves como se esperaba.

Creo que esta solución funcionaría, pero la encontraría más limpia si pudiera configurar el documento json directamente en {"__dirdata": "test"} , que sería el mismo semánticamente.

Pero no estoy seguro de cómo haría eso. Supongo que la forma correcta sería que el complemento directoryvalue modificaría el conjunto de claves que recibe elektraYajlSet. O supongo que podría modificar el KeySet yo mismo en elektraYajlSet.

¿Tienes una sugerencia @ markus2330?

Sí, el valor de directorio modifica el KeySet que recibe elektraYajlSet. Sin embargo, esto no sucede si solo está presente la clave principal (ya que no se considera un "directorio"). Por lo tanto, si solo establece la clave principal, como ya averiguó, se ejecutará elektraGenEmpty y strcmp tiene éxito.

Pero elektraGenEmpty tiene algunas suposiciones que ahora ya no son ciertas (fue escrito antes de que existiera el valor de directorio). Entonces hay otros errores, por ejemplo, # 2132

Creo que esta solución funcionaría, pero la encontraría más limpia si pudiera establecer el documento json directamente en {"__dirdata": "test"}, que sería el mismo semánticamente.

¿No sería {"": "test"} el documento mínimo que describe un valor único? Este también parece ser el comportamiento del complemento "camel".

@sanssecours ¿Puede extender el tutorial de almacenamiento para describir también parentKeys y "llaves vacías" (%) (o al menos como TODO por ahora)?

¿Puede ampliar el tutorial de almacenamiento para describir también parentKeys ...

Creo que el tutorial del

  • el valor de las claves principales (ruta de archivo), y
  • que las claves principales se utilizan para emitir información de error y advertencia

. No sé nada más que sea especial acerca de las claves principales.

y "claves vacías" (%) (o al menos como TODO por ahora)?

Dado que esta es la primera vez que escucho sobre llaves vacías, no creo que sea la persona adecuada para hacer eso.

Podría agregar código que genere el valor de las claves en un documento json como lo describe @sanssecours aquí .

No estoy seguro de que esta sea la forma correcta para que YAJL maneje el problema, ya que un documento JSON válido parece requerir siempre una matriz u objeto en el nivel superior.

No sé nada más que sea especial acerca de las claves principales.

Tampoco tiene nada de especial, excepto que algunos formatos de archivo de configuración no tienen una forma de describir simplemente un valor sin una clave.

"llaves vacías" (%)

Las claves vacías le permiten mapear documentos como {"root": {"": "something"}} . ¿Cómo se asigna esto actualmente a un KeySet?

No estoy seguro de que esta sea la forma correcta para que YAJL maneje el problema, ya que un documento JSON válido parece requerir siempre una matriz u objeto en el nivel superior.

Esto parece haber cambiado: https://stackoverflow.com/questions/13318420/is-a-single-string-value-considered-valid-json

En https://www.ietf.org/rfc/rfc7159.txt hay incluso ejemplos que muestran que se permiten "solo valores". Pero parece que yajl no admite esto ... (yajl 2.1.0-2 + ​​b3 produce el error Expected “{” but found “"” )

Con la función de RFC 7159 podríamos mapear:

"some value" -> parent = "algún valor"
{"", "some value"} -> parent /% = "algún valor"

Pero tendríamos que trabajar en torno a yajl entonces ... (el ChangeLog tampoco indica que esta función se haya agregado más tarde).

Las claves vacías le permiten mapear documentos como {"root": {"": "algo"}}. ¿Cómo se asigna esto actualmente a un KeySet?

Parece que YAML CPP maneja estos datos correctamente:

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

. Sin embargo, no adapté el complemento para claves vacías. Simplemente llamar a setBaseName en un complemento de almacenamiento, utilizando el valor de cadena correcto ( "" ), debería ser suficiente para admitir esta función.

Es bueno ver que esto funciona de inmediato sin un manejo especial: +1:

@sanssecours ¿Ahora queremos admitir RFC 7159? ¿Qué hacen sus complementos si solo se configura parentKey?

¿Deseamos ahora admitir RFC 7159?

En mi opinión, el apoyo a todos los tipos de datos en el nivel superior tiene sentido.

¿Qué hacen sus complementos si solo se configura parentKey?

Simplemente almacenan el texto (sin la clave):

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

.

Agregué un manejo especial para el nivel superior en esta confirmación .
Eso rompe una prueba en el módulo yajl, pero antes de ir y dedicar tiempo a arreglar que quería verificar primero, ¿sería una solución aceptable @ markus2330?

Solo para desarrollar un poco: si el tamaño del KeySet es 1, entonces puedo estar seguro de que solo la clave de nivel superior está en él. Luego genero el valor de esa clave. Pero en ese caso tengo que evitar que se llame a elektraGenOpenValue , porque de lo contrario generaría la clave como una cadena.

Parece que YAML CPP maneja estos datos correctamente:
...

Este ejemplo me funciona con yajl. ¿Me estoy perdiendo de algo?

Eso rompe una prueba en el módulo yajl.

Cual prueba? (ver también abajo)

Primero quería verificar si esa sería una solución aceptable.

Es más fácil ver si algo es una solución aceptable si:

  • creaste un PR (que luego ejecutará todos los casos de prueba)
  • Describe en una prueba y con ejemplos qué comportamiento quieres implementar ahora.

Este ejemplo me funciona con yajl. ¿Me estoy perdiendo de algo?

No, este ejemplo solo demuestra que {"", "some value"} no es una forma ideal de representar el valor de parentKey.

¿Deseamos ahora admitir RFC 7159?
En mi opinión, el apoyo a todos los tipos de datos en el nivel superior tiene sentido.

Estoy de acuerdo completamente.

Simplemente almacenan el texto (sin la clave):

Así que implementemos lo mismo con yajl.

¡Funciona perfectamente para mí ahora!

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

dmoisej picture dmoisej  ·  3Comentarios

markus2330 picture markus2330  ·  3Comentarios

e1528532 picture e1528532  ·  4Comentarios

mpranj picture mpranj  ·  3Comentarios

sanssecours picture sanssecours  ·  3Comentarios