X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ovsdb%2Fexecution.c;h=4cb8b14c4a46193bdbe9bf6195abc8e8cfba0b33;hb=77909859b05f0d2466069883306e8d75d280bbe7;hp=0bfe86fb31ce6a394685cab9dddf7966c086aa91;hpb=58fda1dab104041fc693032475ec4662c1a52849;p=openvswitch diff --git a/ovsdb/execution.c b/ovsdb/execution.c index 0bfe86fb..4cb8b14c 100644 --- a/ovsdb/execution.c +++ b/ovsdb/execution.c @@ -22,6 +22,7 @@ #include "condition.h" #include "file.h" #include "json.h" +#include "mutation.h" #include "ovsdb-data.h" #include "ovsdb-error.h" #include "ovsdb-parser.h" @@ -50,10 +51,13 @@ typedef struct ovsdb_error *ovsdb_operation_executor(struct ovsdb_execution *, static ovsdb_operation_executor ovsdb_execute_insert; static ovsdb_operation_executor ovsdb_execute_select; static ovsdb_operation_executor ovsdb_execute_update; +static ovsdb_operation_executor ovsdb_execute_mutate; static ovsdb_operation_executor ovsdb_execute_delete; static ovsdb_operation_executor ovsdb_execute_wait; static ovsdb_operation_executor ovsdb_execute_commit; static ovsdb_operation_executor ovsdb_execute_abort; +static ovsdb_operation_executor ovsdb_execute_declare; +static ovsdb_operation_executor ovsdb_execute_comment; static ovsdb_operation_executor * lookup_executor(const char *name) @@ -67,10 +71,13 @@ lookup_executor(const char *name) { "insert", ovsdb_execute_insert }, { "select", ovsdb_execute_select }, { "update", ovsdb_execute_update }, + { "mutate", ovsdb_execute_mutate }, { "delete", ovsdb_execute_delete }, { "wait", ovsdb_execute_wait }, { "commit", ovsdb_execute_commit }, { "abort", ovsdb_execute_abort }, + { "declare", ovsdb_execute_declare }, + { "comment", ovsdb_execute_comment }, }; size_t i; @@ -272,9 +279,25 @@ ovsdb_execute_insert(struct ovsdb_execution *x, struct ovsdb_parser *parser, uuid_name = ovsdb_parser_member(parser, "uuid-name", OP_ID | OP_OPTIONAL); error = ovsdb_parser_get_error(parser); - uuid_generate(&row_uuid); if (uuid_name) { - ovsdb_symbol_table_put(x->symtab, json_string(uuid_name), &row_uuid); + struct ovsdb_symbol *symbol; + + symbol = ovsdb_symbol_table_get(x->symtab, json_string(uuid_name)); + if (symbol) { + if (symbol->used) { + return ovsdb_syntax_error(uuid_name, "duplicate uuid-name", + "This \"uuid-name\" appeared on an " + "earlier \"insert\" operation."); + } + row_uuid = symbol->uuid; + symbol->used = true; + } else { + uuid_generate(&row_uuid); + ovsdb_symbol_table_put(x->symtab, json_string(uuid_name), + &row_uuid, true); + } + } else { + uuid_generate(&row_uuid); } if (!error) { @@ -396,6 +419,64 @@ ovsdb_execute_update(struct ovsdb_execution *x, struct ovsdb_parser *parser, return error; } +struct mutate_row_cbdata { + size_t n_matches; + struct ovsdb_txn *txn; + const struct ovsdb_mutation_set *mutations; +}; + +static bool +mutate_row_cb(const struct ovsdb_row *row, void *mr_) +{ + struct mutate_row_cbdata *mr = mr_; + + mr->n_matches++; + ovsdb_mutation_set_execute(ovsdb_txn_row_modify(mr->txn, row), + mr->mutations); + + return true; +} + +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; + 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; +} + struct delete_row_cbdata { size_t n_matches; const struct ovsdb_table *table; @@ -580,3 +661,44 @@ ovsdb_execute_wait(struct ovsdb_execution *x, struct ovsdb_parser *parser, return error; } + +static struct ovsdb_error * +ovsdb_execute_declare(struct ovsdb_execution *x, struct ovsdb_parser *parser, + struct json *result) +{ + const struct json *uuid_name; + struct uuid uuid; + + uuid_name = ovsdb_parser_member(parser, "uuid-name", OP_ID); + if (!uuid_name) { + return NULL; + } + + if (ovsdb_symbol_table_get(x->symtab, json_string(uuid_name))) { + return ovsdb_syntax_error(uuid_name, "duplicate uuid-name", + "This \"uuid-name\" appeared on an " + "earlier \"declare\" or \"insert\" " + "operation."); + } + + uuid_generate(&uuid); + ovsdb_symbol_table_put(x->symtab, json_string(uuid_name), &uuid, false); + json_object_put(result, "uuid", json_string_create_nocopy( + xasprintf(UUID_FMT, UUID_ARGS(&uuid)))); + return NULL; +} + +static struct ovsdb_error * +ovsdb_execute_comment(struct ovsdb_execution *x, struct ovsdb_parser *parser, + struct json *result UNUSED) +{ + const struct json *comment; + + comment = ovsdb_parser_member(parser, "comment", OP_STRING); + if (!comment) { + return NULL; + } + ovsdb_txn_add_comment(x->txn, json_string(comment)); + + return NULL; +}