ovsdb: Add support for multiple databases to the protocol.
authorBen Pfaff <blp@nicira.com>
Tue, 9 Feb 2010 18:17:58 +0000 (10:17 -0800)
committerBen Pfaff <blp@nicira.com>
Tue, 9 Feb 2010 22:25:32 +0000 (14:25 -0800)
This also adds protocol compatibility to the database itself and to
ovsdb-client.  It doesn't actually add multiple database support to
ovsdb-server, since we don't really need that yet.

15 files changed:
lib/ovsdb-idl-provider.h
lib/ovsdb-idl.c
ovsdb/SPECS
ovsdb/execution.c
ovsdb/jsonrpc-server.c
ovsdb/ovsdb-client.1.in
ovsdb/ovsdb-client.c
ovsdb/ovsdb-idlc.in
tests/ovsdb-execution.at
tests/ovsdb-file.at
tests/ovsdb-idl.at
tests/ovsdb-monitor.at
tests/ovsdb-server.at
tests/ovsdb-trigger.at
vswitchd/vswitch.ovsschema

index ed3874d..c86396c 100644 (file)
@@ -60,6 +60,7 @@ struct ovsdb_idl_table {
 };
 
 struct ovsdb_idl_class {
+    const char *database;       /* <db-name> for this database. */
     const struct ovsdb_idl_table_class *tables;
     size_t n_tables;
 };
index 96b31aa..bca8224 100644 (file)
@@ -342,7 +342,9 @@ ovsdb_idl_send_monitor_request(struct ovsdb_idl *idl)
 
     json_destroy(idl->monitor_request_id);
     msg = jsonrpc_create_request(
-        "monitor", json_array_create_2(json_null_create(), monitor_requests),
+        "monitor",
+        json_array_create_3(json_string_create(idl->class->database),
+                            json_null_create(), monitor_requests),
         &idl->monitor_request_id);
     jsonrpc_session_send(idl->session, msg);
 }
@@ -1072,7 +1074,8 @@ ovsdb_idl_txn_commit(struct ovsdb_idl_txn *txn)
         return txn->status;
     }
 
-    operations = json_array_create_empty();
+    operations = json_array_create_1(
+        json_string_create(txn->idl->class->database));
 
     /* Add prerequisites and declarations of new rows. */
     HMAP_FOR_EACH (row, struct ovsdb_idl_row, txn_node, &txn->txn_rows) {
@@ -1138,7 +1141,7 @@ ovsdb_idl_txn_commit(struct ovsdb_idl_txn *txn)
 
                 insert = xmalloc(sizeof *insert);
                 insert->dummy = row->uuid;
-                insert->op_index = operations->u.array.n;
+                insert->op_index = operations->u.array.n - 1;
                 uuid_zero(&insert->real);
                 hmap_insert(&txn->inserted_rows, &insert->hmap_node,
                             uuid_hash(&insert->dummy));
@@ -1174,7 +1177,7 @@ ovsdb_idl_txn_commit(struct ovsdb_idl_txn *txn)
     if (txn->inc_table && any_updates) {
         struct json *op;
 
-        txn->inc_index = operations->u.array.n;
+        txn->inc_index = operations->u.array.n - 1;
 
         op = json_object_create();
         json_object_put_string(op, "op", "mutate");
index ff4015c..d2de137 100644 (file)
@@ -88,10 +88,11 @@ is represented by <database-schema>, as described below.
         "comment": <string>                     optional
         "tables": {<id>: <table-schema>, ...}   required
 
-    The "name" identifies the database as a whole.  The "comment"
-    optionally provides more information about the database.  The
-    value of "tables" is a JSON object whose names are table names and
-    whose values are <table-schema>s.
+    The "name" identifies the database as a whole.  It must be
+    provided to most JSON-RPC requests to identify the database being
+    operated on.  The "comment" optionally provides more information
+    about the database.  The value of "tables" is a JSON object whose
+    names are table names and whose values are <table-schema>s.
 
 <table-schema>
 
@@ -242,13 +243,32 @@ over HTTP, for these reasons:
 
 The database wire protocol consists of the following JSON-RPC methods:
 
+list_dbs
+........
+
+Request object members:
+
+    "method": "list_dbs"              required
+    "params": []                      required
+    "id": any JSON value except null  required
+
+Response object members:
+
+    "result": [<db-name>, ...]
+    "error": null
+    "id": same "id" as request
+
+This operation retrieves an array whose elements are <db-name>s
+that name the databases that can be accessed over this JSON-RPC
+connection.
+
 get_schema
 ..........
 
 Request object members:
 
     "method": "get_schema"            required
-    "params": []                      required
+    "params": [<db-name>]             required
     "id": any JSON value except null  required
 
 Response object members:
@@ -257,17 +277,17 @@ Response object members:
     "error": null
     "id": same "id" as request
 
-This operation retrieves a <database-schema> that describes the
-hosted database.
+This operation retrieves a <database-schema> that describes hosted
+database <db-name>.
 
 transact
 ........
 
 Request object members:
 
-    "method": "transact"              required
-    "params": [<operation>*]          required
-    "id": any JSON value except null  required
+    "method": "transact"                  required
+    "params": [<db-name>, <operation>*]   required
+    "id": any JSON value except null      required
 
 Response object members:
 
@@ -275,9 +295,11 @@ Response object members:
     "error": null
     "id": same "id" as request
 
-The "params" array for this method consists of zero or more JSON
-objects, each of which represents a single database operation.  The
-"Operations" section below describes the valid operations.
+The "params" array for this method consists of a <db-name> that
+identifies the database to which the transaction applies, followed by
+zero or more JSON objects, each of which represents a single database
+operation.  The "Operations" section below describes the valid
+operations.
 
 The value of "id" must be unique among all in-flight transactions
 within the current JSON-RPC session.  Otherwise, the server may return
@@ -373,9 +395,9 @@ monitor
 
 Request object members:
 
-    "method": "monitor"                        required
-    "params": [<value>, <monitor-requests>]    required
-    "id": any JSON value except null           required
+    "method": "monitor"                                   required
+    "params": [<db-name>, <value>, <monitor-requests>]    required
+    "id": any JSON value except null                      required
 
 <monitor-requests> is an object that maps from a table name to a
 <monitor-request>.
@@ -399,13 +421,13 @@ Response object members:
     "id": same "id" as request
 
 This JSON-RPC request enables a client to replicate tables or subsets
-of tables.  Each <monitor-request> specifies a table to be replicated.
-The JSON-RPC response to the "monitor" includes the initial contents
-of each table.  Afterward, when changes to those tables are committed,
-the changes are automatically sent to the client using the "update"
-monitor notification.  This monitoring persists until the JSON-RPC
-session terminates or until the client sends a "monitor_cancel"
-JSON-RPC request.
+of tables within database <db-name>.  Each <monitor-request> specifies
+a table to be replicated.  The JSON-RPC response to the "monitor"
+includes the initial contents of each table.  Afterward, when changes
+to those tables are committed, the changes are automatically sent to
+the client using the "update" monitor notification.  This monitoring
+persists until the JSON-RPC session terminates or until the client
+sends a "monitor_cancel" JSON-RPC request.
 
 Each <monitor-request> describes how to monitor a table:
 
@@ -521,6 +543,12 @@ there or vice versa.
 Notation for the Wire Protocol
 ------------------------------
 
+<db-name>
+
+    An <id> that names a database.  The valid <db-name>s can be
+    obtained using a "list-db" request.  The <db-name> is taken from
+    the "name" member of <database-schema>.
+
 <table>
 
     An <id> that names a table.
index 0465f03..3e3d356 100644 (file)
@@ -99,10 +99,19 @@ ovsdb_execute(struct ovsdb *db, const struct json *params,
     size_t n_operations;
     size_t i;
 
-    if (params->type != JSON_ARRAY) {
+    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)) {
         struct ovsdb_error *error;
 
-        error = ovsdb_syntax_error(params, NULL, "array expected");
+        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");
+        }
+
         results = ovsdb_error_to_json(error);
         ovsdb_error_destroy(error);
         return results;
@@ -117,9 +126,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;
index 936dd1d..26fabe5 100644 (file)
@@ -346,6 +346,48 @@ ovsdb_jsonrpc_session_close_all(struct ovsdb_jsonrpc_remote *remote)
     }
 }
 
