1 """
2 Output tables and their components.
3 """
4
5
6
7
8
9
10
11 import fnmatch
12
13 from gavo import base
14 from gavo import rscdef
15 from gavo import utils
16
17 _EMPTY_TABLE = base.makeStruct(rscdef.TableDef, id="<builtin empty table>")
18 _EMPTY_TABLE.getFullId = lambda: None
22 """A column for defining the output of a service.
23
24 It adds some attributes useful for rendering results, plus functionality
25 specific to certain cores.
26
27 The optional formatter overrides the standard formatting code in HTML
28 (which is based on units, ucds, and displayHints). You receive
29 the item from the database as data and must return a string or
30 nevow stan. In addition to the standard `Functions available for
31 row makers`_ you have queryMeta and nevow's tags in T.
32
33 Here's an example for generating a link to another service using this
34 facility::
35
36 <outputField name="more"
37 select="array[centerAlpha,centerDelta] as more" tablehead="More"
38 description="More exposures near the center of this plate">
39 <formatter><![CDATA[
40 return T.a(href=base.makeSitePath("/lswscans/res/positions/q/form?"
41 "POS=%s,%s&SIZE=1&INTERSECT=OVERLAPS&cutoutSize=0.5"
42 "&__nevow_form__=genForm"%tuple(data)
43 ))["More"] ]]>
44 </formatter>
45 </outputField>
46
47 Within the code, in addition do data, you see rd and queryMeta.
48 """
49 name_ = "outputField"
50
51
52 _formatter = base.UnicodeAttribute("formatter", description="Function"
53 " body to render this item to HTML.", copyable=True, expand=True)
54 _wantsRow = base.BooleanAttribute("wantsRow", description="Does"
55 " formatter expect the entire row rather than the colum value only?",
56 copyable="True")
57 _select = base.UnicodeAttribute("select", description="Use this SQL"
58 " fragment rather than field name in the select list of a DB based"
59 " core.", default=base.Undefined, copyable=True, expand=True)
60 _sets = base.StringSetAttribute("sets", description=
61 "Output sets this field should be included in; ALL includes the field"
62 " in all output sets.",
63 copyable=True)
64
66 return "<OutputField %s>"%repr(self.name)
67
77
78 @classmethod
84
85 - def expand(self, *args, **kwargs):
87
90 """A table that has outputFields for columns.
91
92 Cores always have one of these, but they are implicitly defined by
93 the underlying database tables in case of dbCores and such.
94
95 Services may define output tables to modify what is coming back fromt
96 the core. Note that this usually only affects the output to web browsers.
97 To use the output table also through VO protocols (and when producing
98 VOTables, FITS files, and the like), you need to set the service's
99 votableRespectsOutputTable property to True.
100 """
101 name_ = "outputTable"
102
103
104
105
106
107 metaModel = None
108
109 _cols = rscdef.ColumnListAttribute("columns",
110 childFactory=OutputField,
111 description="Output fields for this table.",
112 aliases=["column"],
113 copyable=True)
114
115 _verbLevel = base.IntAttribute("verbLevel",
116 default=None,
117 description="Copy over columns from fromTable not"
118 " more verbose than this.")
119
120 _autocols = base.StringListAttribute("autoCols",
121 description="Column names obtained from fromTable; you can use"
122 " shell patterns into the output table's parent table (in a table"
123 " core, that's the queried table; in a service, it's the core's"
124 " output table) here.")
125
127 rscdef.TableDef.__init__(self, parent, **kwargs)
128 self.parentTable = None
129 try:
130
131 self.parentTable = self.parent.queriedTable
132 except (AttributeError, base.StructureError):
133
134 pass
135
136 if not self.parentTable:
137 try:
138
139 self.parentTable = self.parent.core.outputTable
140 except (AttributeError, base.StructureError):
141
142 pass
143
144 if not self.parentTable:
145
146 self.parentTable = _EMPTY_TABLE
147
148 self.namePath = None
149
157
159
160
161 if ctx is None:
162 raise base.StructureError("outputTable autocols is"
163 " only available with a parse context")
164 for name in names:
165 self._addName(ctx, name)
166
168 """adopts a param or column name into the outputTable.
169
170 name may be a reference or a param or column name in the parent
171 table (as determined in the constructor, i.e., the queried table
172 of a core or the output table of a service's core.
173
174 You can also use shell patterns into parent columns.
175 """
176 if utils.identifierPattern.match(name):
177 refOb = ctx.resolveId(name, self)
178 if refOb.name_=="param":
179 self.feedObject("param", refOb.copy(self))
180 else:
181 self._adoptColumn(refOb)
182
183 else:
184
185 for col in self.parentTable:
186 if fnmatch.fnmatch(col.name, name):
187 self._adoptColumn(col)
188
190 if self.autoCols:
191 self._addNames(ctx, self.autoCols)
192
193 if self.verbLevel:
194 table = self.parentTable
195 for col in table.columns:
196 if col.verbLevel<=self.verbLevel:
197 self._adoptColumn(col)
198 for par in table.params:
199 if par.verbLevel<=self.verbLevel:
200 self.feedObject("param", par.copy(self))
201
202 self._completeElementNext(OutputTableDef, ctx)
203
204 @classmethod
208
209 @classmethod
211 res = cls(None, columns=[OutputField.fromColumn(c) for c in tableDef],
212 forceUnique=tableDef.forceUnique, dupePolicy=tableDef.dupePolicy,
213 primary=tableDef.primary, params=tableDef.params).finishElement(ctx)
214 res.copyMetaFrom(tableDef)
215 return res
216