############################################################################## # # Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE # ############################################################################## import ExtensionClass from Acquisition import Implicit from Record import Record class SQLAlias(ExtensionClass.Base): def __init__(self, name): self._n=name def __of__(self, parent): return getattr(parent, self._n) class NoBrains: pass class Results: """Class for providing a nice interface to DBI result data """ _index=None # We need to allow access to not-explicitly-protected # individual record objects contained in the result. __allow_access_to_unprotected_subobjects__=1 def __init__(self,(items,data),brains=NoBrains, parent=None, zbrains=None): self._data=data self.__items__=items self._parent=parent self._names=names=[] self._schema=schema={} self._data_dictionary=dd={} aliases=[] if zbrains is None: zbrains=NoBrains i=0 for item in items: name=item['name'] name=name.strip() if not name: raise ValueError, 'Empty column name, %s' % name if schema.has_key(name): raise ValueError, 'Duplicate column name, %s' % name schema[name]=i n=name.lower() if n != name: aliases.append((n, SQLAlias(name))) n=name.upper() if n != name: aliases.append((n, SQLAlias(name))) dd[name]=item names.append(name) i=i+1 self._nv=nv=len(names) # Create a record class to hold the records. names=tuple(names) class r(Record, Implicit, brains, zbrains): 'Result record class' r.__record_schema__=schema for k in Record.__dict__.keys(): if k[:2]=='__': setattr(r,k,getattr(Record,k)) # Add SQL Aliases for k, v in aliases: if not hasattr(r, k): setattr(r, k, v) if hasattr(brains, '__init__'): binit=brains.__init__ if hasattr(binit,'im_func'): binit=binit.im_func def __init__(self, data, parent, binit=binit): Record.__init__(self,data) if parent is not None: self=self.__of__(parent) binit(self) setattr(r, '__init__', __init__) self._class=r # OK, we've read meta data, now get line indexes def _searchable_result_columns(self): return self.__items__ def names(self): return self._names def data_dictionary(self): return self._data_dictionary def __len__(self): return len(self._data) def __getitem__(self,index): if index==self._index: return self._row parent=self._parent fields=self._class(self._data[index], parent) if parent is not None: fields=fields.__of__(parent) self._index=index self._row=fields return fields def tuples(self): return map(tuple, self) def dictionaries(self): r=[] a=r.append names=self.names() for row in self: d={} for n in names: d[n]=row[n] a(d) return r def asRDB(self): # Waaaaa r=[] append=r.append strings=[] nstrings=[] items=self.__items__ indexes=range(len(items)) for i in indexes: item=items[i] t=item['type'].lower() if t=='s' or t=='t': t=='t' strings.append(i) else: nstrings.append(i) if item.has_key('width'): append('%s%s' % (item['width'], t)) else: r.append(t) r=['\t'.join(self._names), '\t'.join(r)] append=r.append row=['']*len(items) tostr=str for d in self._data: for i in strings: v=tostr(d[i]) if v: if v.find('\\') > 0: v='\\\\'.join(v.split('\\')) if v.find('\t') > 0: v='\\t'.join(v.split('\t')) if v.find('\n') > 0: v='\\n'.join(v.split('\n')) row[i]=v for i in nstrings: row[i]=tostr(d[i]) append('\t'.join(row)) append('') return '\n'.join(r)