+static const char *
+get_db_name(const struct ovsdb_jsonrpc_session *s)
+{
+    return s->remote->server->db->schema->name;
+}
+
+static struct jsonrpc_msg *
+ovsdb_jsonrpc_check_db_name(const struct ovsdb_jsonrpc_session *s,
+                            const struct jsonrpc_msg *request)
+{
+    struct json_array *params;
+    const char *want_db_name;
+    const char *have_db_name;
+    struct ovsdb_error *error;
+    struct jsonrpc_msg *reply;
+
+    params = json_array(request->params);
+    if (!params->n || params->elems[0]->type != JSON_STRING) {
+        error = ovsdb_syntax_error(
+            request->params, NULL,
+            "%s request params must begin with <db-name>", request->method);
+        goto error;
+    }
+
+    want_db_name = params->elems[0]->u.string;
+    have_db_name = get_db_name(s);
+    if (strcmp(want_db_name, have_db_name)) {
+        error = ovsdb_syntax_error(
+            request->params, "unknown database",
+            "%s request specifies unknown database %s",
+            request->method, want_db_name);
+        goto error;
+    }
+
+    return NULL;
+
+error:
+    reply = jsonrpc_create_reply(ovsdb_error_to_json(error), request->id);
+    ovsdb_error_destroy(error);
+    return reply;
+}
+
 static struct jsonrpc_msg *
 execute_transaction(struct ovsdb_jsonrpc_session *s,
                     struct jsonrpc_msg *request)
