+struct mutate_row_cbdata {
+ size_t n_matches;
+ struct ovsdb_txn *txn;
+ const struct ovsdb_mutation_set *mutations;
+ struct ovsdb_error **error;
+};
+
+static bool
+mutate_row_cb(const struct ovsdb_row *row, void *mr_)
+{
+ struct mutate_row_cbdata *mr = mr_;
+
+ mr->n_matches++;
+ *mr->error = ovsdb_mutation_set_execute(ovsdb_txn_row_modify(mr->txn, row),
+ mr->mutations);
+ return *mr->error == NULL;
+}
+
+static struct ovsdb_error *
+ovsdb_execute_mutate(struct ovsdb_execution *x, struct ovsdb_parser *parser,
+ struct json *result)
+{
+ struct ovsdb_table *table;
+ const struct json *where;
+ const struct json *mutations_json;
+ struct ovsdb_condition condition = OVSDB_CONDITION_INITIALIZER;
+ struct ovsdb_mutation_set mutations = OVSDB_MUTATION_SET_INITIALIZER;
+ struct ovsdb_row *row = NULL;
+ struct mutate_row_cbdata mr;
+ struct ovsdb_error *error;
+
+ table = parse_table(x, parser, "table");
+ where = ovsdb_parser_member(parser, "where", OP_ARRAY);
+ mutations_json = ovsdb_parser_member(parser, "mutations", OP_ARRAY);
+ error = ovsdb_parser_get_error(parser);
+ if (!error) {
+ error = ovsdb_mutation_set_from_json(table->schema, mutations_json,
+ x->symtab, &mutations);
+ }
+ if (!error) {
+ error = ovsdb_condition_from_json(table->schema, where, x->symtab,
+ &condition);
+ }
+ if (!error) {
+ mr.n_matches = 0;
+ mr.txn = x->txn;
+ mr.mutations = &mutations;
+ mr.error = &error;
+ ovsdb_query(table, &condition, mutate_row_cb, &mr);
+ json_object_put(result, "count", json_integer_create(mr.n_matches));
+ }
+
+ ovsdb_row_destroy(row);
+ ovsdb_mutation_set_destroy(&mutations);
+ ovsdb_condition_destroy(&condition);
+
+ return error;
+}
+