ovsdb: Check ovsdb_mutation_set_execute() return value in transactions.
[sliver-openvswitch.git] / ovsdb / execution.c
index 0465f03..ae17607 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2010 Nicira Networks
+/* Copyright (c) 2009, 2010, 2011 Nicira Networks
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -99,10 +99,17 @@ ovsdb_execute(struct ovsdb *db, const struct json *params,
     size_t n_operations;
     size_t i;
 
-    if (params->type != JSON_ARRAY) {
-        struct ovsdb_error *error;
+    if (params->type != JSON_ARRAY
+        || !params->u.array.n
+        || params->u.array.elems[0]->type != JSON_STRING
+        || strcmp(params->u.array.elems[0]->u.string, db->schema->name)) {
+        if (params->type != JSON_ARRAY) {
+            error = ovsdb_syntax_error(params, NULL, "array expected");
+        } else {
+            error = ovsdb_syntax_error(params, NULL, "database name expected "
+                                       "as first parameter");
+        }
 
-        error = ovsdb_syntax_error(params, NULL, "array expected");
         results = ovsdb_error_to_json(error);
         ovsdb_error_destroy(error);
         return results;
@@ -117,9 +124,9 @@ ovsdb_execute(struct ovsdb *db, const struct json *params,
     results = NULL;
 
     results = json_array_create_empty();
-    n_operations = params->u.array.n;
+    n_operations = params->u.array.n - 1;
     error = NULL;
-    for (i = 0; i < n_operations; i++) {
+    for (i = 1; i <= n_operations; i++) {
         struct json *operation = params->u.array.elems[i];
         struct ovsdb_error *parse_error;
         struct ovsdb_parser parser;
@@ -128,7 +135,7 @@ ovsdb_execute(struct ovsdb *db, const struct json *params,
 
         /* Parse and execute operation. */
         ovsdb_parser_init(&parser, operation,
-                          "ovsdb operation %zu of %zu", i + 1, n_operations);
+                          "ovsdb operation %zu of %zu", i, n_operations);
         op = ovsdb_parser_member(&parser, "op", OP_ID);
         result = json_object_create();
         if (op) {
@@ -195,7 +202,7 @@ exit:
 
 struct ovsdb_error *
 ovsdb_execute_commit(struct ovsdb_execution *x, struct ovsdb_parser *parser,
-                     struct json *result UNUSED)
+                     struct json *result OVS_UNUSED)
 {
     const struct json *durable;
 
@@ -207,9 +214,9 @@ ovsdb_execute_commit(struct ovsdb_execution *x, struct ovsdb_parser *parser,
 }
 
 static struct ovsdb_error *
-ovsdb_execute_abort(struct ovsdb_execution *x UNUSED,
-                    struct ovsdb_parser *parser UNUSED,
-                    struct json *result UNUSED)
+ovsdb_execute_abort(struct ovsdb_execution *x OVS_UNUSED,
+                    struct ovsdb_parser *parser OVS_UNUSED,
+                    struct json *result OVS_UNUSED)
 {
     return ovsdb_error("aborted", "aborted by request");
 }
@@ -236,13 +243,11 @@ parse_table(struct ovsdb_execution *x,
 }
 
 static WARN_UNUSED_RESULT struct ovsdb_error *
-parse_row(struct ovsdb_parser *parser, const char *member,
-          const struct ovsdb_table *table,
+parse_row(const struct json *json, const struct ovsdb_table *table,
           struct ovsdb_symbol_table *symtab,
           struct ovsdb_row **rowp, struct ovsdb_column_set *columns)
 {
     struct ovsdb_error *error;
-    const struct json *json;
     struct ovsdb_row *row;
 
     *rowp = NULL;
@@ -250,9 +255,8 @@ parse_row(struct ovsdb_parser *parser, const char *member,
     if (!table) {
         return OVSDB_BUG("null table");
     }
-    json = ovsdb_parser_member(parser, member, OP_OBJECT);
     if (!json) {
-        return OVSDB_BUG("null row member");
+        return OVSDB_BUG("null row");
     }
 
     row = ovsdb_row_create(table);
@@ -272,31 +276,35 @@ ovsdb_execute_insert(struct ovsdb_execution *x, struct ovsdb_parser *parser,
 {
     struct ovsdb_table *table;
     struct ovsdb_row *row = NULL;
-    const struct json *uuid_name;
+    const struct json *uuid_name, *row_json;
     struct ovsdb_error *error;
     struct uuid row_uuid;
 
     table = parse_table(x, parser, "table");
     uuid_name = ovsdb_parser_member(parser, "uuid-name", OP_ID | OP_OPTIONAL);
+    row_json = ovsdb_parser_member(parser, "row", OP_OBJECT);
     error = ovsdb_parser_get_error(parser);
+    if (error) {
+        return error;
+    }
 
     if (uuid_name) {
         struct ovsdb_symbol *symbol;
 
         symbol = ovsdb_symbol_table_insert(x->symtab, json_string(uuid_name));
-        if (symbol->used) {
+        if (symbol->created) {
             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;
+        symbol->created = true;
     } else {
         uuid_generate(&row_uuid);
     }
 
     if (!error) {
-        error = parse_row(parser, "row", table, x->symtab, &row, NULL);
+        error = parse_row(row_json, table, x->symtab, &row, NULL);
     }
     if (!error) {
         /* Check constraints for columns not included in "row", in case the
@@ -405,7 +413,7 @@ ovsdb_execute_update(struct ovsdb_execution *x, struct ovsdb_parser *parser,
                      struct json *result)
 {
     struct ovsdb_table *table;
-    const struct json *where;
+    const struct json *where, *row_json;
     struct ovsdb_condition condition = OVSDB_CONDITION_INITIALIZER;
     struct ovsdb_column_set columns = OVSDB_COLUMN_SET_INITIALIZER;
     struct ovsdb_row *row = NULL;
@@ -414,9 +422,10 @@ ovsdb_execute_update(struct ovsdb_execution *x, struct ovsdb_parser *parser,
 
     table = parse_table(x, parser, "table");
     where = ovsdb_parser_member(parser, "where", OP_ARRAY);
+    row_json = ovsdb_parser_member(parser, "row", OP_OBJECT);
     error = ovsdb_parser_get_error(parser);
     if (!error) {
-        error = parse_row(parser, "row", table, x->symtab, &row, &columns);
+        error = parse_row(row_json, table, x->symtab, &row, &columns);
     }
     if (!error) {
         error = ovsdb_condition_from_json(table->schema, where, x->symtab,
@@ -442,6 +451,7 @@ struct mutate_row_cbdata {
     size_t n_matches;
     struct ovsdb_txn *txn;
     const struct ovsdb_mutation_set *mutations;
+    struct ovsdb_error **error;
 };
 
 static bool
@@ -450,10 +460,9 @@ 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;
+    *mr->error = ovsdb_mutation_set_execute(ovsdb_txn_row_modify(mr->txn, row),
+                                            mr->mutations);
+    return *mr->error == NULL;
 }
 
 struct ovsdb_error *
@@ -485,6 +494,7 @@ ovsdb_execute_mutate(struct ovsdb_execution *x, struct ovsdb_parser *parser,
         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));
     }
@@ -570,7 +580,7 @@ ovsdb_execute_wait_query_cb(const struct ovsdb_row *row, void *aux_)
 
 static struct ovsdb_error *
 ovsdb_execute_wait(struct ovsdb_execution *x, struct ovsdb_parser *parser,
-                   struct json *result UNUSED)
+                   struct json *result OVS_UNUSED)
 {
     struct ovsdb_table *table;
     const struct json *timeout, *where, *columns_json, *until, *rows;
@@ -620,7 +630,6 @@ ovsdb_execute_wait(struct ovsdb_execution *x, struct ovsdb_parser *parser,
         /* Parse "rows" into 'expected'. */
         ovsdb_row_hash_init(&expected, &columns);
         for (i = 0; i < rows->u.array.n; i++) {
-            struct ovsdb_error *error;
             struct ovsdb_row *row;
 
             row = ovsdb_row_create(table);
@@ -683,7 +692,7 @@ ovsdb_execute_wait(struct ovsdb_execution *x, struct ovsdb_parser *parser,
 
 static struct ovsdb_error *
 ovsdb_execute_comment(struct ovsdb_execution *x, struct ovsdb_parser *parser,
-                      struct json *result UNUSED)
+                      struct json *result OVS_UNUSED)
 {
     const struct json *comment;