[0], [stdout], [], [OVS_VSCTL_CLEANUP])
AT_CHECK([RUN_OVS_VSCTL([list b])],
[0], [], [], [OVS_VSCTL_CLEANUP])
+AT_CHECK([RUN_OVS_VSCTL([--if-exists get b x datapath_id])],
+ [0], [], [], [OVS_VSCTL_CLEANUP])
+AT_CHECK([RUN_OVS_VSCTL([--if-exists list b x])],
+ [0], [], [], [OVS_VSCTL_CLEANUP])
+AT_CHECK([RUN_OVS_VSCTL([--if-exists set controller x connection_mode=standalone])],
+ [0], [], [], [OVS_VSCTL_CLEANUP])
+AT_CHECK(
+ [RUN_OVS_VSCTL([--if-exists remove netflow x targets '"1.2.3.4:567"'])],
+ [0], [], [], [OVS_VSCTL_CLEANUP])
+AT_CHECK(
+ [RUN_OVS_VSCTL([--if-exists clear netflow x targets])],
+ [0], [], [], [OVS_VSCTL_CLEANUP])
OVS_VSCTL_CLEANUP
AT_CLEANUP
AT_CHECK([RUN_OVS_VSCTL([list b x])],
[1], [], [ovs-vsctl: no row "x" in table Bridge
], [OVS_VSCTL_CLEANUP])
+AT_CHECK([RUN_OVS_VSCTL([get b x datapath_id])],
+ [1], [], [ovs-vsctl: no row "x" in table Bridge
+], [OVS_VSCTL_CLEANUP])
AT_CHECK([RUN_OVS_VSCTL([get b br0 d])],
[1], [], [ovs-vsctl: Bridge contains more than one column whose name matches "d"
], [OVS_VSCTL_CLEANUP])
AT_CHECK([RUN_OVS_VSCTL([set b br0 'datapath_id:y>=z'])],
[1], [], [ovs-vsctl: datapath_id:y>=z: argument does not end in "=" followed by a value.
], [OVS_VSCTL_CLEANUP])
+AT_CHECK([RUN_OVS_VSCTL([set controller x connection_mode=standalone])],
+ [1], [], [ovs-vsctl: no row "x" in table Controller
+], [OVS_VSCTL_CLEANUP])
AT_CHECK([RUN_OVS_VSCTL([wait-until b br0 datapath_id:y,z])],
[1], [], [ovs-vsctl: datapath_id:y,z: argument does not end in "=", "!=", "<", ">", "<=", ">=", "{=}", "{!=}", "{<}", "{>}", "{<=}", or "{>=}" followed by a value.
], [OVS_VSCTL_CLEANUP])
AT_CHECK([RUN_OVS_VSCTL([remove netflow `cat netflow-uuid` targets '"1.2.3.4:567"'])],
[1], [], [ovs-vsctl: "remove" operation would put 0 values in column targets of table NetFlow but the minimum number is 1
], [OVS_VSCTL_CLEANUP])
+AT_CHECK([RUN_OVS_VSCTL([remove netflow x targets '"1.2.3.4:567"'])],
+ [1], [], [ovs-vsctl: no row "x" in table NetFlow
+], [OVS_VSCTL_CLEANUP])
+AT_CHECK([RUN_OVS_VSCTL([clear netflow x targets])],
+ [1], [], [ovs-vsctl: no row "x" in table NetFlow
+], [OVS_VSCTL_CLEANUP])
AT_CHECK([RUN_OVS_VSCTL([clear netflow `cat netflow-uuid` targets])],
[1], [], [ovs-vsctl: "clear" operation cannot be applied to column targets of table NetFlow, which is not allowed to be empty
], [OVS_VSCTL_CLEANUP])
other-config=1=y\fR, which may not have the desired effect).
.
.ST "Database Command Syntax"
-.IP "[\fB\-\-columns=\fIcolumn\fR[\fB,\fIcolumn\fR]...] \fBlist \fItable \fR[\fIrecord\fR]..."
+.
+.IP "[\fB\-\-if\-exists\fR] [\fB\-\-columns=\fIcolumn\fR[\fB,\fIcolumn\fR]...] \fBlist \fItable \fR[\fIrecord\fR]..."
Lists the data in each specified \fIrecord\fR. If no
records are specified, lists all the records in \fItable\fR.
.IP
If \fB\-\-columns\fR is specified, only the requested columns are
listed, in the specified order. Otherwise, all columns are listed, in
alphabetical order by column name.
+.IP
+Without \fB\-\-if-exists\fR, it is an error if any specified
+\fIrecord\fR does not exist. With \fB\-\-if-exists\fR, the command
+ignores any \fIrecord\fR that does not exist, without producing any
+output.
.
.IP "[\fB\-\-columns=\fIcolumn\fR[\fB,\fIcolumn\fR]...] \fBfind \fItable \fR[\fIcolumn\fR[\fB:\fIkey\fR]\fB=\fIvalue\fR]..."
Lists the data in each record in \fItable\fR whose \fIcolumn\fR equals
The UUIDs shown for rows created in the same \fBovs\-vsctl\fR
invocation will be wrong.
.
-.IP "[\fB\-\-id=@\fIname\fR] [\fB\-\-if\-exists\fR] \fBget \fItable record \fR[\fIcolumn\fR[\fB:\fIkey\fR]]..."
+.IP "[\fB\-\-if\-exists\fR] [\fB\-\-id=@\fIname\fR] \fBget \fItable record \fR[\fIcolumn\fR[\fB:\fIkey\fR]]..."
Prints the value of each specified \fIcolumn\fR in the given
\fIrecord\fR in \fItable\fR. For map columns, a \fIkey\fR may
optionally be specified, in which case the value associated with
\fIkey\fR in the column is printed, instead of the entire map.
.IP
-For a map column, without \fB\-\-if\-exists\fR it is an error if
-\fIkey\fR does not exist; with it, a blank line is printed. If
-\fIcolumn\fR is not a map column or if \fIkey\fR is not specified,
-\fB\-\-if\-exists\fR has no effect.
+Without \fB\-\-if\-exists\fR, it is an error if \fIrecord\fR does not
+exist or \fIkey\fR is specified, if \fIkey\fR does not exist in
+\fIrecord\fR. With \fB\-\-if\-exists\fR, a missing \fIrecord\fR
+yields no output and a missing \fIkey\fR prints a blank line.
.IP
If \fB@\fIname\fR is specified, then the UUID for \fIrecord\fR may be
referred to by that name later in the same \fBovs\-vsctl\fR
usually at least one or the other should be specified. If both are
omitted, then \fBget\fR has no effect except to verify that
\fIrecord\fR exists in \fItable\fR.
+.IP
+\fB\-\-id\fR and \fB\-\-if\-exists\fR cannot be used together.
.
-.IP "\fBset \fItable record column\fR[\fB:\fIkey\fR]\fB=\fIvalue\fR..."
+.IP "[\fB\-\-if\-exists\fR] \fBset \fItable record column\fR[\fB:\fIkey\fR]\fB=\fIvalue\fR..."
Sets the value of each specified \fIcolumn\fR in the given
\fIrecord\fR in \fItable\fR to \fIvalue\fR. For map columns, a
\fIkey\fR may optionally be specified, in which case the value
associated with \fIkey\fR in that column is changed (or added, if none
exists), instead of the entire map.
+.IP
+Without \fB\-\-if-exists\fR, it is an error if \fIrecord\fR does not
+exist. With \fB\-\-if-exists\fR, this command does nothing if
+\fIrecord\fR does not exist.
.
-.IP "\fBadd \fItable record column \fR[\fIkey\fB=\fR]\fIvalue\fR..."
+.IP "[\fB\-\-if\-exists\fR] \fBadd \fItable record column \fR[\fIkey\fB=\fR]\fIvalue\fR..."
Adds the specified value or key-value pair to \fIcolumn\fR in
\fIrecord\fR in \fItable\fR. If \fIcolumn\fR is a map, then \fIkey\fR
is required, otherwise it is prohibited. If \fIkey\fR already exists
in a map column, then the current \fIvalue\fR is not replaced (use the
\fBset\fR command to replace an existing value).
+.IP
+Without \fB\-\-if-exists\fR, it is an error if \fIrecord\fR does not
+exist. With \fB\-\-if-exists\fR, this command does nothing if
+\fIrecord\fR does not exist.
.
-.IP "\fBremove \fItable record column \fR\fIvalue\fR..."
-.IQ "\fBremove \fItable record column \fR\fIkey\fR..."
-.IQ "\fBremove \fItable record column \fR\fIkey\fB=\fR\fIvalue\fR..."
+.IP "[\fB\-\-if\-exists\fR] \fBremove \fItable record column \fR\fIvalue\fR..."
+.IQ "[\fB\-\-if\-exists\fR] \fBremove \fItable record column \fR\fIkey\fR..."
+.IQ "[\fB\-\-if\-exists\fR] \fBremove \fItable record column \fR\fIkey\fB=\fR\fIvalue\fR..."
Removes the specified values or key-value pairs from \fIcolumn\fR in
\fIrecord\fR in \fItable\fR. The first form applies to columns that
are not maps: each specified \fIvalue\fR is removed from the column.
.IP
It is not an error if the column does not contain the specified key or
value or pair.
+.IP
+Without \fB\-\-if-exists\fR, it is an error if \fIrecord\fR does not
+exist. With \fB\-\-if-exists\fR, this command does nothing if
+\fIrecord\fR does not exist.
.
-.IP "\fBclear\fR \fItable record column\fR..."
+.IP "[\fB\-\-if\-exists\fR] \fBclear\fR \fItable record column\fR..."
Sets each \fIcolumn\fR in \fIrecord\fR in \fItable\fR to the empty set
or empty map, as appropriate. This command applies only to columns
that are allowed to be empty.
+.IP
+Without \fB\-\-if-exists\fR, it is an error if \fIrecord\fR does not
+exist. With \fB\-\-if-exists\fR, this command does nothing if
+\fIrecord\fR does not exist.
.
.IP "[\fB\-\-id=@\fIname\fR] \fBcreate\fR \fItable column\fR[\fB:\fIkey\fR]\fB=\fIvalue\fR..."
Creates a new record in \fItable\fR and sets the initial values of
/*
- * Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
+ * 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.
static const struct ovsdb_idl_row *
get_row (struct vsctl_context *ctx,
- const struct vsctl_table_class *table, const char *record_id)
+ const struct vsctl_table_class *table, const char *record_id,
+ bool must_exist)
{
const struct ovsdb_idl_row *row;
struct uuid uuid;
}
}
}
- return row;
-}
-
-static const struct ovsdb_idl_row *
-must_get_row(struct vsctl_context *ctx,
- const struct vsctl_table_class *table, const char *record_id)
-{
- const struct ovsdb_idl_row *row = get_row(ctx, table, record_id);
- if (!row) {
+ if (must_exist && !row) {
vsctl_fatal("no row \"%s\" in table %s",
record_id, table->class->name);
}
cmd_get(struct vsctl_context *ctx)
{
const char *id = shash_find_data(&ctx->options, "--id");
- bool if_exists = shash_find(&ctx->options, "--if-exists");
+ bool must_exist = !shash_find(&ctx->options, "--if-exists");
const char *table_name = ctx->argv[1];
const char *record_id = ctx->argv[2];
const struct vsctl_table_class *table;
struct ds *out = &ctx->output;
int i;
+ if (id && !must_exist) {
+ vsctl_fatal("--if-exists and --id may not be specified together");
+ }
+
table = get_table(table_name);
- row = must_get_row(ctx, table, record_id);
+ row = get_row(ctx, table, record_id, must_exist);
+ if (!row) {
+ return;
+ }
+
if (id) {
struct ovsdb_symbol *symbol;
bool new;
idx = ovsdb_datum_find_key(datum, &key,
column->type.key.type);
if (idx == UINT_MAX) {
- if (!if_exists) {
+ if (must_exist) {
vsctl_fatal("no key \"%s\" in %s record \"%s\" column %s",
key_string, table->class->name, record_id,
column->name);
{
size_t i;
+ if (!row) {
+ return;
+ }
+
table_add_row(out);
for (i = 0; i < n_columns; i++) {
const struct ovsdb_idl_column *column = columns[i];
cmd_list(struct vsctl_context *ctx)
{
const char *column_names = shash_find_data(&ctx->options, "--columns");
+ bool must_exist = !shash_find(&ctx->options, "--if-exists");
const struct ovsdb_idl_column **columns;
const char *table_name = ctx->argv[1];
const struct vsctl_table_class *table;
out = ctx->table = list_make_table(columns, n_columns);
if (ctx->argc > 2) {
for (i = 2; i < ctx->argc; i++) {
- list_record(must_get_row(ctx, table, ctx->argv[i]),
+ list_record(get_row(ctx, table, ctx->argv[i], must_exist),
columns, n_columns, out);
}
} else {
static void
cmd_set(struct vsctl_context *ctx)
{
+ bool must_exist = !shash_find(&ctx->options, "--if-exists");
const char *table_name = ctx->argv[1];
const char *record_id = ctx->argv[2];
const struct vsctl_table_class *table;
int i;
table = get_table(table_name);
- row = must_get_row(ctx, table, record_id);
+ row = get_row(ctx, table, record_id, must_exist);
+ if (!row) {
+ return;
+ }
+
for (i = 3; i < ctx->argc; i++) {
set_column(table, row, ctx->argv[i], ctx->symtab);
}
static void
cmd_add(struct vsctl_context *ctx)
{
+ bool must_exist = !shash_find(&ctx->options, "--if-exists");
const char *table_name = ctx->argv[1];
const char *record_id = ctx->argv[2];
const char *column_name = ctx->argv[3];
int i;
table = get_table(table_name);
- row = must_get_row(ctx, table, record_id);
die_if_error(get_column(table, column_name, &column));
+ row = get_row(ctx, table, record_id, must_exist);
+ if (!row) {
+ return;
+ }
type = &column->type;
ovsdb_datum_clone(&old, ovsdb_idl_read(row, column), &column->type);
static void
cmd_remove(struct vsctl_context *ctx)
{
+ bool must_exist = !shash_find(&ctx->options, "--if-exists");
const char *table_name = ctx->argv[1];
const char *record_id = ctx->argv[2];
const char *column_name = ctx->argv[3];
int i;
table = get_table(table_name);
- row = must_get_row(ctx, table, record_id);
die_if_error(get_column(table, column_name, &column));
+ row = get_row(ctx, table, record_id, must_exist);
+ if (!row) {
+ return;
+ }
type = &column->type;
ovsdb_datum_clone(&old, ovsdb_idl_read(row, column), &column->type);
static void
cmd_clear(struct vsctl_context *ctx)
{
+ bool must_exist = !shash_find(&ctx->options, "--if-exists");
const char *table_name = ctx->argv[1];
const char *record_id = ctx->argv[2];
const struct vsctl_table_class *table;
int i;
table = get_table(table_name);
- row = must_get_row(ctx, table, record_id);
+ row = get_row(ctx, table, record_id, must_exist);
+ if (!row) {
+ return;
+ }
+
for (i = 3; i < ctx->argc; i++) {
const struct ovsdb_idl_column *column;
const struct ovsdb_type *type;
for (i = 2; i < ctx->argc; i++) {
const struct ovsdb_idl_row *row;
- row = (must_exist ? must_get_row : get_row)(ctx, table, ctx->argv[i]);
+ row = get_row(ctx, table, ctx->argv[i], must_exist);
if (row) {
ovsdb_idl_txn_delete(row);
}
table = get_table(table_name);
- row = get_row(ctx, table, record_id);
+ row = get_row(ctx, table, record_id, false);
if (!row) {
ctx->try_again = true;
return;
/* Database commands. */
{"comment", 0, INT_MAX, NULL, NULL, NULL, "", RO},
{"get", 2, INT_MAX, pre_cmd_get, cmd_get, NULL, "--if-exists,--id=", RO},
- {"list", 1, INT_MAX, pre_cmd_list, cmd_list, NULL, "--columns=", RO},
+ {"list", 1, INT_MAX, pre_cmd_list, cmd_list, NULL,
+ "--if-exists,--columns=", RO},
{"find", 1, INT_MAX, pre_cmd_find, cmd_find, NULL, "--columns=", RO},
- {"set", 3, INT_MAX, pre_cmd_set, cmd_set, NULL, "", RW},
- {"add", 4, INT_MAX, pre_cmd_add, cmd_add, NULL, "", RW},
- {"remove", 4, INT_MAX, pre_cmd_remove, cmd_remove, NULL, "", RW},
- {"clear", 3, INT_MAX, pre_cmd_clear, cmd_clear, NULL, "", RW},
+ {"set", 3, INT_MAX, pre_cmd_set, cmd_set, NULL, "--if-exists", RW},
+ {"add", 4, INT_MAX, pre_cmd_add, cmd_add, NULL, "--if-exists", RW},
+ {"remove", 4, INT_MAX, pre_cmd_remove, cmd_remove, NULL, "--if-exists",
+ RW},
+ {"clear", 3, INT_MAX, pre_cmd_clear, cmd_clear, NULL, "--if-exists", RW},
{"create", 2, INT_MAX, pre_create, cmd_create, post_create, "--id=", RW},
{"destroy", 1, INT_MAX, pre_cmd_destroy, cmd_destroy, NULL,
"--if-exists,--all", RW},