@@ -364,16 +406,30 @@ ovsdb_jsonrpc_session_got_request(struct ovsdb_jsonrpc_session *s,
     struct jsonrpc_msg *reply;
 
     if (!strcmp(request->method, "transact")) {
-        reply = execute_transaction(s, request);
+        reply = ovsdb_jsonrpc_check_db_name(s, request);
+        if (!reply) {
+            reply = execute_transaction(s, request);
+        }
     } else if (!strcmp(request->method, "monitor")) {
-        reply = jsonrpc_create_reply(
-            ovsdb_jsonrpc_monitor_create(s, request->params), request->id);
+        reply = ovsdb_jsonrpc_check_db_name(s, request);
+        if (!reply) {
+            reply = jsonrpc_create_reply(
+                ovsdb_jsonrpc_monitor_create(s, request->params), request->id);
+        }
     } else if (!strcmp(request->method, "monitor_cancel")) {
         reply = ovsdb_jsonrpc_monitor_cancel(s, json_array(request->params),
                                              request->id);
     } else if (!strcmp(request->method, "get_schema")) {
+        reply = ovsdb_jsonrpc_check_db_name(s, request);
+        if (!reply) {
+            reply = jsonrpc_create_reply(
+                ovsdb_schema_to_json(s->remote->server->db->schema),
+                request->id);
+        }
+    } else if (!strcmp(request->method, "list_dbs")) {
         reply = jsonrpc_create_reply(
-            ovsdb_schema_to_json(s->remote->server->db->schema), request->id);
+            json_array_create_1(json_string_create(get_db_name(s))),
+            request->id);
     } else if (!strcmp(request->method, "echo")) {
         reply = jsonrpc_create_reply(json_clone(request->params), request->id);
     } else {
@@ -589,12 +645,12 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s,
     struct shash_node *node;
     struct json *json;
 
-    if (json_array(params)->n != 2) {
+    if (json_array(params)->n != 3) {
         error = ovsdb_syntax_error(params, NULL, "invalid parameters");
         goto error;
     }
-    monitor_id = params->u.array.elems[0];
-    monitor_requests = params->u.array.elems[1];
+    monitor_id = params->u.array.elems[1];
+    monitor_requests = params->u.array.elems[2];
     if (monitor_requests->type != JSON_OBJECT) {
         error = ovsdb_syntax_error(monitor_requests, NULL,
                                    "monitor-requests must be object");
index 716fcc2..64a0811 100644 (file)
 ovsdb\-client \- command-line interface to \fBovsdb-server\fR(1)
 .
 .SH SYNOPSIS
-\fBovsdb\-client \fR[\fIoptions\fR] \fBget-schema\fI server\fR
+\fBovsdb\-client \fR[\fIoptions\fR] \fBlist\-dbs\fI server\fR
 .br
-\fBovsdb\-client \fR[\fIoptions\fR] \fBlist-tables\fI server\fR
+\fBovsdb\-client \fR[\fIoptions\fR] \fBget-schema\fI server database\fR
 .br
-\fBovsdb\-client \fR[\fIoptions\fR] \fBlist-columns\fI server \fR[\fItable\fR]
+\fBovsdb\-client \fR[\fIoptions\fR] \fBlist-tables\fI server database\fR
+.br
+\fBovsdb\-client \fR[\fIoptions\fR] \fBlist-columns\fI server database \fR[\fItable\fR]
 .br
 \fBovsdb\-client \fR[\fIoptions\fR] \fBtransact\fI server transaction\fR
 .br
-\fBovsdb\-client \fR[\fIoptions\fR] \fBmonitor\fI server table\fR
+\fBovsdb\-client \fR[\fIoptions\fR] \fBmonitor\fI server database table\fR
 [\fIcolumn\fR[\fB,\fIcolumn\fR]...]
 [\fIselect\fR[\fB,\fIselect\fR]...]
 .br
@@ -47,32 +49,37 @@ the following forms:
 .
 .SS "Commands"
 The following commands are implemented:
-.IP "\fBget-schema\fI server\fR"
-Connects to \fIserver\fR, retrieves the database schema, and prints it
-in JSON format.
+.IP "\fBlist-dbs\fI server\fR"
+Connects to \fIserver\fR, retrieves the list of known databases, and
+prints them one per line.  These database names are the ones that may
+be used for \fIdatabase\fR in the following commands.
+.
+.IP "\fBget-schema\fI server database\fR"
+Connects to \fIserver\fR, retrieves the schema for \fIdatabase\fR, and
+prints it in JSON format.
 .
-.IP "\fBlist-tables\fI server\fR"
-Connects to \fIserver\fR, retrieves the database schema, and prints
-a table listing the names and comments (if any) on each table within
-the database.
+.IP "\fBlist-tables\fI server database\fR"
+Connects to \fIserver\fR, retrieves the schema for \fIdatabase\fR, and
+prints a table listing the names and comments (if any) on each table
+within the database.
 .
-.IP "\fBlist-columns\fI server \fR[\fItable\fR]"
-Connects to \fIserver\fR, retrieves the database schema, and prints
-a table listing the names, type, and comment (if any) on each column.  If
-\fItable\fR is specified, only columns in that table are listed;
-otherwise, the tables include columns in all tables.
+.IP "\fBlist-columns\fI server database \fR[\fItable\fR]"
+Connects to \fIserver\fR, retrieves the schema for \fIdatabase\fR, and
+prints a table listing the names, type, and comment (if any) on each
+column.  If \fItable\fR is specified, only columns in that table are
+listed; otherwise, the tables include columns in all tables.
 .
 .IP "\fBtransact\fI server transaction\fR"
 Connects to \fIserver\fR, sends it the specified \fItransaction\fR,
 which must be a JSON array containing one or more valid OVSDB
 operations, and prints the received reply on stdout.
 .
-.IP "\fBmonitor\fI server table\fR [\fIcolumn\fR[\fB,\fIcolumn\fR]...] [\fIselect\fR[\fB,\fIselect\fR]...]"
-Connects to \fIserver\fR and monitors the contents of \fItable\fR.  By
-default, the initial contents of \fItable\fR are printed, followed by
-each change as it occurs.  If at least one \fIcolumn\fR is specified,
-only those columns are monitored.  If at least one \fIselect\fR is
-specified, they are interpreted as follows:
+.IP "\fBmonitor\fI server database table\fR [\fIcolumn\fR[\fB,\fIcolumn\fR]...] [\fIselect\fR[\fB,\fIselect\fR]...]"
+Connects to \fIserver\fR and monitors the contents of \fItable\fR in
+\fIdatabase\fR.  By default, the initial contents of \fItable\fR are
+printed, followed by each change as it occurs.  If at least one
+\fIcolumn\fR is specified, only those columns are monitored.  If at
+least one \fIselect\fR is specified, they are interpreted as follows:
 .RS
 .IP "\fBinitial\fR"
 Print the initial contents of the specified columns.
index a59f6de..df24e37 100644 (file)
@@ -167,17 +167,19 @@ usage(void)
     printf("%s: Open vSwitch database JSON-RPC client\n"
            "usage: %s [OPTIONS] COMMAND [ARG...]\n"
            "\nValid commands are:\n"
-           "\n  get-schema SERVER\n"
-           "    retrieve schema from SERVER\n"
-           "\n  list-tables SERVER\n"
-           "    list SERVER's tables\n"
-           "\n  list-columns SERVER [TABLE]\n"
-           "    list columns in TABLE (or all tables) on SERVER\n"
+           "\n  list-dbs SERVER\n"
+           "    list databases available on SERVER\n"
+           "\n  get-schema SERVER DATABASE\n"
+           "    retrieve schema for DATABASE from SERVER\n"
+           "\n  list-tables SERVER DATABSE\n"
+           "    list tables for DATABSAE on SERVER\n"
+           "\n  list-columns SERVER DATABASE [TABLE]\n"
+           "    list columns in TABLE (or all tables) in DATABASE on SERVER\n"
            "\n  transact SERVER TRANSACTION\n"
            "    run TRANSACTION (a JSON array of operations) on SERVER\n"
            "    and print the results as JSON on stdout\n"
-           "\n  monitor SERVER TABLE [COLUMN,...] [SELECT,...]\n"
-           "    monitor contents of (COLUMNs in) TABLE on SERVER\n"
+           "\n  monitor SERVER DATABASE TABLE [COLUMN,...] [SELECT,...]\n"
+           "    monitor contents of (COLUMNs in) TABLE in DATABASE on SERVER\n"
            "    Valid SELECTs are: initial, insert, delete, modify\n",
            program_name, program_name);
     stream_usage("SERVER", true, true, true);
@@ -258,13 +260,15 @@ check_ovsdb_error(struct ovsdb_error *error)
 }
 
 static struct ovsdb_schema *
-fetch_schema_from_rpc(struct jsonrpc *rpc)
+fetch_schema_from_rpc(struct jsonrpc *rpc, const char *database)
 {
     struct jsonrpc_msg *request, *reply;
     struct ovsdb_schema *schema;
     int error;
 
-    request = jsonrpc_create_request("get_schema", json_array_create_empty(),
+    request = jsonrpc_create_request("get_schema",
+                                     json_array_create_1(
+                                         json_string_create(database)),
                                      NULL);
     error = jsonrpc_transact_block(rpc, request, &reply);
     if (error) {
@@ -277,13 +281,13 @@ fetch_schema_from_rpc(struct jsonrpc *rpc)
 }
 
 static struct ovsdb_schema *
-fetch_schema(const char *server)
+fetch_schema(const char *server, const char *database)
 {
     struct ovsdb_schema *schema;
     struct jsonrpc *rpc;
 
     rpc = open_jsonrpc(server);
-    schema = fetch_schema_from_rpc(rpc);
+    schema = fetch_schema_from_rpc(rpc, database);
     jsonrpc_close(rpc);
 
     return schema;
@@ -571,10 +575,41 @@ table_print(const struct table *table)
     }
 }
 \f
+static void
+do_list_dbs(int argc UNUSED, char *argv[])
+{
+    struct jsonrpc_msg *request, *reply;
+    struct jsonrpc *rpc;
+    int error;
+    size_t i;
+
+    rpc = open_jsonrpc(argv[1]);
+    request = jsonrpc_create_request("list_dbs", json_array_create_empty(),
+                                     NULL);
+    error = jsonrpc_transact_block(rpc, request, &reply);
+    if (error) {
+        ovs_fatal(error, "transaction failed");
+    }
+
+    if (reply->result->type != JSON_ARRAY) {
+        ovs_fatal(0, "list_dbs response is not array");
+    }
+
+    for (i = 0; i < reply->result->u.array.n; i++) {
+        const struct json *name = reply->result->u.array.elems[i];
+
+        if (name->type != JSON_STRING) {
+            ovs_fatal(0, "list_dbs response %zu is not string", i);
+        }
+        puts(name->u.string);
+    }
+    jsonrpc_msg_destroy(reply);
+}
+
 static void
 do_get_schema(int argc UNUSED, char *argv[])
 {
-    struct ovsdb_schema *schema = fetch_schema(argv[1]);
+    struct ovsdb_schema *schema = fetch_schema(argv[1], argv[2]);
     print_and_free_json(ovsdb_schema_to_json(schema));
     ovsdb_schema_destroy(schema);
 }
@@ -586,7 +621,7 @@ do_list_tables(int argc UNUSED, char *argv[])
     struct shash_node *node;
     struct table t;
 
-    schema = fetch_schema(argv[1]);
+    schema = fetch_schema(argv[1], argv[2]);
     table_init(&t);
     table_add_column(&t, "Table");
     table_add_column(&t, "Comment");
@@ -606,12 +641,12 @@ do_list_tables(int argc UNUSED, char *argv[])
 static void
 do_list_columns(int argc UNUSED, char *argv[])
 {
-    const char *table_name = argv[2];
+    const char *table_name = argv[3];
     struct ovsdb_schema *schema;
     struct shash_node *table_node;
     struct table t;
 
-    schema = fetch_schema(argv[1]);
+    schema = fetch_schema(argv[1], argv[2]);
     table_init(&t);
     if (!table_name) {
         table_add_column(&t, "Table");
@@ -759,6 +794,9 @@ monitor_print(struct json *table_updates,
 static void
 do_monitor(int argc, char *argv[])
 {
+    const char *server = argv[1];
+    const char *database = argv[2];
+    const char *table_name = argv[3];
     struct ovsdb_column_set columns = OVSDB_COLUMN_SET_INITIALIZER;
     struct ovsdb_table_schema *table;
     struct ovsdb_schema *schema;
@@ -767,25 +805,27 @@ do_monitor(int argc, char *argv[])
     struct json *select, *monitor, *monitor_request, *monitor_requests,
         *request_id;
 
-    rpc = open_jsonrpc(argv[1]);
+    rpc = open_jsonrpc(server);
 
-    schema = fetch_schema_from_rpc(rpc);
-    table = shash_find_data(&schema->tables, argv[2]);
+    schema = fetch_schema_from_rpc(rpc, database);
+    table = shash_find_data(&schema->tables, table_name);
     if (!table) {
-        ovs_fatal(0, "%s: no table named \"%s\"", argv[1], argv[2]);
+        ovs_fatal(0, "%s: %s does not have a table named \"%s\"",
+                  server, database, table_name);
     }
 
-    if (argc >= 4 && *argv[3] != '\0') {
+    if (argc >= 5 && *argv[4] != '\0') {
         char *save_ptr = NULL;
         char *token;
 
-        for (token = strtok_r(argv[3], ",", &save_ptr); token != NULL;
+        for (token = strtok_r(argv[4], ",", &save_ptr); token != NULL;
              token = strtok_r(NULL, ",", &save_ptr)) {
             const struct ovsdb_column *column;
             column = ovsdb_table_schema_get_column(table, token);
             if (!column) {
-                ovs_fatal(0, "%s: table \"%s\" does not have a "
-                          "column named \"%s\"", argv[1], argv[2], token);
+                ovs_fatal(0, "%s: table \"%s\" in %s does not have a "
+                          "column named \"%s\"",
+                          server, table_name, database, token);
             }
             ovsdb_column_set_add(&columns, column);
         }
@@ -800,12 +840,12 @@ do_monitor(int argc, char *argv[])
         }
     }
 
-    if (argc >= 5 && *argv[4] != '\0') {
+    if (argc >= 6 && *argv[5] != '\0') {
         char *save_ptr = NULL;
         char *token;
 
         select = json_object_create();
-        for (token = strtok_r(argv[4], ",", &save_ptr); token != NULL;
+        for (token = strtok_r(argv[5], ",", &save_ptr); token != NULL;
              token = strtok_r(NULL, ",", &save_ptr)) {
             json_object_put(select, token, json_boolean_create(true));
         }
@@ -821,9 +861,10 @@ do_monitor(int argc, char *argv[])
     }
 
     monitor_requests = json_object_create();
-    json_object_put(monitor_requests, argv[2], monitor_request);
+    json_object_put(monitor_requests, table_name, monitor_request);
 
-    monitor = json_array_create_2(json_null_create(), monitor_requests);
+    monitor = json_array_create_3(json_string_create(database),
+                                  json_null_create(), monitor_requests);
     request = jsonrpc_create_request("monitor", monitor, NULL);
     request_id = json_clone(request->id);
     jsonrpc_send(rpc, request);
@@ -834,7 +875,7 @@ do_monitor(int argc, char *argv[])
         error = jsonrpc_recv_block(rpc, &msg);
         if (error) {
             ovsdb_schema_destroy(schema);
-            ovs_fatal(error, "%s: receive failed", argv[1]);
+            ovs_fatal(error, "%s: receive failed", server);
         }
 
         if (msg->type == JSONRPC_REQUEST && !strcmp(msg->method, "echo")) {
@@ -874,11 +915,12 @@ do_help(int argc UNUSED, char *argv[] UNUSED)
 }
 
 static const struct command all_commands[] = {
-    { "get-schema", 1, 1, do_get_schema },
-    { "list-tables", 1, 1, do_list_tables },
-    { "list-columns", 1, 2, do_list_columns },
+    { "list-dbs", 1, 1, do_list_dbs },
+    { "get-schema", 2, 2, do_get_schema },
+    { "list-tables", 2, 2, do_list_tables },
+    { "list-columns", 2, 3, do_list_columns },
     { "transact", 2, 2, do_transact },
-    { "monitor", 2, 4, do_monitor },
+    { "monitor", 3, 5, do_monitor },
     { "help", 0, INT_MAX, do_help },
     { NULL, 0, 0, NULL },
 };
index b411131..a0f4a56 100755 (executable)
@@ -734,7 +734,8 @@ static void\n%s_columns_init(void)
 
     # IDL class.
     print "\nstruct ovsdb_idl_class %sidl_class = {" % prefix
-    print "    %stable_classes, ARRAY_SIZE(%stable_classes)" % (prefix, prefix)
+    print "    \"%s\", %stable_classes, ARRAY_SIZE(%stable_classes)" % (
+        schema.name, prefix, prefix)
     print "};"
 
     # global init function
index 06080f7..ca155a1 100644 (file)
@@ -1,7 +1,7 @@
 AT_BANNER([OVSDB -- execution])
 
 m4_define([ORDINAL_SCHEMA],
-  [[{"name": "mydb",
+  [[{"name": "ordinals",
      "tables": {
        "ordinals": {
          "columns": {
@@ -53,10 +53,12 @@ m4_define([OVSDB_CHECK_EXECUTION],
 m4_define([EXECUTION_EXAMPLES], [
 OVSDB_CHECK_EXECUTION([insert row, query table],
   [ORDINAL_SCHEMA], 
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"}}]]],
-   [[[{"op": "select",
+   [[["ordinals",
+      {"op": "select",
        "table": "ordinals",
        "where": []}]]]],
   [[[{"uuid":["uuid","<0>"]}]
@@ -65,16 +67,20 @@ OVSDB_CHECK_EXECUTION([insert row, query table],
 
 OVSDB_CHECK_EXECUTION([insert rows, query by value],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"}}]]],
-   [[[{"op": "insert",
+   [[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 1, "name": "one"}}]]],
-   [[[{"op": "select",
+   [[["ordinals",
+      {"op": "select",
        "table": "ordinals",
        "where": [["name", "==", "zero"]]}]]],
-   [[[{"op": "select",
+   [[["ordinals",
+      {"op": "select",
        "table": "ordinals",
        "where": [["name", "==", "one"]]}]]]],
   [[[{"uuid":["uuid","<0>"]}]
@@ -85,7 +91,8 @@ OVSDB_CHECK_EXECUTION([insert rows, query by value],
 
 OVSDB_CHECK_EXECUTION([insert rows, query by named-uuid],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"},
        "uuid-name": "first"},
@@ -104,19 +111,23 @@ OVSDB_CHECK_EXECUTION([insert rows, query by named-uuid],
 
 OVSDB_CHECK_EXECUTION([insert rows, update rows by value],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"},
        "uuid-name": "first"}]]],
-   [[[{"op": "insert",
+   [[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 1, "name": "one"},
        "uuid-name": "first"}]]],
-   [[[{"op": "update",
+   [[["ordinals",
+      {"op": "update",
        "table": "ordinals",
        "where": [["name", "==", "zero"]],
        "row": {"name": "nought"}}]]],
-   [[[{"op": "select",
+   [[["ordinals",
+      {"op": "select",
        "table": "ordinals",
        "where": [],
        "sort": ["number"]}]]]],
@@ -128,19 +139,23 @@ OVSDB_CHECK_EXECUTION([insert rows, update rows by value],
 
 OVSDB_CHECK_EXECUTION([insert rows, mutate rows],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"},
        "uuid-name": "first"}]]],
-   [[[{"op": "insert",
+   [[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 1, "name": "one"},
        "uuid-name": "first"}]]],
-   [[[{"op": "mutate",
+   [[["ordinals",
+      {"op": "mutate",
        "table": "ordinals",
        "where": [["name", "==", "zero"]],
        "mutations": [["number", "+=", 2]]}]]],
-   [[[{"op": "select",
+   [[["ordinals",
+      {"op": "select",
        "table": "ordinals",
        "where": [],
        "sort": ["number"]}]]]],
@@ -152,7 +167,8 @@ OVSDB_CHECK_EXECUTION([insert rows, mutate rows],
 
 OVSDB_CHECK_EXECUTION([insert rows, delete by named-uuid],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"},
        "uuid-name": "first"},
@@ -172,18 +188,22 @@ OVSDB_CHECK_EXECUTION([insert rows, delete by named-uuid],
 
 OVSDB_CHECK_EXECUTION([insert rows, delete rows by value],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"},
        "uuid-name": "first"}]]],
-   [[[{"op": "insert",
+   [[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 1, "name": "one"},
        "uuid-name": "first"}]]],
-   [[[{"op": "delete",
+   [[["ordinals",
+      {"op": "delete",
        "table": "ordinals",
        "where": [["name", "==", "zero"]]}]]],
-   [[[{"op": "select",
+   [[["ordinals",
+      {"op": "select",
        "table": "ordinals",
        "where": []}]]]],
   [[[{"uuid":["uuid","<0>"]}]
@@ -194,18 +214,22 @@ OVSDB_CHECK_EXECUTION([insert rows, delete rows by value],
 
 OVSDB_CHECK_EXECUTION([insert rows, delete by (non-matching) value],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"},
        "uuid-name": "first"}]]],
-   [[[{"op": "insert",
+   [[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 1, "name": "one"},
        "uuid-name": "first"}]]],
-   [[[{"op": "delete",
+   [[["ordinals",
+      {"op": "delete",
        "table": "ordinals",
        "where": [["name", "==", "nought"]]}]]],
-   [[[{"op": "select",
+   [[["ordinals",
+      {"op": "select",
        "table": "ordinals",
        "where": [],
        "sort": ["number"]}]]]],
@@ -217,7 +241,8 @@ OVSDB_CHECK_EXECUTION([insert rows, delete by (non-matching) value],
 
 OVSDB_CHECK_EXECUTION([insert rows, delete all],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"},
        "uuid-name": "first"},
@@ -237,7 +262,8 @@ OVSDB_CHECK_EXECUTION([insert rows, delete all],
 
 OVSDB_CHECK_EXECUTION([insert row, query table, commit],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"}},
       {"op": "select",
@@ -250,7 +276,8 @@ OVSDB_CHECK_EXECUTION([insert row, query table, commit],
 
 OVSDB_CHECK_EXECUTION([insert row, query table, commit durably],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"}},
       {"op": "select",
@@ -263,7 +290,8 @@ OVSDB_CHECK_EXECUTION([insert row, query table, commit durably],
 
 OVSDB_CHECK_EXECUTION([equality wait with correct rows],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"}},
       {"op": "insert",
@@ -282,7 +310,8 @@ OVSDB_CHECK_EXECUTION([equality wait with correct rows],
 
 OVSDB_CHECK_EXECUTION([equality wait with extra row],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"}},
       {"op": "insert",
@@ -302,7 +331,8 @@ OVSDB_CHECK_EXECUTION([equality wait with extra row],
 
 OVSDB_CHECK_EXECUTION([equality wait with missing row],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"}},
       {"op": "insert",
@@ -320,7 +350,8 @@ OVSDB_CHECK_EXECUTION([equality wait with missing row],
 
 OVSDB_CHECK_EXECUTION([inequality wait with correct rows],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"}},
       {"op": "insert",
@@ -339,7 +370,8 @@ OVSDB_CHECK_EXECUTION([inequality wait with correct rows],
 
 OVSDB_CHECK_EXECUTION([inequality wait with extra row],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"}},
       {"op": "insert",
@@ -359,7 +391,8 @@ OVSDB_CHECK_EXECUTION([inequality wait with extra row],
 
 OVSDB_CHECK_EXECUTION([inequality wait with missing row],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"}},
       {"op": "insert",
@@ -377,13 +410,16 @@ OVSDB_CHECK_EXECUTION([inequality wait with missing row],
 
 OVSDB_CHECK_EXECUTION([insert and update constraints],
   [CONSTRAINT_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["constraints",
+      {"op": "insert",
        "table": "constrained",
        "row": {}}]]],
-   [[[{"op": "insert",
+   [[["constraints",
+      {"op": "insert",
        "table": "constrained",
        "row": {"positive": -1}}]]],
-   [[[{"op": "update",
+   [[["constraints",
+      {"op": "update",
        "table": "constrained",
        "where": [],
        "row": {"positive": -2}}]]]],
@@ -394,7 +430,8 @@ OVSDB_CHECK_EXECUTION([insert and update constraints],
 
 OVSDB_CHECK_EXECUTION([referential integrity -- simple],
   [CONSTRAINT_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["constraints",
+      {"op": "insert",
        "table": "b",
        "row": {"b": 1},
        "uuid-name": "brow"},
@@ -410,25 +447,32 @@ OVSDB_CHECK_EXECUTION([referential integrity -- simple],
        "table": "a",
        "row": {"a": 2,
                "a2b": ["set", [["named-uuid", "brow"]]]}}]]],
-   [[[{"op": "delete",
+   [[["constraints",
+      {"op": "delete",
        "table": "b",
        "where": []}]]],
-   [[[{"op": "delete",
+   [[["constraints",
+      {"op": "delete",
        "table": "a",
        "where": [["a", "==", 0]]}]]],
-   [[[{"op": "delete",
+   [[["constraints",
+      {"op": "delete",
        "table": "b",
        "where": []}]]],
-   [[[{"op": "delete",
+   [[["constraints",
+      {"op": "delete",
        "table": "a",
        "where": [["a", "==", 1]]}]]],
-   [[[{"op": "delete",
+   [[["constraints",
+      {"op": "delete",
        "table": "b",
        "where": []}]]],
-   [[[{"op": "delete",
+   [[["constraints",
+      {"op": "delete",
        "table": "a",
        "where": [["a", "==", 2]]}]]],
-   [[[{"op": "delete",
+   [[["constraints",
+      {"op": "delete",
        "table": "b",
        "where": []}]]]],
   [[[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{"uuid":["uuid","<2>"]},{"uuid":["uuid","<3>"]}]
@@ -443,7 +487,8 @@ OVSDB_CHECK_EXECUTION([referential integrity -- simple],
 
 OVSDB_CHECK_EXECUTION([referential integrity -- mutual references],
   [CONSTRAINT_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["constraints",
+      {"op": "insert",
        "table": "a",
        "row": {"a": 0,
                "a2b": ["set", [["named-uuid", "row2"]]],
@@ -455,23 +500,29 @@ OVSDB_CHECK_EXECUTION([referential integrity -- mutual references],
                "b2b": ["set", [["named-uuid", "row2"]]],
                "b2a": ["set", [["named-uuid", "row1"]]]},
        "uuid-name": "row2"}]]],
-   [[[{"op": "insert",
+   [[["constraints",
+      {"op": "insert",
        "table": "a",
        "row": {"a2b": ["set", [["uuid", "b516b960-5b19-4fc2-bb82-fe1cbd6d0241"]]]}}]]],
-   [[[{"op": "delete",
+   [[["constraints",
+      {"op": "delete",
        "table": "a",
        "where": [["a", "==", 0]]}]]],
-   [[[{"op": "delete",
+   [[["constraints",
+      {"op": "delete",
        "table": "b",
        "where": [["b", "==", 1]]}]]],
    dnl Try the deletions again to make sure that the refcounts got rolled back.
-   [[[{"op": "delete",
+   [[["constraints",
+      {"op": "delete",
        "table": "a",
        "where": [["a", "==", 0]]}]]],
-   [[[{"op": "delete",
+   [[["constraints",
+      {"op": "delete",
        "table": "b",
        "where": [["b", "==", 1]]}]]],
-   [[[{"op": "delete",
+   [[["constraints",
+      {"op": "delete",
        "table": "a",
        "where": [["a", "==", 0]]},
       {"op": "delete",
index d08b6de..4f8f7ee 100644 (file)
@@ -36,7 +36,8 @@ AT_DATA([schema], [ORDINAL_SCHEMA
 touch .db.~lock~
 AT_CHECK([ovsdb-tool create db schema], [0], [], [ignore])
 AT_CHECK([[ovsdb-tool transact db '
-    [{"op": "insert",
+    ["ordinals",
+     {"op": "insert",
       "table": "ordinals",
       "row": {"name": "five", "number": 5}},
      {"op": "comment",
index 6fc57f3..9b90b03 100644 (file)
@@ -38,7 +38,8 @@ OVSDB_CHECK_IDL([simple idl, initially empty, no ops],
 
 OVSDB_CHECK_IDL([simple idl, initially empty, various ops],
   [],
-  [['[{"op": "insert",
+  [['["idltest",
+      {"op": "insert",
        "table": "simple",
        "row": {"i": 1,
                "r": 2.0,
@@ -54,15 +55,18 @@ OVSDB_CHECK_IDL([simple idl, initially empty, various ops],
       {"op": "insert",
        "table": "simple",
        "row": {}}]' \
-    '[{"op": "update",
+    '["idltest",
+      {"op": "update",
        "table": "simple",
        "where": [],
        "row": {"b": true}}]' \
-    '[{"op": "update",
+    '["idltest",
+      {"op": "update",
        "table": "simple",
        "where": [],
        "row": {"r": 123.5}}]' \
-    '[{"op": "insert",
+    '["idltest",
+      {"op": "insert",
        "table": "simple",
        "row": {"i": -1,
                "r": 125,
@@ -73,11 +77,13 @@ OVSDB_CHECK_IDL([simple idl, initially empty, various ops],
                "ba": ["set", [false]],
                "sa": ["set", []], 
                "ua": ["set", []]}}]' \
-    '[{"op": "update",
+    '["idltest",
+      {"op": "update",
        "table": "simple",
        "where": [["i", "<", 1]],
        "row": {"s": "newstring"}}]' \
-    '[{"op": "delete",
+    '["idltest",
+      {"op": "delete",
        "table": "simple",
        "where": [["i", "==", 0]]}]' \
     'reconnect']],
@@ -109,7 +115,8 @@ OVSDB_CHECK_IDL([simple idl, initially empty, various ops],
 ]])
 
 OVSDB_CHECK_IDL([simple idl, initially populated],
-  [['[{"op": "insert",
+  [['["idltest",
+      {"op": "insert",
        "table": "simple",
        "row": {"i": 1,
                "r": 2.0,
@@ -125,7 +132,8 @@ OVSDB_CHECK_IDL([simple idl, initially populated],
       {"op": "insert",
        "table": "simple",
        "row": {}}]']],
-  [['[{"op": "update",
+  [['["idltest",
+      {"op": "update",
        "table": "simple",
        "where": [],
        "row": {"b": true}}]']],
@@ -138,7 +146,8 @@ OVSDB_CHECK_IDL([simple idl, initially populated],
 ]])
 
 OVSDB_CHECK_IDL([simple idl, writing via IDL],
-  [['[{"op": "insert",
+  [['["idltest",
+      {"op": "insert",
        "table": "simple",
        "row": {"i": 1,
                "r": 2.0,
@@ -168,7 +177,8 @@ OVSDB_CHECK_IDL([simple idl, writing via IDL],
 ]])
 
 OVSDB_CHECK_IDL([simple idl, increment operation],
-  [['[{"op": "insert",
+  [['["idltest",
+      {"op": "insert",
        "table": "simple",
        "row": {}}]']],
   [['set 0 r 2.0, increment simple i']],
@@ -180,11 +190,13 @@ OVSDB_CHECK_IDL([simple idl, increment operation],
 
 OVSDB_CHECK_IDL([self-linking idl, consistent ops],
   [],
-  [['[{"op": "insert",
+  [['["idltest",
+      {"op": "insert",
        "table": "link1",
        "row": {"i": 0, "k": ["named-uuid", "self"]},
        "uuid-name": "self"}]' \
-    '[{"op": "insert",
+    '["idltest",
+      {"op": "insert",
        "table": "link1",
        "row": {"i": 1, "k": ["named-uuid", "row2"]},
        "uuid-name": "row1"},
@@ -192,11 +204,13 @@ OVSDB_CHECK_IDL([self-linking idl, consistent ops],
        "table": "link1",
        "row": {"i": 2, "k": ["named-uuid", "row1"]},
        "uuid-name": "row2"}]' \
-    '[{"op": "update",
+    '["idltest",
+      {"op": "update",
        "table": "link1",
        "where": [["i", "==", 1]],
        "row": {"k": ["uuid", "#1#"]}}]' \
-    '[{"op": "update",
+    '["idltest",
+      {"op": "update",
        "table": "link1",
        "where": [],
        "row": {"k": ["uuid", "#0#"]}}]']],
@@ -220,27 +234,33 @@ OVSDB_CHECK_IDL([self-linking idl, consistent ops],
 
 OVSDB_CHECK_IDL([self-linking idl, inconsistent ops],
   [],
-  [['[{"op": "insert",
+  [['["idltest",
+      {"op": "insert",
        "table": "link1",
        "row": {"i": 0, "k": ["uuid", "cf197cc5-c8c9-42f5-82d5-c71a9f2cb96b"]}}]' \
-    '+[{"op": "insert",
+    '+["idltest",
+      {"op": "insert",
        "table": "link1",
        "uuid-name": "one",
        "row": {"i": 1, "k": ["named-uuid", "one"]}},
       {"op": "insert",
        "table": "link1",
        "row": {"i": 2, "k": ["named-uuid", "one"]}}]' \
-     '[{"op": "update",
+     '["idltest",
+      {"op": "update",
        "table": "link1",
        "where": [],
        "row": {"k": ["uuid", "c2fca39a-e69a-42a4-9c56-5eca85839ce9"]}}]' \
-     '+[{"op": "delete",
+     '+["idltest",
+      {"op": "delete",
        "table": "link1",
        "where": [["_uuid", "==", ["uuid", "#1#"]]]}]' \
-     '+[{"op": "delete",
+     '+["idltest",
+      {"op": "delete",
        "table": "link1",
        "where": [["_uuid", "==", ["uuid", "#2#"]]]}]' \
-     '[{"op": "delete",
+     '["idltest",
+      {"op": "delete",
        "table": "link1",
        "where": []}]' \
 ]],
@@ -260,7 +280,8 @@ OVSDB_CHECK_IDL([self-linking idl, inconsistent ops],
 
 OVSDB_CHECK_IDL([self-linking idl, sets],
   [],
-  [['[{"op": "insert",
+  [['["idltest",
+      {"op": "insert",
        "table": "link1",
        "row": {"i": 0, "k": ["named-uuid", "i0"], "ka": ["set", [["named-uuid", "i0"]]]},
        "uuid-name": "i0"},
@@ -276,15 +297,18 @@ OVSDB_CHECK_IDL([self-linking idl, sets],
        "table": "link1",
        "row": {"i": 3, "k": ["named-uuid", "i0"], "ka": ["set", [["named-uuid", "i3"]]]},
        "uuid-name": "i3"}]' \
-    '[{"op": "update",
+    '["idltest",
+      {"op": "update",
        "table": "link1",
        "where": [],
        "row": {"ka": ["set", [["uuid", "#0#"], ["uuid", "#1#"], ["uuid", "#2#"], ["uuid", "#3#"]]]}}]' \
-    '[{"op": "update",
+    '["idltest",
+      {"op": "update",
        "table": "link1",
        "where": [],
        "row": {"ka": ["set", [["uuid", "#0#"], ["uuid", "88702e78-845b-4a6e-ad08-cf68922ae84a"], ["uuid", "#2#"], ["uuid", "1ac2b12e-b767-4805-a55d-43976e40c465"]]]}}]' \
-    '+[{"op": "delete",
+    '+["idltest",
+      {"op": "delete",
        "table": "link1",
        "where": []}]']],
   [[000: empty
@@ -306,7 +330,8 @@ OVSDB_CHECK_IDL([self-linking idl, sets],
 
 OVSDB_CHECK_IDL([external-linking idl, consistent ops],
   [],
-  [['[{"op": "insert",
+  [['["idltest",
+      {"op": "insert",
        "table": "link2",
        "row": {"i": 0},
        "uuid-name": "row0"},
index 5ebf122..87afa1e 100644 (file)
@@ -24,7 +24,7 @@ m4_define([OVSDB_CHECK_MONITOR],
    m4_foreach([txn], [$3],
      [AT_CHECK([ovsdb-tool transact db 'txn'], [0], [ignore], [ignore])])
    AT_CHECK([ovsdb-server --detach --pidfile=$PWD/server-pid --remote=punix:socket --unixctl=$PWD/unixctl db], [0], [ignore], [ignore])
-   AT_CHECK([ovsdb-client --detach --pidfile=$PWD/client-pid monitor --format=csv unix:socket $4 > output], 
+   AT_CHECK([ovsdb-client --detach --pidfile=$PWD/client-pid monitor --format=csv unix:socket ordinals $4 > output], 
             [0], [ignore], [ignore], [kill `cat server-pid`])
    m4_foreach([txn], [$5],
      [AT_CHECK([ovsdb-client transact unix:socket 'txn'], [0],
@@ -40,7 +40,8 @@ OVSDB_CHECK_MONITOR([monitor insert into empty table],
   [ORDINAL_SCHEMA],
   [],
   [ordinals],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"}}]]]],
   [[row,action,name,number,_version
@@ -49,11 +50,13 @@ OVSDB_CHECK_MONITOR([monitor insert into empty table],
 
 OVSDB_CHECK_MONITOR([monitor insert into populated table],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 10, "name": "ten"}}]]]],
   [ordinals],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"}}]]]],
   [[row,action,name,number,_version
@@ -64,11 +67,13 @@ row,action,name,number,_version
 
 OVSDB_CHECK_MONITOR([monitor delete],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 10, "name": "ten"}}]]]],
   [ordinals],
-  [[[[{"op": "delete",
+  [[[["ordinals",
+      {"op": "delete",
        "table": "ordinals",
        "where": [["number", "==", 10]]}]]]],
   [[row,action,name,number,_version
@@ -79,11 +84,13 @@ row,action,name,number,_version
 
 OVSDB_CHECK_MONITOR([monitor row update],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 10, "name": "ten"}}]]]],
   [ordinals],
-  [[[[{"op": "update",
+  [[[["ordinals",
+      {"op": "update",
        "table": "ordinals",
        "where": [["number", "==", 10]],
        "row": {"name": "five plus five"}}]]]],
@@ -96,15 +103,18 @@ row,action,name,number,_version
 
 OVSDB_CHECK_MONITOR([monitor no-op row updates],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 10, "name": "ten"}}]]]],
   [ordinals],
-  [[[[{"op": "update",
+  [[[["ordinals",
+      {"op": "update",
        "table": "ordinals",
        "where": [["number", "==", 10]],
        "row": {"number": 10, "name": "ten"}}]]],
-   [[[{"op": "insert",
+   [[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 9, "name": "nine"}}]]]],
   [[row,action,name,number,_version
@@ -115,11 +125,13 @@ row,action,name,number,_version
 
 OVSDB_CHECK_MONITOR([monitor insert-and-update transaction],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 10, "name": "ten"}}]]]],
   [ordinals],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 9, "name": "nine"},
        "uuid-name": "nine"},
@@ -136,11 +148,13 @@ row,action,name,number,_version
 
 OVSDB_CHECK_MONITOR([monitor insert-update-and-delete transaction],
   [ORDINAL_SCHEMA],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 10, "name": "ten"}}]]]],
   [ordinals],
-  [[[[{"op": "insert",
+  [[[["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 9, "name": "nine"},
        "uuid-name": "nine"},
index 0b02189..8d81e11 100644 (file)
@@ -38,6 +38,23 @@ cat stdout >> output
 
 EXECUTION_EXAMPLES
 \f
+AT_SETUP([database multiplexing implementation])
+AT_KEYWORDS([ovsdb server positive])
+AT_DATA([schema], [ORDINAL_SCHEMA
+])
+AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
+AT_CHECK([ovsdb-server --detach --pidfile=$PWD/pid --unixctl=$PWD/unixctl --remote=punix:socket db], [0], [ignore], [ignore])
+AT_CHECK(
+  [[ovsdb-client list-dbs unix:socket]], 
+  [0], [ordinals
+], [ignore], [test ! -e pid || kill `cat pid`])
+AT_CHECK(
+  [[ovsdb-client get-schema unix:socket nonexistent]], 
+  [1], [], [[ovsdb-client: syntax "{"syntax":"[\"nonexistent\"]","details":"get_schema request specifies unknown database nonexistent","error":"unknown database"}": syntax error: Parsing database schema failed: Required 'name' member is missing.
+]], [test ! -e pid || kill `cat pid`])
+OVSDB_SERVER_SHUTDOWN
+AT_CLEANUP
+
 AT_SETUP([--remote=db: implementation])
 AT_KEYWORDS([ovsdb server positive])
 AT_DATA([schema],
@@ -50,13 +67,15 @@ AT_DATA([schema],
 AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
 AT_CHECK(
   [[ovsdb-tool transact db \
-     '[{"op": "insert",
+     '["mydb",
+       {"op": "insert",
         "table": "Manager",
         "row": {"manager": "punix:socket"}}]']], [0], [ignore], [ignore])
 AT_CHECK([ovsdb-server --detach --pidfile=$PWD/pid --remote=db:Manager,manager --unixctl=$PWD/unixctl db], [0], [ignore], [ignore])
 AT_CHECK(
   [[ovsdb-client transact unix:socket \
-     '[{"op": "select",
+     '["mydb",
+       {"op": "select",
         "table": "Manager",
         "where": [],
         "columns": ["manager"]}]']], 
index 97330fb..c2b1b96 100644 (file)
@@ -14,7 +14,8 @@ m4_define([OVSDB_CHECK_TRIGGER],
 
 OVSDB_CHECK_TRIGGER([trigger fires immediately],
   ['ORDINAL_SCHEMA' [\
-    '[{"op": "insert",
+    '["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"}},
       {"op": "insert",
@@ -36,7 +37,8 @@ OVSDB_CHECK_TRIGGER([trigger fires immediately],
 
 OVSDB_CHECK_TRIGGER([trigger times out],
   ['ORDINAL_SCHEMA' [\
-    '[{"op": "insert",
+    '["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"}},
       {"op": "insert",
@@ -58,14 +60,16 @@ t=10: trigger 0 (delayed): [{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{"de
 
 OVSDB_CHECK_TRIGGER([trigger fires after delay],
   ['ORDINAL_SCHEMA' [\
-    '[{"op": "insert",
+    '["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"}},
       {"op": "insert",
        "table": "ordinals",
        "row": {"number": 1, "name": "one"}}]' \
     '["advance", 5]' \
-    '[{"op": "wait",
+    '["ordinals",
+      {"op": "wait",
        "timeout": 10,
        "table": "ordinals",
        "where": [],
@@ -75,7 +79,8 @@ OVSDB_CHECK_TRIGGER([trigger fires after delay],
                 {"name": "one", "number": 1},
                 {"name": "two", "number": 2}]}]' \
     '["advance", 5]' \
-    '[{"op": "insert",
+    '["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 2, "name": "two"}}]']],
   [[t=0: trigger 0 (immediate): [{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]}]
@@ -86,14 +91,16 @@ t=10: trigger 1 (delayed): [{}]
 
 OVSDB_CHECK_TRIGGER([delayed trigger modifies database],
   ['ORDINAL_SCHEMA' [\
-    '[{"op": "insert",
+    '["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"}},
       {"op": "insert",
        "table": "ordinals",
        "row": {"number": 1, "name": "one"}}]' \
     '["advance", 5]' \
-    '[{"op": "wait",
+    '["ordinals",
+      {"op": "wait",
        "timeout": 10,
        "table": "ordinals",
        "where": [],
@@ -106,11 +113,13 @@ OVSDB_CHECK_TRIGGER([delayed trigger modifies database],
        "table": "ordinals",
        "where": [["number", "<", 2]]}]' \
     '["advance", 5]' \
-    '[{"op": "insert",
+    '["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 2, "name": "two"}}]' \
     '["advance", 5]' \
-    '[{"op": "select",
+    '["ordinals",
+      {"op": "select",
        "table": "ordinals",
        "where": []}]']],
   [[t=0: trigger 0 (immediate): [{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]}]
@@ -122,14 +131,16 @@ t=15: trigger 3 (immediate): [{"rows":[{"_uuid":["uuid","<2>"],"_version":["uuid
 
 OVSDB_CHECK_TRIGGER([one delayed trigger wakes up another],
   ['ORDINAL_SCHEMA' [\
-    '[{"op": "insert",
+    '["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 0, "name": "zero"}},
       {"op": "insert",
        "table": "ordinals",
        "row": {"number": 1, "name": "one"}}]' \
     '["advance", 5]' \
-    '[{"op": "wait",
+    '["ordinals",
+      {"op": "wait",
        "timeout": 10,
        "table": "ordinals",
        "where": [],
@@ -142,7 +153,8 @@ OVSDB_CHECK_TRIGGER([one delayed trigger wakes up another],
       {"op": "insert",
        "table": "ordinals",
        "row": {"number": 3, "name": "three"}}]' \
-    '[{"op": "wait",
+    '["ordinals",
+      {"op": "wait",
        "timeout": 10,
        "table": "ordinals",
        "where": [],
@@ -155,11 +167,13 @@ OVSDB_CHECK_TRIGGER([one delayed trigger wakes up another],
        "table": "ordinals",
        "where": [["number", "<", 2]]}]' \
     '["advance", 5]' \
-    '[{"op": "insert",
+    '["ordinals",
+      {"op": "insert",
        "table": "ordinals",
        "row": {"number": 2, "name": "two"}}]' \
     '["advance", 5]' \
-    '[{"op": "select",
+    '["ordinals",
+      {"op": "select",
        "table": "ordinals",
        "where": []}]']],
   [[t=0: trigger 0 (immediate): [{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]}]
index c1fd98e..02fd94e 100644 (file)
@@ -1,4 +1,4 @@
-{"name": "ovs_vswitchd_db",
+{"name": "Open_vSwitch",
  "comment": "Configuration for one Open vSwitch daemon.",
  "tables": {
    "Open_vSwitch": {