class Index(validation.Validated): """Individual index definition. Order of the properties determines a given index's sort priority. Attributes: kind: Datastore kind that index belongs to. ancestors: Include ancestors in index. properties: Properties to be included. """ ATTRIBUTES = { 'kind': validation.Type(str, convert=False), 'ancestor': validation.Type(bool, convert=False, default=False), 'properties': validation.Optional(validation.Repeated(Property)), } def CheckInitialized(self): self._Normalize() super(Index, self).CheckInitialized() def _Normalize(self): if self.properties is None: return is_geo = any(x.mode == 'geospatial' for x in self.properties) for prop in self.properties: if is_geo: if prop.direction is not None: raise validation.ValidationError( 'direction not supported in a geospatial index') else: # Normalize the property object by making direction explicit if prop.IsAscending(): prop.direction = 'asc'
class Property(validation.Validated): """Representation for a property of an index as it appears in YAML. Attributes (all in string form): name: Name of attribute to sort by. direction: Direction of sort. mode: How the property is indexed. Either 'geospatial' or None (unspecified). """ ATTRIBUTES = { 'name': validation.Type(str, convert=False), 'direction': validation.Optional([('asc', ('ascending', )), ('desc', ('descending', ))]), 'mode': validation.Optional(['geospatial']) } def IsAscending(self): # TODO(user): raise an internal consistency assertion failure # if this Property has a "mode" (or actually if *any* Property in # the containing Index has a "mode"), because in that case it doesn't # make sense to ask for the direction. # # TODO(user): shouldn't we also check for 'descending' here? return self.direction != 'desc' def CheckInitialized(self): if self.direction is not None and self.mode is not None: raise validation.ValidationError( 'direction and mode are mutually exclusive') super(Property, self).CheckInitialized()