1 # Copyright (c) 2009, 2010 Nicira Networks
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at:
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
18 from ovs.db import error
20 from ovs.db import types
22 class DbSchema(object):
23 """Schema for an OVSDB database."""
25 def __init__(self, name, version, tables):
27 self.version = version
30 # Validate that all ref_tables refer to the names of tables
32 for table in self.tables.itervalues():
33 for column in table.columns.itervalues():
34 self.__check_ref_table(column, column.type.key, "key")
35 self.__check_ref_table(column, column.type.value, "value")
39 parser = ovs.db.parser.Parser(json, "database schema")
40 name = parser.get("name", ['id'])
41 version = parser.get_optional("version", [unicode])
42 parser.get_optional("cksum", [unicode])
43 tablesJson = parser.get("tables", [dict])
46 if (version is not None and
47 not re.match('[0-9]+\.[0-9]+\.[0-9]+$', version)):
48 raise error.Error("schema version \"%s\" not in format x.y.z"
52 for tableName, tableJson in tablesJson.iteritems():
53 if tableName.startswith('_'):
54 raise error.Error("names beginning with \"_\" are reserved",
56 elif not ovs.db.parser.is_identifier(tableName):
57 raise error.Error("name must be a valid id", json)
58 tables[tableName] = TableSchema.from_json(tableJson, tableName)
60 return DbSchema(name, version, tables)
64 for table in self.tables.itervalues():
65 tables[table.name] = table.to_json()
66 json = {"name": self.name, "tables": tables}
68 json["version"] = self.version
71 def __check_ref_table(self, column, base, base_name):
72 if (base and base.type == types.UuidType and base.ref_table and
73 base.ref_table not in self.tables):
74 raise error.Error("column %s %s refers to undefined table %s"
75 % (column.name, base_name, base.ref_table),
78 class IdlSchema(DbSchema):
79 def __init__(self, name, version, tables, idlPrefix, idlHeader):
80 DbSchema.__init__(self, name, version, tables)
81 self.idlPrefix = idlPrefix
82 self.idlHeader = idlHeader
86 parser = ovs.db.parser.Parser(json, "IDL schema")
87 idlPrefix = parser.get("idlPrefix", [unicode])
88 idlHeader = parser.get("idlHeader", [unicode])
91 del subjson["idlPrefix"]
92 del subjson["idlHeader"]
93 schema = DbSchema.from_json(subjson)
95 return IdlSchema(schema.name, schema.version, schema.tables,
98 class TableSchema(object):
99 def __init__(self, name, columns, mutable=True, max_rows=sys.maxint):
101 self.columns = columns
102 self.mutable = mutable
103 self.max_rows = max_rows
106 def from_json(json, name):
107 parser = ovs.db.parser.Parser(json, "table schema for table %s" % name)
108 columnsJson = parser.get("columns", [dict])
109 mutable = parser.get_optional("mutable", [bool], True)
110 max_rows = parser.get_optional("maxRows", [int])
114 max_rows = sys.maxint
116 raise error.Error("maxRows must be at least 1", json)
119 raise error.Error("table must have at least one column", json)
122 for columnName, columnJson in columnsJson.iteritems():
123 if columnName.startswith('_'):
124 raise error.Error("names beginning with \"_\" are reserved",
126 elif not ovs.db.parser.is_identifier(columnName):
127 raise error.Error("name must be a valid id", json)
128 columns[columnName] = ColumnSchema.from_json(columnJson,
131 return TableSchema(name, columns, mutable, max_rows)
136 json["mutable"] = False
138 json["columns"] = columns = {}
139 for column in self.columns.itervalues():
140 if not column.name.startswith("_"):
141 columns[column.name] = column.to_json()
143 if self.max_rows != sys.maxint:
144 json["maxRows"] = self.max_rows
148 class ColumnSchema(object):
149 def __init__(self, name, mutable, persistent, type):
151 self.mutable = mutable
152 self.persistent = persistent
156 def from_json(json, name):
157 parser = ovs.db.parser.Parser(json, "schema for column %s" % name)
158 mutable = parser.get_optional("mutable", [bool], True)
159 ephemeral = parser.get_optional("ephemeral", [bool], False)
160 type = types.Type.from_json(parser.get("type", [dict, unicode]))
163 return ColumnSchema(name, mutable, not ephemeral, type)
166 json = {"type": self.type.to_json()}
168 json["mutable"] = False
169 if not self.persistent:
170 json["ephemeral"] = True