ovs.db.types: Add table reference to ovs.db.types.BaseType.
authorBen Pfaff <blp@nicira.com>
Tue, 20 Sep 2011 18:24:44 +0000 (11:24 -0700)
committerBen Pfaff <blp@nicira.com>
Fri, 23 Sep 2011 16:10:45 +0000 (09:10 -0700)
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
ovsdb/ovsdb-dot.in
ovsdb/ovsdb-idlc.in
python/ovs/db/schema.py
python/ovs/db/types.py

index 019da23..b9a4126 100755 (executable)
@@ -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)
index 30da1cb..85c126d 100755 (executable)
@@ -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):
index e5c8183..3392c35 100755 (executable)
@@ -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:
index 1c474a8..7e18564 100644 (file)
@@ -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
index 72ab410..f313186 100644 (file)
@@ -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):