X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=python%2Fovs%2Fdb%2Fschema.py;h=9883adc2d69262d926cae5374489e6502239bb69;hb=42a49b96013c6a149ad0bdd9799b22db59630ae7;hp=e0e0daf5ec60b7bd093c4da8247676cbeadf2fec;hpb=219c9a73dc5bdff5c1350cc1b9cc10e405fefed2;p=sliver-openvswitch.git diff --git a/python/ovs/db/schema.py b/python/ovs/db/schema.py index e0e0daf5e..9883adc2d 100644 --- a/python/ovs/db/schema.py +++ b/python/ovs/db/schema.py @@ -27,13 +27,6 @@ class DbSchema(object): self.version = version self.tables = tables - # Validate that all ref_tables refer to the names of tables - # that exist. - 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") - # "isRoot" was not part of the original schema definition. Before it # was added, there was no support for garbage collection. So, for # backward compatibility, if the root set is empty then assume that @@ -42,6 +35,17 @@ 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. + # + # 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") + def __root_set_size(self): """Returns the number of tables in the schema's root set.""" n_root = 0 @@ -91,12 +95,25 @@ class DbSchema(object): return json def __check_ref_table(self, column, base, base_name): - if (base and base.type == types.UuidType and base.ref_table and - base.ref_table not in self.tables): + if not base or base.type != types.UuidType or not base.ref_table: + return + + ref_table = self.tables.get(base.ref_table) + if not ref_table: raise error.Error("column %s %s refers to undefined table %s" % (column.name, base_name, base.ref_table), tag="syntax error") + if base.is_strong_ref() and not 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 + # deleted, even though it did exist in memory. If there are + # references to that row later in the log (to modify it, to delete + # it, or just to point to it), then this will yield a transaction + # error. + column.persistent = True + class IdlSchema(DbSchema): def __init__(self, name, version, tables, idlPrefix, idlHeader): DbSchema.__init__(self, name, version, tables)