three-valued return values for datastore text_modify

This commit is contained in:
Olof hagsand 2019-01-02 18:20:50 +01:00
parent 32ea957a52
commit 6c48165340
4 changed files with 63 additions and 37 deletions

View file

@ -285,7 +285,7 @@ candidate_commit(clicon_handle h,
/* Optionally write (potentially modified) tree back to candidate */
if (clicon_option_bool(h, "CLICON_TRANSACTION_MOD")){
if ((ret = xmldb_put(h, candidate, OP_REPLACE, td->td_target, NULL)) < 0)
if ((ret = xmldb_put(h, candidate, OP_REPLACE, td->td_target, cbret)) < 0)
goto done;
if (ret == 0)
goto fail;

View file

@ -572,7 +572,10 @@ text_get(xmldb_handle xh,
* @param[in] x0p Parent of x0
* @param[in] x1 xml tree which modifies base
* @param[in] op OP_MERGE, OP_REPLACE, OP_REMOVE, etc
* @param[out] cbret Initialized cligen buffer. Contains return XML or "".
* @param[out] cbret Initialized cligen buffer. Contains return XML if retval is 0.
* @retval -1 Error
* @retval 0 Failed (cbret set)
* @retval 1 OK
* Assume x0 and x1 are same on entry and that y is the spec
* @see text_modify_top
*/
@ -598,6 +601,7 @@ text_modify(struct text_handle *th,
yang_stmt *yc; /* yang child */
cxobj **x0vec = NULL;
int i;
int ret;
assert(x1 && xml_type(x1) == CX_ELMNT);
assert(y0);
@ -613,7 +617,7 @@ text_modify(struct text_handle *th,
if (x0){
if (netconf_data_exists(cbret, "Data already exists; cannot create new resource") < 0)
goto done;
goto ok;
goto fail;
}
case OP_NONE: /* fall thru */
case OP_MERGE:
@ -658,7 +662,7 @@ text_modify(struct text_handle *th,
if (x0==NULL){
if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0)
goto done;
goto ok;
goto fail;
}
case OP_REMOVE: /* fall thru */
if (x0){
@ -675,7 +679,7 @@ text_modify(struct text_handle *th,
if (x0){
if (netconf_data_exists(cbret, "Data already exists; cannot create new resource") < 0)
goto done;
goto ok;
goto fail;
}
case OP_REPLACE: /* fall thru */
if (x0){
@ -738,18 +742,18 @@ text_modify(struct text_handle *th,
while ((x1c = xml_child_each(x1, x1c, CX_ELMNT)) != NULL) {
x1cname = xml_name(x1c);
yc = yang_find_datanode(y0, x1cname);
if (text_modify(th, x0vec[i++], (yang_node*)yc, x0, x1c, op, cbret) < 0)
if ((ret = text_modify(th, x0vec[i++], (yang_node*)yc, x0, x1c, op, cbret)) < 0)
goto done;
/* If xml return - ie netconf error xml tree, then stop and return OK */
if (cbuf_len(cbret))
goto ok;
if (ret == 0)
goto fail;
}
break;
case OP_DELETE:
if (x0==NULL){
if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0)
goto done;
goto ok;
goto fail;
}
case OP_REMOVE: /* fall thru */
if (x0)
@ -760,12 +764,14 @@ text_modify(struct text_handle *th,
} /* CONTAINER switch op */
} /* else Y_CONTAINER */
xml_sort(x0p, NULL);
ok:
retval = 0;
retval = 1;
done:
if (x0vec)
free(x0vec);
return retval;
fail: /* cbret set */
retval = 0;
goto done;
} /* text_modify */
/*! Modify a top-level base tree x0 with modification tree x1
@ -774,7 +780,10 @@ text_modify(struct text_handle *th,
* @param[in] x1 xml tree which modifies base
* @param[in] yspec Top-level yang spec (if y is NULL)
* @param[in] op OP_MERGE, OP_REPLACE, OP_REMOVE, etc
* @param[out] cbret Initialized cligen buffer. Contains return XML or "".
* @param[out] cbret Initialized cligen buffer. Contains return XML if retval is 0.
* @retval -1 Error
* @retval 0 Failed (cbret set)
* @retval 1 OK
* @see text_modify
*/
static int
@ -792,6 +801,7 @@ text_modify_top(struct text_handle *th,
yang_stmt *yc; /* yang child */
yang_stmt *ymod;/* yang module */
char *opstr;
int ret;
/* Assure top-levels are 'config' */
assert(x0 && strcmp(xml_name(x0),"config")==0);
@ -820,7 +830,7 @@ text_modify_top(struct text_handle *th,
case OP_DELETE:
if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0)
goto done;
goto ok;
goto fail;
break;
default:
break;
@ -849,21 +859,24 @@ text_modify_top(struct text_handle *th,
if (yc == NULL){
if (netconf_unknown_element(cbret, "application", x1cname, "Unassigned yang spec") < 0)
goto done;
goto ok;
goto fail;
}
/* See if there is a corresponding node in the base tree */
if (match_base_child(x0, x1c, &x0c, yc) < 0)
goto done;
if (text_modify(th, x0c, (yang_node*)yc, x0, x1c, op, cbret) < 0)
if ((ret = text_modify(th, x0c, (yang_node*)yc, x0, x1c, op, cbret)) < 0)
goto done;
/* If xml return - ie netconf error xml tree, then stop and return OK */
if (cbuf_len(cbret))
goto ok;
if (ret == 0)
goto fail;
}
ok:
retval = 0;
// ok:
retval = 1;
done:
return retval;
fail: /* cbret set */
retval = 0;
goto done;
} /* text_modify_top */
/*! For containers without presence and no children(except attrs), remove
@ -923,15 +936,12 @@ text_put(xmldb_handle xh,
yang_spec *yspec;
cxobj *x0 = NULL;
struct db_element *de = NULL;
int cbretlocal = 0; /* Set if cbret is NULL on entry */
int ret;
if (cbret == NULL){
if ((cbret = cbuf_new()) == NULL){
clicon_err(OE_XML, errno, "cbuf_new");
clicon_err(OE_XML, EINVAL, "cbret is NULL");
goto done;
}
cbretlocal++;
}
if ((yspec = th->th_yangspec) == NULL){
clicon_err(OE_YANG, ENOENT, "No yang spec");
goto done;
@ -991,10 +1001,10 @@ text_put(xmldb_handle xh,
* Modify base tree x with modification x1. This is where the
* new tree is made.
*/
if (text_modify_top(th, x0, x1, yspec, op, cbret) < 0)
if ((ret = text_modify_top(th, x0, x1, yspec, op, cbret)) < 0)
goto done;
/* If xml return - ie netconf error xml tree, then stop and return OK */
if (cbuf_len(cbret))
if (ret == 0)
goto fail;
/* Remove NONE nodes if all subs recursively are also NONE */
@ -1047,8 +1057,6 @@ text_put(xmldb_handle xh,
goto done;
retval = 1;
done:
if (cbretlocal && cbret)
cbuf_free(cbret);
if (f != NULL)
fclose(f);
if (dbfile)
@ -1408,6 +1416,8 @@ main(int argc,
char *yangmod; /* yang file */
yang_spec *yspec = NULL;
clicon_handle h;
cbuf *cbret = NULL;
int ret;
if ((h = clicon_handle_init()) == NULL)
goto done;
@ -1456,13 +1466,21 @@ main(int argc,
op = OP_REMOVE;
else
usage(argv[0]);
if (xmldb_put(h, db, op, NULL, xn, NULL) < 1)
if ((cbret = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
if ((ret = xmldb_put(h, db, op, NULL, xn, cbret)) < 0)
goto done;
if (ret == 0)
fprintf(stderr, "%s\n", cbuf_get(cbret));
}
else
usage(argv[0]);
printf("\n");
done:
if (cbret)
cbuf_free(cbret);
return 0;
}

View file

@ -260,6 +260,7 @@ example_reset(clicon_handle h,
int retval = -1;
cxobj *xt = NULL;
int ret;
cbuf *cbret = NULL;
if (xml_parse_string("<config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface>"
"<name>lo</name><type>ex:loopback</type>"
@ -268,15 +269,22 @@ example_reset(clicon_handle h,
/* Replace parent w first child */
if (xml_rootchild(xt, 0, &xt) < 0)
goto done;
if ((cbret = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
/* Merge user reset state */
if ((ret = xmldb_put(h, (char*)db, OP_MERGE, xt, NULL)) < 0)
if ((ret = xmldb_put(h, (char*)db, OP_MERGE, xt, cbret)) < 0)
goto done;
if (ret == 0){
clicon_err(OE_XML, 0, "Error when writing to XML database");
clicon_err(OE_XML, 0, "Error when writing to XML database: %s",
cbuf_get(cbret));
goto done;
}
retval = 0;
done:
if (cbret)
cbuf_free(cbret);
if (xt != NULL)
xml_free(xt);
return retval;

View file

@ -379,7 +379,7 @@ xmldb_get(clicon_handle h,
* @param[in] db running or candidate
* @param[in] op Top-level operation, can be superceded by other op in tree
* @param[in] xt xml-tree. Top-level symbol is dummy
* @param[out] cbret Initialized cligen buffer or NULL. On exit contains XML or "".
* @param[out] cbret Initialized cligen buffer. On exit contains XML if retval == 0
* @retval 1 OK
* @retval 0 Failed, cbret contains error xml message
* @retval -1 Error