Package gavo :: Package votable :: Module tablewriter
[frames] | no frames]

Source Code for Module gavo.votable.tablewriter

  1  """ 
  2  Writing tabular data within VOTables. 
  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 cStringIO import StringIO 
 12   
 13  from gavo import utils 
 14  from gavo.utils import stanxml 
 15  from gavo.votable import coding 
 16  from gavo.votable import common 
 17  from gavo.votable import enc_binary 
 18  from gavo.votable import enc_binary2 
 19  from gavo.votable import enc_tabledata 
 20  from gavo.votable.model import VOTable 
 21   
 22  _encoders = { 
 23          VOTable.TABLEDATA: enc_tabledata, 
 24          VOTable.BINARY: enc_binary, 
 25          VOTable.BINARY2: enc_binary2, 
 26  } 
 27   
 28   
29 -def write(root, outputFile, xmlDecl=True):
30 """writes a VOTable to outputFile. 31 32 This is a compatiblity function that's in this place mainly for historical 33 reasons. It's basically stanxml.write, except that the prefix of the root 34 element will be the empty prefix. 35 """ 36 return stanxml.write(root, outputFile, xmlDecl=xmlDecl, 37 prefixForEmpty=root._prefix)
38 39
40 -def asString(root, xmlDecl=False):
41 """returns the V.VOTABLE root as a string. 42 """ 43 res = StringIO() 44 try: 45 write(root, res, xmlDecl=xmlDecl) 46 except Exception: 47 # something bad happened while generating the VOTable. We probably 48 # have unwound the element stack and left an error INFO, so probably 49 # the document is all right. Let's return it, but try to report an 50 # error anyway if there's the infrastructure to do that 51 utils.sendUIEvent("Error", "Exception during VOTable write (delivering" 52 " the document anyway)") 53 return res.getvalue()
54 55
56 -class OverflowElement(stanxml.Stub):
57 """A container for VOTable elements that are written when it is 58 likely that a query has overflowed the limit. 59 60 This is for use with DelayedTable. Instances of this can be 61 passed into overflowElement. 62 63 OverflowElements are constructed with the row limit and VOTable 64 material to be inserted when exactly row limit (or more) rows 65 have been written to the table. 66 67 All automatic namespace processing is turned off for the overflow 68 element. This should not be a problem if you're embedding VOTable 69 elements into VOTables. 70 """
71 - def __init__(self, rowLimit, overflowStan):
72 self.rowLimit, self.overflowStan = rowLimit, overflowStan 73 self.rowsDelivered = None 74 # disable namespace generation for write (ugly; fix this when 75 # we've improved XML generation in xmlstan) 76 self.overflowStan._fixedTagMaterial = ""
77
78 - def __repr__(self):
79 return "<Uninstanciated Overflow Warning>"
80
81 - def setRowsDelivered(self, numRows):
82 self.rowsDelivered = numRows
83
84 - def write(self, outputFile):
85 if self.rowLimit<=self.rowsDelivered: 86 write(self.overflowStan, outputFile, xmlDecl=False)
87 88
89 -def DelayedTable(tableDefinition, rowIterator, contentElement, 90 overflowElement=None, **attrs):
91 """returns tableDefinition such that when serialized, it contains 92 the data from rowIterator 93 94 rowIterator is an iterator yielding all rows from the table to be encoded, 95 tableDefinition is the TABLE element, and ContentElement is one of the 96 permitted DATA children from VOTable. 97 98 See the OverflowElement class for overflowElement. 99 100 attrs are optional attributes to the content element. 101 """ 102 if contentElement not in _encoders: 103 raise common.VOTableError("Unsupported content element %s"%contentElement, 104 hint="Try something like TABLEDATA or BINARY") 105 encodeRow = coding.buildEncoder(tableDefinition, _encoders[contentElement]) 106 107 def iterSerialized(): 108 numRows = 0 109 for row in rowIterator: 110 numRows += 1 111 yield encodeRow(row) 112 if overflowElement is not None: 113 overflowElement.setRowsDelivered(numRows)
114 115 content = contentElement(**attrs) 116 content.text_ = "Placeholder for real data" 117 content.iterSerialized = iterSerialized 118 119 return tableDefinition[ 120 VOTable.DATA[content]] 121 # In a way, we'd like to have an overflow element here, assuming that 122 # the table comes from a db query. We could have that writing: 123 # overflowElement] 124 # -- but TAP wants the overflow at the resource level. So, we 125 # put it there. It will reflect the state of affairs for the last 126 # table (which is probably as good as anything else). 127