Add ovsdb_schema_join that joins two schemas into a new schema that is the union of the originally tow schemas.
Signed-off-by: Andy Zhou <az...@nicira.com> --- ovsdb/column.c | 13 +++++++++++++ ovsdb/column.h | 2 ++ ovsdb/ovsdb.c | 28 +++++++++++++++++++++++++++- ovsdb/ovsdb.h | 3 +++ ovsdb/table.c | 39 +++++++++++++++++++++++++++++++++++++++ ovsdb/table.h | 3 +++ 6 files changed, 87 insertions(+), 1 deletion(-) diff --git a/ovsdb/column.c b/ovsdb/column.c index 26b7a0b..8d94deb 100644 --- a/ovsdb/column.c +++ b/ovsdb/column.c @@ -53,6 +53,19 @@ ovsdb_column_clone(const struct ovsdb_column *old) &old->type); } +bool +ovsdb_column_equal(const struct ovsdb_column *a, + const struct ovsdb_column *b) +{ + struct json *ja = ovsdb_column_to_json(a); + struct json *jb = ovsdb_column_to_json(b); + bool equals = json_equal(ja, jb); + json_destroy(ja); + json_destroy(jb); + + return equals; +} + void ovsdb_column_destroy(struct ovsdb_column *column) { diff --git a/ovsdb/column.h b/ovsdb/column.h index f75a107..1eaf0e0 100644 --- a/ovsdb/column.h +++ b/ovsdb/column.h @@ -48,6 +48,8 @@ struct ovsdb_column *ovsdb_column_create( const char *name, bool mutable, bool persistent, const struct ovsdb_type *); struct ovsdb_column *ovsdb_column_clone(const struct ovsdb_column *); +bool ovsdb_column_equal(const struct ovsdb_column *, + const struct ovsdb_column *); void ovsdb_column_destroy(struct ovsdb_column *); struct ovsdb_error *ovsdb_column_from_json(const struct json *, diff --git a/ovsdb/ovsdb.c b/ovsdb/ovsdb.c index 56d2333..64355eb 100644 --- a/ovsdb/ovsdb.c +++ b/ovsdb/ovsdb.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. +/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2015 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -307,6 +307,32 @@ ovsdb_schema_equal(const struct ovsdb_schema *a, return equals; } + +static struct ovsdb_error * +ovsdb_schema_join(struct ovsdb_schema *dst, const struct ovsdb_schema *src) +{ + struct shash_node *snode, *dnode; + struct ovsdb_error *err; + + SHASH_FOR_EACH (snode, &src->tables) { + const struct ovsdb_table_schema *sts = snode->data; + + dnode = shash_find(&dst->tables, sts->name); + if (dnode) { + struct ovsdb_table_schema *dts = dnode->data; + + err = ovsdb_table_schema_join(dts, sts); + if (err) { + return err; + } + } else { + shash_add(&dst->tables, sts->name, ovsdb_table_schema_clone(sts)); + } + } + + return NULL; +} + static void ovsdb_set_ref_table(const struct shash *tables, diff --git a/ovsdb/ovsdb.h b/ovsdb/ovsdb.h index 04586e7..215e046 100644 --- a/ovsdb/ovsdb.h +++ b/ovsdb/ovsdb.h @@ -19,6 +19,7 @@ #include "compiler.h" #include "hmap.h" #include "list.h" +#include "sset.h" #include "shash.h" struct json; @@ -50,8 +51,10 @@ struct ovsdb_error *ovsdb_schema_from_json(struct json *, OVS_WARN_UNUSED_RESULT; struct json *ovsdb_schema_to_json(const struct ovsdb_schema *); + bool ovsdb_schema_equal(const struct ovsdb_schema *, const struct ovsdb_schema *); + /* Database. */ struct ovsdb { diff --git a/ovsdb/table.c b/ovsdb/table.c index e7545ad..ec43d98 100644 --- a/ovsdb/table.c +++ b/ovsdb/table.c @@ -102,6 +102,45 @@ ovsdb_table_schema_clone(const struct ovsdb_table_schema *old) return new; } +struct ovsdb_error * +ovsdb_table_schema_join(struct ovsdb_table_schema *dst, + const struct ovsdb_table_schema *src) +{ + struct shash_node *node; + +#undef CHECK_TABLE_FIELD +#define CHECK_TABLE_FIELD(dst, src, field) \ + if (dst->field != src->field) { \ + return ovsdb_error("schema join error", \ + "attribute %s of table %s match failed", \ + #field, dst->name); \ + } + + CHECK_TABLE_FIELD(dst, src, mutable); + CHECK_TABLE_FIELD(dst, src, is_root); + CHECK_TABLE_FIELD(dst, src, max_rows); + +#undef CHECK_TABLE_FIELD + + SHASH_FOR_EACH (node, &src->columns) { + struct ovsdb_column *scol = node->data; + const struct ovsdb_column *dcol; + + dcol = ovsdb_table_schema_get_column(dst, scol->name); + if (dcol) { + if (!ovsdb_column_equal(dcol, scol)) { + return ovsdb_error("schema join error", + "column %s of table %s match failed", + dcol->name, dst->name); + } + } else { + add_column(dst, ovsdb_column_clone(scol)); + } + } + + return NULL; +} + void ovsdb_table_schema_destroy(struct ovsdb_table_schema *ts) { diff --git a/ovsdb/table.h b/ovsdb/table.h index 68a59ad..8572ee4 100644 --- a/ovsdb/table.h +++ b/ovsdb/table.h @@ -39,6 +39,9 @@ struct ovsdb_table_schema *ovsdb_table_schema_create( const char *name, bool mutable, unsigned int max_rows, bool is_root); struct ovsdb_table_schema *ovsdb_table_schema_clone( const struct ovsdb_table_schema *); +struct ovsdb_error *ovsdb_table_schema_join(struct ovsdb_table_schema *, + const struct ovsdb_table_schema *) + OVS_WARN_UNUSED_RESULT; void ovsdb_table_schema_destroy(struct ovsdb_table_schema *); struct ovsdb_error *ovsdb_table_schema_from_json(const struct json *, -- 1.9.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev