Package gavo :: Package rscdef :: Module group
[frames] | no frames]

Source Code for Module gavo.rscdef.group

  1  """ 
  2  VOTable-style groups for RD tables. 
  3  """ 
  4   
  5  #c Copyright 2008-2019, the GAVO project 
  6  #c 
  7  #c This program is free software, covered by the GNU GPL.  See the 
  8  #c COPYING file in the source distribution. 
  9   
 10   
 11  from gavo import base 
 12  from gavo.base import attrdef 
 13  from gavo.rscdef import column 
 14  from gavo.rscdef import common 
15 16 17 -class TypedReference(base.Structure):
18 """A base class for references to columns and parameters. 19 """ 20 _dest = base.UnicodeAttribute("key", 21 default=base.Undefined, 22 description="The key (i.e., name) of the referenced column or param.", 23 copyable="True", 24 aliases=["dest"]) 25 26 _ucd = base.UnicodeAttribute("ucd", 27 default=None, 28 description="The UCD of the group", 29 copyable=True) 30 31 _utype = base.UnicodeAttribute("utype", 32 default=None, 33 description="A utype for the group", 34 copyable=True) 35
36 - def resolve(self, container):
37 """tries to resolve the reference within container. 38 39 This must be overridden by derived classes. 40 """ 41 raise NotImplementedError("Don't now how to resolve %s references."% 42 self.__class__.__name__)
43
44 45 -class ColumnReference(TypedReference):
46 """A reference from a group to a column within a table. 47 48 ColumnReferences do not support qualified references, i.e., you 49 can only give simple names. 50 """ 51 name_ = "columnRef" 52
53 - def resolve(self, container):
54 return container.getColumnByName(self.key)
55
56 57 -class ParameterReference(TypedReference):
58 """A reference from a group to a parameter within a table. 59 60 ParamReferences do not support qualified references, i.e., you 61 can only give simple names. 62 63 Also note that programmatically, you usually want to resolve 64 ParamReferences within the Table instance, not the table definition. 65 """ 66 name_ = "paramRef" 67
68 - def resolve(self, container):
69 return container.getParamByName(self.key)
70
71 72 -class Group(base.Structure):
73 """A group is a collection of columns, parameters and other groups 74 with a dash of metadata. 75 76 Within a group, you can refer to columns or params of the enclosing table 77 by their names. Nothing outside of the enclosing table can be 78 part of a group. 79 80 Rather than referring to params, you can also embed them into a group; 81 they will then *not* be present in the embedding table. 82 83 Groups may contain groups. 84 85 One application for this is grouping input keys for the form renderer. 86 For such groups, you probably want to give the label property (and 87 possibly cssClass). 88 """ 89 name_ = "group" 90 91 _name = column.ParamNameAttribute("name", 92 default=None, 93 description="Name of the column (must be SQL-valid for onDisk tables)", 94 copyable=True) 95 96 _ucd = base.UnicodeAttribute("ucd", 97 default=None, 98 description="The UCD of the group", 99 copyable=True) 100 101 _description = base.NWUnicodeAttribute("description", 102 default=None, 103 copyable=True, 104 description="A short (one-line) description of the group") 105 106 _utype = base.UnicodeAttribute("utype", 107 default=None, 108 description="A utype for the group", 109 copyable=True) 110 111 _columnRefs = base.StructListAttribute("columnRefs", 112 description="References to table columns belonging to this group", 113 childFactory=ColumnReference, 114 copyable=True) 115 116 _paramRefs = base.StructListAttribute("paramRefs", 117 description="Names of table parameters belonging to this group", 118 childFactory=ParameterReference, 119 copyable=True) 120 121 _params = common.ColumnListAttribute("params", 122 childFactory=column.Param, 123 description="Immediate param elements for this group (use paramref" 124 " to reference params defined in the parent table)", 125 copyable=True) 126 127 _groups = base.StructListAttribute("groups", 128 childFactory=attrdef.Recursive, 129 description="Sub-groups of this group (names are still referenced" 130 " from the enclosing table)", 131 copyable=True, 132 xmlName="group") 133 134 _props = base.PropertyAttribute(copyable=True) 135 136 @property
137 - def table(self):
138 """the table definition this group lives in. 139 140 For nested groups, this still is the ancestor table. 141 """ 142 try: 143 # (re) compute the table we belong to if there's no table cache 144 # or determination has failed so far. 145 if self.__tableCache is None: 146 raise AttributeError 147 except AttributeError: 148 # find something that has columns (presumably a table def) in our 149 # ancestors. I don't want to check for a TableDef instance 150 # since I don't want to import rscdef.table here (circular import) 151 # and things with column and params would work as well. 152 anc = self.parent 153 while anc: 154 if hasattr(anc, "columns"): 155 self.__tableCache = anc 156 break 157 anc = anc.parent 158 else: 159 self.__tableCache = None 160 return self.__tableCache
161
162 - def onParentComplete(self):
163 """checks that param and column names can be found in the parent table. 164 """ 165 # defer validation for sub-groups (parent group will cause validation) 166 if isinstance(self.parent, Group): 167 return 168 # forgo validation if the group doesn't have a table 169 if self.table is None: 170 return 171 172 try: 173 for col in self.iterColumns(): 174 pass 175 for par in self.iterParams(): 176 pass 177 except base.NotFoundError as msg: 178 raise base.StructureError( 179 "No param or field %s in found in table %s"%( 180 msg.what, self.table.id)) 181 182 for group in self.groups: 183 group.onParentComplete()
184
185 - def iterColumns(self):
186 """iterates over columns within this group. 187 """ 188 table = self.table # (self.table is a property) 189 for ref in self.columnRefs: 190 yield ref.resolve(table)
191
192 - def iterParams(self):
193 """iterates over all params within this group. 194 195 This includes both params refereced in the parent table and immediate 196 params. 197 """ 198 table = self.table # (self.table is a property) 199 for ref in self.paramRefs: 200 yield ref.resolve(table) 201 for par in self.params: 202 yield par
203