From 7cba02e442012a7ae6cfdfe67f858a18057e5470 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 20 Sep 2011 11:24:44 -0700 Subject: [PATCH] ovs.db.types: Add table reference to ovs.db.types.BaseType. Until now ovs.db.types.BaseType has kept track of the name of the referenced table but not a reference to it. This commit renames the ref_table attribute to ref_table_name and adds a new ref_table attribute whose value is a reference to the named table. This will be useful in an upcoming commit where table references are actually followed. --- debian/ovs-monitor-ipsec | 2 +- ovsdb/ovsdb-dot.in | 4 ++-- ovsdb/ovsdb-idlc.in | 8 +++---- python/ovs/db/schema.py | 19 ++++++++--------- python/ovs/db/types.py | 45 +++++++++++++++++++++------------------- 5 files changed, 40 insertions(+), 38 deletions(-) diff --git a/debian/ovs-monitor-ipsec b/debian/ovs-monitor-ipsec index 019da232a..b9a41268c 100755 --- a/debian/ovs-monitor-ipsec +++ b/debian/ovs-monitor-ipsec @@ -379,7 +379,7 @@ def keep_table_columns(schema, table_name, column_types): def monitor_uuid_schema_cb(schema): string_type = types.Type(types.BaseType(types.StringType)) optional_ssl_type = types.Type(types.BaseType(types.UuidType, - ref_table='SSL'), None, 0, 1) + ref_table_name='SSL'), None, 0, 1) string_map_type = types.Type(types.BaseType(types.StringType), types.BaseType(types.StringType), 0, sys.maxint) diff --git a/ovsdb/ovsdb-dot.in b/ovsdb/ovsdb-dot.in index 30da1cb35..85c126d15 100755 --- a/ovsdb/ovsdb-dot.in +++ b/ovsdb/ovsdb-dot.in @@ -11,7 +11,7 @@ import sys argv0 = sys.argv[0] def printEdge(tableName, type, baseType, label): - if baseType.ref_table: + if baseType.ref_table_name: if type.n_min == 0: if type.n_max == 1: arity = "?" @@ -34,7 +34,7 @@ def printEdge(tableName, type, baseType, label): options['style'] = 'dotted' print "\t%s -> %s [%s];" % ( tableName, - baseType.ref_table, + baseType.ref_table_name, ', '.join(['%s=%s' % (k,v) for k,v in options.items()])) def schemaToDot(schemaFile): diff --git a/ovsdb/ovsdb-idlc.in b/ovsdb/ovsdb-idlc.in index e5c81832a..3392c3559 100755 --- a/ovsdb/ovsdb-idlc.in +++ b/ovsdb/ovsdb-idlc.in @@ -244,13 +244,13 @@ static void if not type.key.ref_table: print " %s = datum->keys[0].%s;" % (keyVar, type.key.type.to_string()) else: - print " %s = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_classes[%sTABLE_%s], &datum->keys[0].uuid));" % (keyVar, prefix, type.key.ref_table.lower(), prefix, prefix.upper(), type.key.ref_table.upper()) + print " %s = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_classes[%sTABLE_%s], &datum->keys[0].uuid));" % (keyVar, prefix, type.key.ref_table.name.lower(), prefix, prefix.upper(), type.key.ref_table.name.upper()) if valueVar: if type.value.ref_table: print " %s = datum->values[0].%s;" % (valueVar, type.value.type.to_string()) else: - print " %s = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_classes[%sTABLE_%s], &datum->values[0].uuid));" % (valueVar, prefix, type.value.ref_table.lower(), prefix, prefix.upper(), type.value.ref_table.upper()) + print " %s = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_classes[%sTABLE_%s], &datum->values[0].uuid));" % (valueVar, prefix, type.value.ref_table.name.lower(), prefix, prefix.upper(), type.value.ref_table.name.upper()) print " } else {" print " %s" % type.key.initCDefault(keyVar, type.n_min == 0) if valueVar: @@ -272,13 +272,13 @@ static void print " for (i = 0; i < %s; i++) {" % nMax refs = [] if type.key.ref_table: - print " struct %s%s *keyRow = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_classes[%sTABLE_%s], &datum->keys[i].uuid));" % (prefix, type.key.ref_table.lower(), prefix, type.key.ref_table.lower(), prefix, prefix.upper(), type.key.ref_table.upper()) + print " struct %s%s *keyRow = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_classes[%sTABLE_%s], &datum->keys[i].uuid));" % (prefix, type.key.ref_table.name.lower(), prefix, type.key.ref_table.name.lower(), prefix, prefix.upper(), type.key.ref_table.name.upper()) keySrc = "keyRow" refs.append('keyRow') else: keySrc = "datum->keys[i].%s" % type.key.type.to_string() if type.value and type.value.ref_table: - print " struct %s%s *valueRow = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_classes[%sTABLE_%s], &datum->values[i].uuid));" % (prefix, type.value.ref_table.lower(), prefix, type.value.ref_table.lower(), prefix, prefix.upper(), type.value.ref_table.upper()) + print " struct %s%s *valueRow = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_classes[%sTABLE_%s], &datum->values[i].uuid));" % (prefix, type.value.ref_table.name.lower(), prefix, type.value.ref_table.name.lower(), prefix, prefix.upper(), type.value.ref_table.name.upper()) valueSrc = "valueRow" refs.append('valueRow') elif valueVar: diff --git a/python/ovs/db/schema.py b/python/ovs/db/schema.py index 1c474a8a2..7e18564e0 100644 --- a/python/ovs/db/schema.py +++ b/python/ovs/db/schema.py @@ -41,16 +41,15 @@ class DbSchema(object): for table in self.tables.itervalues(): table.is_root = True - # Validate that all ref_tables refer to the names of tables - # that exist. + # Find the "ref_table"s referenced by "ref_table_name"s. # # Also force certain columns to be persistent, as explained in # __check_ref_table(). This requires 'is_root' to be known, so this # must follow the loop updating 'is_root' above. for table in self.tables.itervalues(): for column in table.columns.itervalues(): - self.__check_ref_table(column, column.type.key, "key") - self.__check_ref_table(column, column.type.value, "value") + self.__follow_ref_table(column, column.type.key, "key") + self.__follow_ref_table(column, column.type.value, "value") def __root_set_size(self): """Returns the number of tables in the schema's root set.""" @@ -96,17 +95,17 @@ class DbSchema(object): json["version"] = self.version return json - def __check_ref_table(self, column, base, base_name): - if not base or base.type != types.UuidType or not base.ref_table: + def __follow_ref_table(self, column, base, base_name): + if not base or base.type != types.UuidType or not base.ref_table_name: return - ref_table = self.tables.get(base.ref_table) - if not ref_table: + base.ref_table = self.tables.get(base.ref_table_name) + if not base.ref_table: raise error.Error("column %s %s refers to undefined table %s" - % (column.name, base_name, base.ref_table), + % (column.name, base_name, base.ref_table_name), tag="syntax error") - if base.is_strong_ref() and not ref_table.is_root: + if base.is_strong_ref() and not base.ref_table.is_root: # We cannot allow a strong reference to a non-root table to be # ephemeral: if it is the only reference to a row, then replaying # the database log from disk will cause the referenced row to be diff --git a/python/ovs/db/types.py b/python/ovs/db/types.py index 72ab41077..f31318625 100644 --- a/python/ovs/db/types.py +++ b/python/ovs/db/types.py @@ -104,7 +104,7 @@ def returnUnchanged(x): class BaseType(object): def __init__(self, type_, enum=None, min=None, max=None, - min_length = 0, max_length=sys.maxint, ref_table=None): + min_length = 0, max_length=sys.maxint, ref_table_name=None): assert isinstance(type_, AtomicType) self.type = type_ self.enum = enum @@ -112,11 +112,12 @@ class BaseType(object): self.max = max self.min_length = min_length self.max_length = max_length - self.ref_table = ref_table - if ref_table: + self.ref_table_name = ref_table_name + if ref_table_name: self.ref_type = 'strong' else: self.ref_type = None + self.ref_table = None def default(self): return ovs.db.data.Atom.default(self.type) @@ -128,7 +129,7 @@ class BaseType(object): self.min == other.min and self.max == other.max and self.min_length == other.min_length and self.max_length == other.max_length and - self.ref_table == other.ref_table) + self.ref_table_name == other.ref_table_name) def __ne__(self, other): if not isinstance(other, BaseType): @@ -178,8 +179,8 @@ class BaseType(object): if base.min_length > base.max_length: raise error.Error("minLength exceeds maxLength", json) elif base.type == UuidType: - base.ref_table = parser.get_optional("refTable", ['id']) - if base.ref_table: + base.ref_table_name = parser.get_optional("refTable", ['id']) + if base.ref_table_name: base.ref_type = parser.get_optional("refType", [str, unicode], "strong") if base.ref_type not in ['strong', 'weak']: @@ -214,15 +215,17 @@ class BaseType(object): if self.max_length != sys.maxint: json['maxLength'] = self.max_length elif self.type == UuidType: - if self.ref_table: - json['refTable'] = self.ref_table + if self.ref_table_name: + json['refTable'] = self.ref_table_name if self.ref_type != 'strong': json['refType'] = self.ref_type return json def copy(self): - return BaseType(self.type, self.enum.copy(), self.min, self.max, - self.min_length, self.max_length, self.ref_table) + base = BaseType(self.type, self.enum.copy(), self.min, self.max, + self.min_length, self.max_length, self.ref_table_name) + base.ref_table = self.ref_table + return base def is_valid(self): if self.type in (VoidType, BooleanType, UuidType): @@ -237,7 +240,7 @@ class BaseType(object): def has_constraints(self): return (self.enum is not None or self.min is not None or self.max is not None or self.min_length != 0 or self.max_length != sys.maxint or - self.ref_table is not None) + self.ref_table_name is not None) def without_constraints(self): return BaseType(self.type) @@ -249,7 +252,7 @@ class BaseType(object): return Type(BaseType(atomic_type), None, 1, sys.maxint) def is_ref(self): - return self.type == UuidType and self.ref_table is not None + return self.type == UuidType and self.ref_table_name is not None def is_strong_ref(self): return self.is_ref() and self.ref_type == 'strong' @@ -258,8 +261,8 @@ class BaseType(object): return self.is_ref() and self.ref_type == 'weak' def toEnglish(self, escapeLiteral=returnUnchanged): - if self.type == UuidType and self.ref_table: - s = escapeLiteral(self.ref_table) + if self.type == UuidType and self.ref_table_name: + s = escapeLiteral(self.ref_table_name) if self.ref_type == 'weak': s = "weak reference to " + s return s @@ -305,8 +308,8 @@ class BaseType(object): return '' def toCType(self, prefix): - if self.ref_table: - return "struct %s%s *" % (prefix, self.ref_table.lower()) + if self.ref_table_name: + return "struct %s%s *" % (prefix, self.ref_table_name.lower()) else: return {IntegerType: 'int64_t ', RealType: 'double ', @@ -319,7 +322,7 @@ class BaseType(object): def copyCValue(self, dst, src): args = {'dst': dst, 'src': src} - if self.ref_table: + if self.ref_table_name: return ("%(dst)s = %(src)s->header_.uuid;") % args elif self.type == StringType: return "%(dst)s = xstrdup(%(src)s);" % args @@ -327,7 +330,7 @@ class BaseType(object): return "%(dst)s = %(src)s;" % args def initCDefault(self, var, is_optional): - if self.ref_table: + if self.ref_table_name: return "%s = NULL;" % var elif self.type == StringType and not is_optional: return '%s = "";' % var @@ -363,8 +366,8 @@ class BaseType(object): if self.max_length != sys.maxint: stmts.append('%s.u.string.maxLen = %d;' % (var, self.max_length)) elif self.type == UuidType: - if self.ref_table is not None: - stmts.append('%s.u.uuid.refTableName = "%s";' % (var, escapeCString(self.ref_table))) + if self.ref_table_name is not None: + stmts.append('%s.u.uuid.refTableName = "%s";' % (var, escapeCString(self.ref_table_name))) stmts.append('%s.u.uuid.refType = OVSDB_REF_%s;' % (var, self.ref_type.upper())) return '\n'.join([indent + stmt for stmt in stmts]) @@ -420,7 +423,7 @@ class Type(object): def is_optional_pointer(self): return (self.is_optional() and not self.value - and (self.key.type == StringType or self.key.ref_table)) + and (self.key.type == StringType or self.key.ref_table_name)) @staticmethod def __n_from_json(json, default): -- 2.43.0