-/* Copyright (c) 2009, 2010, 2011 Nicira Networks
+/* Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <config.h>
-#include <assert.h>
#include <limits.h>
#include "column.h"
#include "ovsdb.h"
#include "query.h"
#include "row.h"
+#include "server.h"
#include "table.h"
#include "timeval.h"
#include "transaction.h"
struct ovsdb_execution {
struct ovsdb *db;
+ const struct ovsdb_session *session;
struct ovsdb_txn *txn;
struct ovsdb_symbol_table *symtab;
bool durable;
static ovsdb_operation_executor ovsdb_execute_commit;
static ovsdb_operation_executor ovsdb_execute_abort;
static ovsdb_operation_executor ovsdb_execute_comment;
+static ovsdb_operation_executor ovsdb_execute_assert;
static ovsdb_operation_executor *
lookup_executor(const char *name)
{ "commit", ovsdb_execute_commit },
{ "abort", ovsdb_execute_abort },
{ "comment", ovsdb_execute_comment },
+ { "assert", ovsdb_execute_assert },
};
size_t i;
}
struct json *
-ovsdb_execute(struct ovsdb *db, const struct json *params,
+ovsdb_execute(struct ovsdb *db, const struct ovsdb_session *session,
+ const struct json *params,
long long int elapsed_msec, long long int *timeout_msec)
{
struct ovsdb_execution x;
}
x.db = db;
+ x.session = session;
x.txn = ovsdb_txn_create(db);
x.symtab = ovsdb_symbol_table_create();
x.durable = false;
/* Parse and execute operation. */
ovsdb_parser_init(&parser, operation,
- "ovsdb operation %zu of %zu", i, n_operations);
+ "ovsdb operation %"PRIuSIZE" of %"PRIuSIZE, i, n_operations);
op = ovsdb_parser_member(&parser, "op", OP_ID);
result = json_object_create();
if (op) {
op_name);
}
} else {
- assert(ovsdb_parser_has_error(&parser));
+ ovs_assert(ovsdb_parser_has_error(&parser));
}
/* A parse error overrides any other error.
return table;
}
-static WARN_UNUSED_RESULT struct ovsdb_error *
+static OVS_WARN_UNUSED_RESULT struct ovsdb_error *
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)
if (!error) {
error = parse_row(row_json, table, x->symtab, &row, &columns);
}
+ if (!error) {
+ size_t i;
+
+ for (i = 0; i < columns.n_columns; i++) {
+ const struct ovsdb_column *column = columns.columns[i];
+
+ if (!column->mutable) {
+ error = ovsdb_syntax_error(parser->json,
+ "constraint violation",
+ "Cannot update immutable column %s "
+ "in table %s.",
+ column->name, table->schema->name);
+ break;
+ }
+ }
+ }
if (!error) {
error = ovsdb_condition_from_json(table->schema, where, x->symtab,
&condition);
} else {
timeout_msec = LLONG_MAX;
}
+ }
+ if (!error) {
if (strcmp(json_string(until), "==")
&& strcmp(json_string(until), "!=")) {
error = ovsdb_syntax_error(until, NULL,
error = ovsdb_row_from_json(row, rows->u.array.elems[i], x->symtab,
NULL);
if (error) {
+ ovsdb_row_destroy(row);
break;
}
return NULL;
}
+
+static struct ovsdb_error *
+ovsdb_execute_assert(struct ovsdb_execution *x, struct ovsdb_parser *parser,
+ struct json *result OVS_UNUSED)
+{
+ const struct json *lock_name;
+
+ lock_name = ovsdb_parser_member(parser, "lock", OP_ID);
+ if (!lock_name) {
+ return NULL;
+ }
+
+ if (x->session) {
+ const struct ovsdb_lock_waiter *waiter;
+
+ waiter = ovsdb_session_get_lock_waiter(x->session,
+ json_string(lock_name));
+ if (waiter && ovsdb_lock_waiter_is_owner(waiter)) {
+ return NULL;
+ }
+ }
+
+ return ovsdb_error("not owner", "Asserted lock %s not held.",
+ json_string(lock_name));
+}