- {&ovsrec_table_netflow,
- {{&ovsrec_table_bridge,
- &ovsrec_bridge_col_name,
- &ovsrec_bridge_col_netflow},
- {NULL, NULL, NULL}}},
-
- {&ovsrec_table_open_vswitch,
- {{&ovsrec_table_open_vswitch, NULL, NULL},
- {NULL, NULL, NULL}}},
-
- {&ovsrec_table_port,
- {{&ovsrec_table_port, &ovsrec_port_col_name, NULL},
- {NULL, NULL, NULL}}},
-
- {&ovsrec_table_qos,
- {{&ovsrec_table_port, &ovsrec_port_col_name, &ovsrec_port_col_qos},
- {NULL, NULL, NULL}}},
-
- {&ovsrec_table_queue,
- {{NULL, NULL, NULL},
- {NULL, NULL, NULL}}},
-
- {&ovsrec_table_ssl,
- {{&ovsrec_table_open_vswitch, NULL, &ovsrec_open_vswitch_col_ssl}}},
-
- {&ovsrec_table_sflow,
- {{&ovsrec_table_bridge,
- &ovsrec_bridge_col_name,
- &ovsrec_bridge_col_sflow},
- {NULL, NULL, NULL}}},
-
- {&ovsrec_table_flow_table,
- {{&ovsrec_table_flow_table, &ovsrec_flow_table_col_name, NULL},
- {NULL, NULL, NULL}}},
-
- {NULL, {{NULL, NULL, NULL}, {NULL, NULL, NULL}}}
-};
-
-static void
-die_if_error(char *error)
-{
- if (error) {
- vsctl_fatal("%s", error);
- }
-}
-
-static int
-to_lower_and_underscores(unsigned c)
-{
- return c == '-' ? '_' : tolower(c);
-}
-
-static unsigned int
-score_partial_match(const char *name, const char *s)
-{
- int score;
-
- if (!strcmp(name, s)) {
- return UINT_MAX;
- }
- for (score = 0; ; score++, name++, s++) {
- if (to_lower_and_underscores(*name) != to_lower_and_underscores(*s)) {
- break;
- } else if (*name == '\0') {
- return UINT_MAX - 1;
- }
- }
- return *s == '\0' ? score : 0;
-}
-
-static const struct vsctl_table_class *
-get_table(const char *table_name)
-{
- const struct vsctl_table_class *table;
- const struct vsctl_table_class *best_match = NULL;
- unsigned int best_score = 0;
-
- for (table = tables; table->class; table++) {
- unsigned int score = score_partial_match(table->class->name,
- table_name);
- if (score > best_score) {
- best_match = table;
- best_score = score;
- } else if (score == best_score) {
- best_match = NULL;
- }
- }
- if (best_match) {
- return best_match;
- } else if (best_score) {
- vsctl_fatal("multiple table names match \"%s\"", table_name);
- } else {
- vsctl_fatal("unknown table \"%s\"", table_name);
- }
-}
-
-static const struct vsctl_table_class *
-pre_get_table(struct vsctl_context *ctx, const char *table_name)
-{
- const struct vsctl_table_class *table_class;
- int i;
-
- table_class = get_table(table_name);
- ovsdb_idl_add_table(ctx->idl, table_class->class);
-
- for (i = 0; i < ARRAY_SIZE(table_class->row_ids); i++) {
- const struct vsctl_row_id *id = &table_class->row_ids[i];
- if (id->table) {
- ovsdb_idl_add_table(ctx->idl, id->table);
- }
- if (id->name_column) {
- ovsdb_idl_add_column(ctx->idl, id->name_column);
- }
- if (id->uuid_column) {
- ovsdb_idl_add_column(ctx->idl, id->uuid_column);
- }
- }
-
- return table_class;
-}
-
-static const struct ovsdb_idl_row *
-get_row_by_id(struct vsctl_context *ctx, const struct vsctl_table_class *table,
- const struct vsctl_row_id *id, const char *record_id)
-{
- const struct ovsdb_idl_row *referrer, *final;
-
- if (!id->table) {
- return NULL;
- }
-
- if (!id->name_column) {
- if (strcmp(record_id, ".")) {
- return NULL;
- }
- referrer = ovsdb_idl_first_row(ctx->idl, id->table);
- if (!referrer || ovsdb_idl_next_row(referrer)) {
- return NULL;
- }
- } else {
- const struct ovsdb_idl_row *row;
-
- referrer = NULL;
- for (row = ovsdb_idl_first_row(ctx->idl, id->table);
- row != NULL;
- row = ovsdb_idl_next_row(row))
- {
- const struct ovsdb_datum *name;
-
- name = ovsdb_idl_get(row, id->name_column,
- OVSDB_TYPE_STRING, OVSDB_TYPE_VOID);
- if (name->n == 1 && !strcmp(name->keys[0].string, record_id)) {
- if (referrer) {
- vsctl_fatal("multiple rows in %s match \"%s\"",
- table->class->name, record_id);
- }
- referrer = row;
- }
- }
- }
- if (!referrer) {
- return NULL;
- }
-
- final = NULL;
- if (id->uuid_column) {
- const struct ovsdb_datum *uuid;
-
- ovsdb_idl_txn_verify(referrer, id->uuid_column);
- uuid = ovsdb_idl_get(referrer, id->uuid_column,
- OVSDB_TYPE_UUID, OVSDB_TYPE_VOID);
- if (uuid->n == 1) {
- final = ovsdb_idl_get_row_for_uuid(ctx->idl, table->class,
- &uuid->keys[0].uuid);
- }
- } else {
- final = referrer;