mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-27 03:03:02 +02:00
libsrx: new api, srx_get_changes()
Reduces the overhead/repetition for module callbacks by combining the forces of srx_get_diff() and lydx_get_descendant() into one API. The resulting function supports both XPath and simplified paths to get the subtree of changes applicable to the callback. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -2,9 +2,11 @@
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <sysrepo/values.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "lyx.h"
|
||||
|
||||
sr_error_t srx_get_diff(sr_session_ctx_t *session, struct lyd_node **treep)
|
||||
{
|
||||
@@ -25,6 +27,104 @@ sr_error_t srx_get_diff(sr_session_ctx_t *session, struct lyd_node **treep)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Helper tokenizer to srx_get_changes() */
|
||||
static char *token(char *ptr)
|
||||
{
|
||||
char *token;
|
||||
|
||||
if (ptr && *ptr == '/')
|
||||
ptr++;
|
||||
|
||||
token = strtok(ptr, "/");
|
||||
if (token && (ptr = strchr(token, ':')))
|
||||
token = &ptr[1]; /* skip any module prefix */
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a combination of srx_get_diff() + lydx_get_descendant() that
|
||||
* gives you the subtree relevant to your change callback.
|
||||
*
|
||||
* Usage: 1) set up change callback with /module:xpath/to/array//.
|
||||
* 2) call this function with the /module:xpath/to/array XPath
|
||||
* 3) over all items in array with LYX_LIST_FOR_EACH()
|
||||
*
|
||||
* The XPath to the change callback has //. to ensure it is called for
|
||||
* *any* change below that path. Meaning: any depth and any augmented
|
||||
* model inside that scope.
|
||||
*
|
||||
* Both the srx_*() and lyx?*() family APIs are supported after calling
|
||||
* this function. Either traverse further down using XPath, or using
|
||||
* the lydx_*() APIs. The latter have all the metadata for checking if
|
||||
* a node/tree has been removed or added, which is sometimes preferable,
|
||||
* sometimes data from the subtrees is regenerated every time anyway, so
|
||||
* it depends.
|
||||
*
|
||||
* When done, call srx_free_changes(treep);
|
||||
*/
|
||||
int srx_get_changes(sr_session_ctx_t *session, const char *path, struct lyd_node **treep)
|
||||
{
|
||||
struct lyd_node *node, *tree;
|
||||
sr_change_iter_t *iter;
|
||||
char *xpath = NULL;
|
||||
char *name = NULL;
|
||||
int err;
|
||||
|
||||
err = sr_dup_changes_iter(session, "/ietf-system:system//.", &iter);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/*
|
||||
* WARNING: sr_change_iter_t is opaque, we rely on the diff
|
||||
* tree being the first member.
|
||||
*/
|
||||
tree = node = *((struct lyd_node **)iter);
|
||||
|
||||
if (path) {
|
||||
xpath = strdup(path);
|
||||
if (!xpath) {
|
||||
err = SR_ERR_NO_MEMORY;
|
||||
goto fail;
|
||||
}
|
||||
name = token(xpath);
|
||||
}
|
||||
|
||||
while (name) {
|
||||
tree = lydx_get_sibling(node, name);
|
||||
if (!tree)
|
||||
break;
|
||||
|
||||
node = lyd_child(tree);
|
||||
name = token(NULL);
|
||||
}
|
||||
|
||||
if (tree) {
|
||||
if (lyd_dup_siblings(tree, NULL, LYD_DUP_RECURSIVE, treep))
|
||||
err = SR_ERR_LY;
|
||||
} else
|
||||
err = SR_ERR_NOT_FOUND;
|
||||
|
||||
if (xpath)
|
||||
free(xpath);
|
||||
fail:
|
||||
sr_free_change_iter(iter);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free changes from srx_get_changes() or srx_get_diff().
|
||||
*/
|
||||
int srx_free_changes(struct lyd_node *tree)
|
||||
{
|
||||
if (!tree)
|
||||
return SR_ERR_INVAL_ARG;
|
||||
|
||||
lyd_free_tree(tree);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check if string at xpath (fmt) is set (non-zero length) */
|
||||
bool srx_isset(sr_session_ctx_t *session, const char *fmt, ...)
|
||||
{
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
#define SRX_GET_UINT32(s,v,fmt,...) srx_get_int(s, &v, SR_UINT32_T, fmt, ##__VA_ARGS__)
|
||||
|
||||
sr_error_t srx_get_diff(sr_session_ctx_t *session, struct lyd_node **treep);
|
||||
|
||||
int srx_get_changes(sr_session_ctx_t *session, const char *path, struct lyd_node **treep);
|
||||
int srx_free_changes(struct lyd_node *tree);
|
||||
|
||||
bool srx_isset(sr_session_ctx_t *session, const char *fmt, ...);
|
||||
|
||||
int srx_set_item(sr_session_ctx_t *, const sr_val_t *, sr_edit_options_t, const char *, ...)
|
||||
|
||||
Reference in New Issue
Block a user