ovsdb-idlc: Fix parsing of "ephemeral" member of "column".
[openvswitch] / ovsdb / execution.c
index 0bfe86fb31ce6a394685cab9dddf7966c086aa91..932bee2380bfe3b4853bb775bf583399f25186f3 100644 (file)
@@ -54,6 +54,7 @@ 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 *
 lookup_executor(const char *name)
@@ -71,6 +72,7 @@ lookup_executor(const char *name)
         { "wait", ovsdb_execute_wait },
         { "commit", ovsdb_execute_commit },
         { "abort", ovsdb_execute_abort },
+        { "declare", ovsdb_execute_declare },
     };
 
     size_t i;
@@ -272,9 +274,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) {
@@ -580,3 +598,29 @@ 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;
+}