On Tue, Jun 30, 2015 at 10:36 AM, Sabyasachi Sengupta
<sabyasachi.sengu...@alcatel-lucent.com> wrote:
>
> v2: fixed a bug in do_dump that was calling print_table incorrectly when
> 'table' option is specified
>
> Added capability of displaying tables through an optional 'table' argument
> to 'ovsdb-client dump'. When specified, ovsdb-client will iterate
> through all tables in the chosen ovsdb, and create a transaction only
> for that table instead of all, and then print the response for that
> transaction.
>
> Signed-off-by: Sabyasachi Sengupta <sabyasachi.sengu...@alcatel-lucent.com>

Is actually adding a new feature rather than fix a bug?
If so, you may also want to update the man pages with the new usage
and add unit tests for it.

If this patch also fixes bugs, then the bug fix should be in a separate patch.

What would be default argument for the new 'table' argument if it is
not specified?

Just to make sure we are not feature creeping, Can this be achieved via
shell scripts running on top of 'ovsdb-client dump db'?

>
> ---
>  ovsdb/ovsdb-client.c |  105
> +++++++++++++++++++++++++++++++++-----------------
>  1 files changed, 69 insertions(+), 36 deletions(-)
>
> diff --git a/ovsdb/ovsdb-client.c b/ovsdb/ovsdb-client.c
> index 2942953..84474d0 100644
> --- a/ovsdb/ovsdb-client.c
> +++ b/ovsdb/ovsdb-client.c
> @@ -255,8 +255,8 @@ usage(void)
>             "\n  monitor [SERVER] [DATABASE] ALL\n"
>             "    monitor all changes to all columns in all tables\n"
>             "    in DATBASE on SERVER.\n"
> -           "\n  dump [SERVER] [DATABASE]\n"
> -           "    dump contents of DATABASE on SERVER to stdout\n"
> +           "\n  dump [SERVER] [DATABASE] [TABLE]\n"
> +           "    dump contents of table(s) in DATABASE on SERVER to
> stdout\n"
>             "\nThe default SERVER is unix:%s/db.sock.\n"
>             "The default DATABASE is Open_vSwitch.\n",
>             program_name, program_name, ovs_rundir());
> @@ -1042,44 +1042,80 @@ dump_table(const struct ovsdb_table_schema *ts,
> struct json_array *rows)
>  }
>
>  static void
> -do_dump(struct jsonrpc *rpc, const char *database,
> -        int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
> +create_table_transaction(struct json *transaction,
> +                         const struct shash_node *table)
> +{
> +    const struct ovsdb_table_schema *ts = table->data;
> +    struct json *op, *columns;
> +    struct shash_node *node;
> +
> +    columns = json_array_create_empty();
> +    SHASH_FOR_EACH (node, &ts->columns) {
> +        const struct ovsdb_column *column = node->data;
> +
> +        if (strcmp(column->name, "_version")) {
> +            json_array_add(columns, json_string_create(column->name));
> +        }
> +    }
> +
> +    op = json_object_create();
> +    json_object_put_string(op, "op", "select");
> +    json_object_put_string(op, "table", table->name);
> +    json_object_put(op, "where", json_array_create_empty());
> +    json_object_put(op, "columns", columns);
> +    json_array_add(transaction, op);
> +}
> +
> +static void
> +print_table(const struct json *op_result, const struct shash_node *table)
> +{
> +    const struct ovsdb_table_schema *ts = table->data;
> +    struct json *rows;
> +
> +    if (op_result->type != JSON_OBJECT
> +        || !(rows = shash_find_data(json_object(op_result), "rows"))
> +        || rows->type != JSON_ARRAY) {
> +        ovs_fatal(0, "%s table reply is not an object with a \"rows\" "
> +                  "member array: %s", ts->name, json_to_string(op_result,
> 0));
> +    }
> +    dump_table(ts, &rows->u.array);
> +}
> +
> +static void
> +do_dump(struct jsonrpc *rpc, const char *database, int argc, char *argv[])
>  {
>      struct jsonrpc_msg *request, *reply;
>      struct ovsdb_schema *schema;
>      struct json *transaction;
>
>      const struct shash_node **tables;
> -    size_t n_tables;
> +    size_t n_tables, n_tables_out;
> +    char *table_name = (argc == 1) ? argv[0] : NULL;
> +    bool table_found = false;
>
>      size_t i;
>
>      schema = fetch_schema(rpc, database);
>      tables = shash_sort(&schema->tables);
>      n_tables = shash_count(&schema->tables);
> +    n_tables_out = table_name ? 1 : n_tables;
>
>      /* Construct transaction to retrieve entire database. */
>      transaction = json_array_create_1(json_string_create(database));
>      for (i = 0; i < n_tables; i++) {
> -        const struct ovsdb_table_schema *ts = tables[i]->data;
> -        struct json *op, *columns;
> -        struct shash_node *node;
> -
> -        columns = json_array_create_empty();
> -        SHASH_FOR_EACH (node, &ts->columns) {
> -            const struct ovsdb_column *column = node->data;
> -
> -            if (strcmp(column->name, "_version")) {
> -                json_array_add(columns, json_string_create(column->name));
> +        if (table_name) {
> +            if (!strncmp(tables[i]->name, table_name,
> +                         MIN(strlen(tables[i]->name), strlen(table_name))))
> {
> +                create_table_transaction(transaction, tables[i]);
> +                table_found = true;
> +                break;
>              }
> +        } else {
> +            create_table_transaction(transaction, tables[i]);
>          }
> -
> -        op = json_object_create();
> -        json_object_put_string(op, "op", "select");
> -        json_object_put_string(op, "table", tables[i]->name);
> -        json_object_put(op, "where", json_array_create_empty());
> -        json_object_put(op, "columns", columns);
> -        json_array_add(transaction, op);
> +    }
> +    if (table_name && !table_found) {
> +        ovs_fatal(0, "specified table '%s' does not exist", table_name);
>      }
>
>      /* Send request, get reply. */
> @@ -1088,24 +1124,21 @@ do_dump(struct jsonrpc *rpc, const char *database,
>
>      /* Print database contents. */
>      if (reply->result->type != JSON_ARRAY
> -        || reply->result->u.array.n != n_tables) {
> +        || reply->result->u.array.n != n_tables_out) {
>          ovs_fatal(0, "reply is not array of %"PRIuSIZE" elements: %s",
>                    n_tables, json_to_string(reply->result, 0));
>      }
>      for (i = 0; i < n_tables; i++) {
> -        const struct ovsdb_table_schema *ts = tables[i]->data;
> -        const struct json *op_result = reply->result->u.array.elems[i];
> -        struct json *rows;
> -
> -        if (op_result->type != JSON_OBJECT
> -            || !(rows = shash_find_data(json_object(op_result), "rows"))
> -            || rows->type != JSON_ARRAY) {
> -            ovs_fatal(0, "%s table reply is not an object with a \"rows\" "
> -                      "member array: %s",
> -                      ts->name, json_to_string(op_result, 0));
> +        if (table_name) {
> +            if (!strncmp(tables[i]->name, table_name,
> +                         MIN(strlen(tables[i]->name),
> +                             strlen(table_name)))) {
> +                print_table(reply->result->u.array.elems[0], tables[i]);
> +                break;
> +            }
> +        } else {
> +            print_table(reply->result->u.array.elems[i], tables[i]);
>          }
> -
> -        dump_table(ts, &rows->u.array);
>      }
>
>      jsonrpc_msg_destroy(reply);
> @@ -1135,7 +1168,7 @@ static const struct ovsdb_client_command
> all_commands[] = {
>      { "list-columns",       NEED_DATABASE, 0, 1,       do_list_columns },
>      { "transact",           NEED_RPC,      1, 1,       do_transact },
>      { "monitor",            NEED_DATABASE, 1, INT_MAX, do_monitor },
> -    { "dump",               NEED_DATABASE, 0, 0,       do_dump },
> +    { "dump",               NEED_DATABASE, 0, 1,       do_dump },
>
>      { "help",               NEED_NONE,     0, INT_MAX, do_help },
>
> --
> 1.7.1
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to