X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=python%2Fovs%2Fdb%2Fschema.py;h=29fe986a254c56a0f47aa9057914f21d21903d8b;hb=63b1a5213331cd962be05df57f1375db902216c5;hp=9883adc2d69262d926cae5374489e6502239bb69;hpb=42a49b96013c6a149ad0bdd9799b22db59630ae7;p=openvswitch diff --git a/python/ovs/db/schema.py b/python/ovs/db/schema.py index 9883adc2..29fe986a 100644 --- a/python/ovs/db/schema.py +++ b/python/ovs/db/schema.py @@ -19,6 +19,12 @@ from ovs.db import error import ovs.db.parser from ovs.db import types +def _check_id(name, json): + if name.startswith('_'): + raise error.Error('names beginning with "_" are reserved', json) + elif not ovs.db.parser.is_identifier(name): + raise error.Error("name must be a valid id", json) + class DbSchema(object): """Schema for an OVSDB database.""" @@ -65,16 +71,12 @@ class DbSchema(object): if (version is not None and not re.match('[0-9]+\.[0-9]+\.[0-9]+$', version)): - raise error.Error("schema version \"%s\" not in format x.y.z" + raise error.Error('schema version "%s" not in format x.y.z' % version) tables = {} for tableName, tableJson in tablesJson.iteritems(): - if tableName.startswith('_'): - raise error.Error("names beginning with \"_\" are reserved", - json) - elif not ovs.db.parser.is_identifier(tableName): - raise error.Error("name must be a valid id", json) + _check_id(tableName, json) tables[tableName] = TableSchema.from_json(tableJson, tableName) return DbSchema(name, version, tables) @@ -134,22 +136,42 @@ class IdlSchema(DbSchema): return IdlSchema(schema.name, schema.version, schema.tables, idlPrefix, idlHeader) +def column_set_from_json(json, columns): + if json is None: + return tuple(columns) + elif type(json) != list: + raise error.Error("array of distinct column names expected", json) + else: + for column_name in json: + if type(column_name) not in [str, unicode]: + raise error.Error("array of distinct column names expected", + json) + elif column_name not in columns: + raise error.Error("%s is not a valid column name" + % column_name, json) + if len(set(json)) != len(json): + # Duplicate. + raise error.Error("array of distinct column names expected", json) + return tuple([columns[column_name] for column_name in json]) + class TableSchema(object): def __init__(self, name, columns, mutable=True, max_rows=sys.maxint, - is_root=True): + is_root=True, indexes=[]): self.name = name self.columns = columns self.mutable = mutable self.max_rows = max_rows self.is_root = is_root + self.indexes = indexes @staticmethod def from_json(json, name): parser = ovs.db.parser.Parser(json, "table schema for table %s" % name) - columnsJson = parser.get("columns", [dict]) + columns_json = parser.get("columns", [dict]) mutable = parser.get_optional("mutable", [bool], True) max_rows = parser.get_optional("maxRows", [int]) is_root = parser.get_optional("isRoot", [bool], False) + indexes_json = parser.get_optional("indexes", [list], []) parser.finish() if max_rows == None: @@ -157,20 +179,29 @@ class TableSchema(object): elif max_rows <= 0: raise error.Error("maxRows must be at least 1", json) - if not columnsJson: + if not columns_json: raise error.Error("table must have at least one column", json) columns = {} - for columnName, columnJson in columnsJson.iteritems(): - if columnName.startswith('_'): - raise error.Error("names beginning with \"_\" are reserved", - json) - elif not ovs.db.parser.is_identifier(columnName): - raise error.Error("name must be a valid id", json) - columns[columnName] = ColumnSchema.from_json(columnJson, - columnName) - - return TableSchema(name, columns, mutable, max_rows, is_root) + for column_name, column_json in columns_json.iteritems(): + _check_id(column_name, json) + columns[column_name] = ColumnSchema.from_json(column_json, + column_name) + + indexes = [] + for index_json in indexes_json: + index = column_set_from_json(index_json, columns) + if not index: + raise error.Error("index must have at least one column", json) + elif len(index) == 1: + index[0].unique = True + for column in index: + if not column.persistent: + raise error.Error("ephemeral columns (such as %s) may " + "not be indexed" % column.name, json) + indexes.append(index) + + return TableSchema(name, columns, mutable, max_rows, is_root, indexes) def to_json(self, default_is_root=False): """Returns this table schema serialized into JSON. @@ -198,14 +229,20 @@ class TableSchema(object): if self.max_rows != sys.maxint: json["maxRows"] = self.max_rows + if self.indexes: + json["indexes"] = [] + for index in self.indexes: + json["indexes"].append([column.name for column in index]) + return json class ColumnSchema(object): - def __init__(self, name, mutable, persistent, type): + def __init__(self, name, mutable, persistent, type_): self.name = name self.mutable = mutable self.persistent = persistent - self.type = type + self.type = type_ + self.unique = False @staticmethod def from_json(json, name):