Skip to content

Commit aa549f0

Browse files
committed
tree data UPDATE support applying diff subtrees instead of full diff
1 parent ca2e091 commit aa549f0

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

src/diff.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1763,7 +1763,7 @@ lyd_diff_apply_metadata(struct lyd_node *node, const struct lyd_node *diff_node)
17631763
/**
17641764
* @brief Apply diff subtree on data tree nodes, recursively.
17651765
*
1766-
* @param[in,out] first_node First sibling of the data tree.
1766+
* @param[in,out] first_node First sibling of the subtree.
17671767
* @param[in] parent_node Parent of the first sibling.
17681768
* @param[in] diff_node Current diff node.
17691769
* @param[in] diff_cb Optional diff callback.
@@ -1949,6 +1949,41 @@ lyd_diff_apply_all(struct lyd_node **data, const struct lyd_node *diff)
19491949
return lyd_diff_apply_module(data, diff, NULL, NULL, NULL);
19501950
}
19511951

1952+
LIBYANG_API_DEF LY_ERR
1953+
lyd_diff_apply_node(struct lyd_node *data_parent, struct lyd_node **data_first, const struct lyd_node *diff_node)
1954+
{
1955+
LY_ERR ret = LY_SUCCESS;
1956+
struct ly_ht *dup_inst = NULL;
1957+
1958+
LY_CHECK_ARG_RET(NULL, data_parent || data_first, diff_node, LY_EINVAL);
1959+
1960+
/* diff_node is top level node, data_parent must be NULL */
1961+
if (!diff_node->parent && data_parent) {
1962+
LOGERR(LYD_CTX(diff_node), LY_EINVAL, "data_parent must be NULL when applying top-level diff_node.");
1963+
return LY_EINVAL;
1964+
}
1965+
1966+
if (!data_first) {
1967+
data_first = lyd_node_child_p(data_parent);
1968+
}
1969+
1970+
/* diff_node is top level node, data_first must be set */
1971+
if (!diff_node->parent && !data_first) {
1972+
LOGERR(LYD_CTX(diff_node), LY_EINVAL, "data_first is not set, when working with top-level node.");
1973+
return LY_EINVAL;
1974+
}
1975+
1976+
if (diff_node->parent && data_parent && (diff_node->parent->schema != data_parent->schema)) {
1977+
LOGERR(LYD_CTX(diff_node), LY_EINVAL, "Schemas of data_parent and diff_node do not match.");
1978+
return LY_EINVAL;
1979+
}
1980+
1981+
ret = lyd_diff_apply_r(data_first, data_parent, diff_node, NULL, NULL, &dup_inst);
1982+
1983+
lyd_dup_inst_free(dup_inst);
1984+
return ret;
1985+
}
1986+
19521987
/**
19531988
* @brief Update operations on a diff node when the new operation is NONE.
19541989
*

src/tree_data.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2186,6 +2186,24 @@ LIBYANG_API_DECL LY_ERR lyd_diff_apply_module(struct lyd_node **data, const stru
21862186
*/
21872187
LIBYANG_API_DECL LY_ERR lyd_diff_apply_all(struct lyd_node **data, const struct lyd_node *diff);
21882188

2189+
/**
2190+
* @brief Apply the diff subtree on a data tree.
2191+
*
2192+
* Details are mentioned in ::lyd_diff_apply_module().
2193+
*
2194+
* @param[in,out] data_parent Parent of data to apply the diff subtree on.
2195+
* If @p diff_node is a top-level node, this parameter must be NULL.
2196+
* If @p diff_node has a parent, its schema must match this parameter schema.
2197+
* @param[in,out] data_first First sibling of the subtree.
2198+
* If @p diff_node is a top-level node, this parameter must point to the first top-level sibling.
2199+
* Optional for nested data.
2200+
* @param[in] diff_node Diff subtree to apply on data.
2201+
* @return LY_SUCCESS on success,
2202+
* @return LY_ERR on error.
2203+
*/
2204+
LIBYANG_API_DECL LY_ERR lyd_diff_apply_node(struct lyd_node *data_parent, struct lyd_node **data_first,
2205+
const struct lyd_node *diff_node);
2206+
21892207
/**
21902208
* @ingroup datatree
21912209
* @defgroup diffmergeoptions Data diff merge options.

0 commit comments

Comments
 (0)