Shared/DC/ZRDB/Aqueduct.py100666 0 0 40641 7335721660 16011 0ustar00unknownunknown 0 0 7############################################################################## # # Zope Public License (ZPL) Version 1.0 # ------------------------------------- # # Copyright (c) Digital Creations. All rights reserved. # # This license has been certified as Open Source(tm). # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions in source code must retain the above copyright # notice, this list of conditions, and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions, and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # 3. Digital Creations requests that attribution be given to Zope # in any manner possible. Zope includes a "Powered by Zope" # button that is installed by default. While it is not a license # violation to remove this button, it is requested that the # attribution remain. A significant investment has been put # into Zope, and this effort will continue if the Zope community # continues to grow. This is one way to assure that growth. # # 4. All advertising materials and documentation mentioning # features derived from or use of this software must display # the following acknowledgement: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # In the event that the product being advertised includes an # intact Zope distribution (with copyright and license included) # then this clause is waived. # # 5. Names associated with Zope or Digital Creations must not be used to # endorse or promote products derived from this software without # prior written permission from Digital Creations. # # 6. Modified redistributions of any form whatsoever must retain # the following acknowledgment: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # Intact (re-)distributions of any official Zope release do not # require an external acknowledgement. # # 7. Modifications are encouraged but must be packaged separately as # patches to official Zope releases. Distributions that do not # clearly separate the patches from the original work must be clearly # labeled as unofficial distributions. Modifications which do not # carry the name Zope may be packaged in any form, as long as they # conform to all of the clauses above. # # # Disclaimer # # THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # # This software consists of contributions made by Digital Creations and # many individuals on behalf of Digital Creations. Specific # attributions are listed in the accompanying credits file. # ############################################################################## __doc__='''Shared classes and functions $Id: Aqueduct.py,v 1.49.4.3 2001/08/13 14:53:51 andreasjung Exp $''' __version__='$Revision: 1.49.4.3 $'[11:-2] import Globals, os from Globals import Persistent import DocumentTemplate, DateTime, re, string import binascii, Acquisition DateTime.now=DateTime.DateTime from cStringIO import StringIO from OFS import SimpleItem from AccessControl.Role import RoleManager from DocumentTemplate import HTML from string import strip, replace dtml_dir=os.path.join(Globals.package_home(globals()), 'dtml') InvalidParameter='Invalid Parameter' class BaseQuery(Persistent, SimpleItem.Item, Acquisition.Implicit, RoleManager): def query_year(self): return self.query_date.year() def query_month(self): return self.query_date.month() def query_day(self): return self.query_date.day() query_date=DateTime.now() manage_options=() def quoted_input(self): return quotedHTML(self.input_src) def quoted_report(self): return quotedHTML(self.report_src) MissingArgumentError='Bad Request' def _convert(self): self._arg=parse(self.arguments_src) def _argdata(self, REQUEST): r={} try: args=self._arg except: self._convert() args=self._arg id=self.id missing=[] for name in args.keys(): idname="%s/%s" % (id, name) try: r[name]=REQUEST[idname] except: try: r[name]=REQUEST[name] except: arg=args[name] try: r[name]=arg['default'] except: try: if not arg['optional']: missing.append(name) except: missing.append(name) # Note: the code above tries to check if an argument of the # ZSQL method above has the "optional" flag set (in case the # argument is omitted from the ZSQL function call). But there # is neither corresponding code inside the parse() function to # check for the "optional" parameter nor any documentation. # So we omit the check for the optional parameter. There will # be probably no code break but there will be hopefully more code # to work as supposed to work. # if missing: # raise self.MissingArgumentError, \ # "The following arguments were omitted " \ # " from the ZSQL method call: %s" % str(missing) # return r _col=None _arg={} class Searchable(BaseQuery): def _searchable_arguments(self): try: return self._arg except: self._convert() return self._arg def _searchable_result_columns(self): return self._col def manage_testForm(self, REQUEST): """Provide testing interface""" input_src=default_input_form(self.title_or_id(), self._searchable_arguments(), 'manage_test') return HTML(input_src)(self, REQUEST) def manage_test(self, REQUEST): 'Perform an actual query' result=self(REQUEST) report=HTML(custom_default_report(self.id, result)) return apply(report,(self,REQUEST),{self.id:result}) def index_html(self, URL1): " " raise 'Redirect', ("%s/manage_testForm" % URL1) class Composite: def _getquery(self,id): o=self i=0 while 1: __traceback_info__=o q=getattr(o,id) try: if hasattr(q,'_searchable_arguments'): try: q=q.__of__(self.aq_parent) except: pass return q except: pass if i > 100: raise AttributeError, id i=i+1 o=o.aq_parent def myQueryIds(self): return map( lambda k, queries=self.queries: {'id': k, 'selected': k in queries}, self.ZQueryIds()) def default_input_form(id,arguments,action='query', tabs=''): if arguments: items=arguments.items() return ( "%s\n%s%s" % ( '\n' '%s Input Data\n' '\n%s\n' '
\n' '

%s Input Data

\n' 'Enter query parameters:
' '\n' % (id, tabs, action,id), string.joinfields( map( lambda a: ('\n' ' ' % (nicify(a[0]), ( a[1].has_key('type') and ("%s:%s" % (a[0],a[1]['type'])) or a[0] ), a[1].has_key('default') and a[1]['default'] or '' )) , items ), '\n'), '\n\n
%s' '
\n' '\n' '\n' ' \n' ' \n' '\n' '
\n
\n\n\n' ) ) else: return ( '\n' '%s Input Data\n' '\n%s\n' '
\n' '

%s Input Data

\n' 'This query requires no input.

\n' '\n' '\n' ' \n' ' \n' '\n' '\n\n

\n\n\n' % (id, tabs, action, id) ) custom_default_report_src=DocumentTemplate.File( os.path.join(dtml_dir,'customDefaultReport.dtml')) def custom_default_report(id, result, action='', no_table=0, goofy=re.compile('\W').search ): columns=result._searchable_result_columns() __traceback_info__=columns heading=('\n%s ' % string.joinfields( map(lambda c: ' %s\n' % nicify(c['name']), columns), '' ) ) if no_table: tr, _tr, td, _td, delim = '

', '

', '', '', ',\n' else: tr, _tr, td, _td, delim = '', '', '', '', '\n' row=[] for c in columns: n=c['name'] if goofy(n) is not None: n='expr="_[\'%s]"' % (`'"'+n`[2:]) row.append(' %s%s' % (td,n,c['type']!='s' and ' null=""' or '',_td)) row=(' %s\n%s\n %s' % (tr,string.joinfields(row,delim), _tr)) return custom_default_report_src( id=id,heading=heading,row=row,action=action,no_table=no_table) def detypify(arg): l=string.find(arg,':') if l > 0: arg=arg[:l] return arg def decode(input,output): while 1: line = input.readline() if not line: break s = binascii.a2b_base64(line[:-1]) output.write(s) def decodestring(s): f = StringIO(s) g = StringIO() decode(f, g) return g.getvalue() class Args: def __init__(self, data, keys): self._data=data self._keys=keys def items(self): return map(lambda k, d=self._data: (k,d[k]), self._keys) def values(self): return map(lambda k, d=self._data: d[k], self._keys) def keys(self): return list(self._keys) def has_key(self, key): return self._data.has_key(key) def __getitem__(self, key): return self._data[key] def __setitem__(self, key, v): self._data[key]=v def __delitem__(self, key): del self._data[key] def __len__(self): return len(self._data) def parse(text, result=None, keys=None, unparmre=re.compile( r'([\000- ]*([^\000- ="]+))'), parmre=re.compile( r'([\000- ]*([^\000- ="]+)=([^\000- ="]+))'), qparmre=re.compile( r'([\000- ]*([^\000- ="]+)="([^"]*)")'), ): if result is None: result = {} keys = [] __traceback_info__=text mo = parmre.match(text) if mo: name = mo.group(2) value = {'default':mo.group(3)} l = len(mo.group(1)) else: mo = qparmre.match(text) if mo: name = mo.group(2) value = {'default':mo.group(3)} l = len(mo.group(1)) else: mo = unparmre.match(text) if mo: name = mo.group(2) value = {} l = len(mo.group(1)) else: if not text or not text.strip(): return Args(result,keys) raise InvalidParameter, text lt=name.find(':') if lt > 0: value['type']=name[lt+1:] name=name[:lt] result[name]=value keys.append(name) return parse(text[l:],result,keys) def quotedHTML(text, character_entities=( ('&', '&'), ("<", '<' ), (">", '>' ), ('"', '"'))): #" for re,name in character_entities: text=replace(text,re,name) return text def nicify(name): name=replace(string.strip(name), '_',' ') return string.upper(name[:1])+name[1:] def decapitate(html, RESPONSE=None, header_re=re.compile( r'((' r'[^\000- <>:]+:[^\n]*\n' r'|' r'[ \011]+[^\000- ][^\n]*\n' r')+)[ \t]*\n([\000-\377]+)' ), # please kill me now space_re=re.compile(r'([ \t]+)'), name_re=re.compile(r'([^\000- <>:]+):([^\n]*)'), ): mo = header_re.match(html) if mo is None: return html headers, html = mo.group(1,3) headers=string.split(headers,'\n') i=1 while i < len(headers): if not headers[i]: del headers[i] else: mo = space_re.match(headers[i]) if mo: headers[i-1]="%s %s" % (headers[i-1], headers[i][len(mo.group(1)):]) del headers[i] else: i=i+1 for i in range(len(headers)): mo = name_re.match(headers[i]) if mo: k,v = mo.group(1,2) v=string.strip(v) else: raise ValueError, 'Invalid Header (%d): %s ' % (i,headers[i]) RESPONSE.setHeader(k,v) return html def delimited_output(results,REQUEST,RESPONSE): delim=REQUEST['output-delimiter'] try: output_type=REQUEST['output-type'] except: output_type='text/plain' RESPONSE.setHeader('content-type', output_type) join=string.join return "%s\n%s\n" % ( join(results.names(),delim), join(map(lambda row, delim=delim, join=join: join(map(str,row),delim), results), '\n') ) Shared/DC/ZRDB/Connection.py100666 0 0 22755 7227567252 16350 0ustar00unknownunknown 0 0 ############################################################################## # # Zope Public License (ZPL) Version 1.0 # ------------------------------------- # # Copyright (c) Digital Creations. All rights reserved. # # This license has been certified as Open Source(tm). # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions in source code must retain the above copyright # notice, this list of conditions, and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions, and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # 3. Digital Creations requests that attribution be given to Zope # in any manner possible. Zope includes a "Powered by Zope" # button that is installed by default. While it is not a license # violation to remove this button, it is requested that the # attribution remain. A significant investment has been put # into Zope, and this effort will continue if the Zope community # continues to grow. This is one way to assure that growth. # # 4. All advertising materials and documentation mentioning # features derived from or use of this software must display # the following acknowledgement: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # In the event that the product being advertised includes an # intact Zope distribution (with copyright and license included) # then this clause is waived. # # 5. Names associated with Zope or Digital Creations must not be used to # endorse or promote products derived from this software without # prior written permission from Digital Creations. # # 6. Modified redistributions of any form whatsoever must retain # the following acknowledgment: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # Intact (re-)distributions of any official Zope release do not # require an external acknowledgement. # # 7. Modifications are encouraged but must be packaged separately as # patches to official Zope releases. Distributions that do not # clearly separate the patches from the original work must be clearly # labeled as unofficial distributions. Modifications which do not # carry the name Zope may be packaged in any form, as long as they # conform to all of the clauses above. # # # Disclaimer # # THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # # This software consists of contributions made by Digital Creations and # many individuals on behalf of Digital Creations. Specific # attributions are listed in the accompanying credits file. # ############################################################################## __doc__='''Generic Database Connection Support $Id: Connection.py,v 1.33 2001/01/12 16:46:50 chrism Exp $''' __version__='$Revision: 1.33 $'[11:-2] import Globals, OFS.SimpleItem, AccessControl.Role, Acquisition, sys from DateTime import DateTime from App.Dialogs import MessageDialog from Globals import DTMLFile from string import find, join, split from Aqueduct import custom_default_report from cStringIO import StringIO from Results import Results import DocumentTemplate, RDB class Connection( Globals.Persistent, AccessControl.Role.RoleManager, OFS.SimpleItem.Item, Acquisition.Implicit, ): # Specify definitions for tabs: manage_options=( ( {'label':'Status', 'action':'manage_main'}, {'label':'Properties', 'action':'manage_properties'}, {'label':'Test', 'action':'manage_testForm'}, ) +AccessControl.Role.RoleManager.manage_options +OFS.SimpleItem.Item.manage_options ) # Specify how individual operations add up to "permissions": __ac_permissions__=( ('View management screens', ('manage_main',)), ('Change Database Connections', ('manage_edit',)), ('Test Database Connections', ('manage_testForm','manage_test')), ('Open/Close Database Connection', ('manage_open_connection', 'manage_close_connection')), ) _v_connected='' connection_string='' def __init__(self, id, title, connection_string, check=None): self.id=str(id) self.edit(title, connection_string, check) def __setstate__(self, state): Globals.Persistent.__setstate__(self, state) if self.connection_string: try: self.connect(self.connection_string) except: pass def title_and_id(self): s=Connection.inheritedAttribute('title_and_id')(self) if hasattr(self, '_v_connected') and self._v_connected: s="%s, which is connected" % s else: s="%s, which is not connected" % s return s def title_or_id(self): s=Connection.inheritedAttribute('title_or_id')(self) if hasattr(self, '_v_connected') and self._v_connected: s="%s (connected)" % s else: s="%s ( not connected)" % s return s def connected(self): return self._v_connected def edit(self, title, connection_string, check=1): self.title=title self.connection_string=connection_string if check: self.connect(connection_string) manage_properties=DTMLFile('dtml/connectionEdit', globals()) def manage_edit(self, title, connection_string, check=None, REQUEST=None): """Change connection """ self.edit(title, connection_string, check) if REQUEST is not None: return MessageDialog( title='Edited', message='%s has been edited.' % self.id, action ='./manage_main', ) manage_testForm=DTMLFile('dtml/connectionTestForm', globals()) def manage_test(self, query, REQUEST=None): "Executes the SQL in parameter 'query' and returns results" dbc=self() #get our connection res=dbc.query(query) if type(res) is type(''): f=StringIO() f.write(res) f.seek(0) result=RDB.File(f) else: result=Results(res) if REQUEST is None: return result #return unadulterated result objects if result._searchable_result_columns(): r=custom_default_report(self.id, result) else: r='This statement returned no results.' report=DocumentTemplate.HTML( '\n' '\n
\n%s\n\n' '

SQL Used:
\n
\n%s\n
\n
\n' '' % (r, query)) report=apply(report,(self,REQUEST),{self.id:result}) return report manage_main=DTMLFile('dtml/connectionStatus', globals()) def manage_close_connection(self, REQUEST): " " try: self._v_database_connection.close() except: pass self._v_connected='' return self.manage_main(self, REQUEST) def manage_open_connection(self, REQUEST=None): " " self.connect(self.connection_string) return self.manage_main(self, REQUEST) def __call__(self, v=None): try: return self._v_database_connection except AttributeError: s=self.connection_string if s: self.connect(s) return self._v_database_connection raise 'Database Not Connected',( '''The database connection is not connected''') def connect(self,s): try: self._v_database_connection.close() except: pass self._v_connected='' DB=self.factory() try: try: self._v_database_connection=DB(s) except: t, v, tb = sys.exc_info() raise 'BadRequest', ( 'Invalid connection string: %s
\n' '\n' % (s,t,v)), tb finally: tb=None self._v_connected=DateTime() return self def sql_quote__(self, v): if find(v,"\'") >= 0: v=join(split(v,"\'"),"''") return "'%s'" % v Shared/DC/ZRDB/DA.py100666 0 0 57630 7360054424 14523 0ustar00unknownunknown 0 0 ############################################################################## # # Zope Public License (ZPL) Version 1.0 # ------------------------------------- # # Copyright (c) Digital Creations. All rights reserved. # # This license has been certified as Open Source(tm). # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions in source code must retain the above copyright # notice, this list of conditions, and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions, and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # 3. Digital Creations requests that attribution be given to Zope # in any manner possible. Zope includes a "Powered by Zope" # button that is installed by default. While it is not a license # violation to remove this button, it is requested that the # attribution remain. A significant investment has been put # into Zope, and this effort will continue if the Zope community # continues to grow. This is one way to assure that growth. # # 4. All advertising materials and documentation mentioning # features derived from or use of this software must display # the following acknowledgement: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # In the event that the product being advertised includes an # intact Zope distribution (with copyright and license included) # then this clause is waived. # # 5. Names associated with Zope or Digital Creations must not be used to # endorse or promote products derived from this software without # prior written permission from Digital Creations. # # 6. Modified redistributions of any form whatsoever must retain # the following acknowledgment: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # Intact (re-)distributions of any official Zope release do not # require an external acknowledgement. # # 7. Modifications are encouraged but must be packaged separately as # patches to official Zope releases. Distributions that do not # clearly separate the patches from the original work must be clearly # labeled as unofficial distributions. Modifications which do not # carry the name Zope may be packaged in any form, as long as they # conform to all of the clauses above. # # # Disclaimer # # THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # # This software consists of contributions made by Digital Creations and # many individuals on behalf of Digital Creations. Specific # attributions are listed in the accompanying credits file. # ############################################################################## __doc__='''Generic Database adapter''' __version__='$Revision: 1.103 $'[11:-2] import OFS.SimpleItem, Aqueduct, RDB, re import DocumentTemplate, marshal, md5, base64, Acquisition, os from Aqueduct import decodestring, parse from Aqueduct import custom_default_report, default_input_form from Globals import DTMLFile, MessageDialog from cStringIO import StringIO import sys, Globals, OFS.SimpleItem, AccessControl.Role from string import atoi, find, join, split, rstrip import DocumentTemplate, sqlvar, sqltest, sqlgroup from time import time from zlib import compress, decompress from DateTime.DateTime import DateTime md5new=md5.new import ExtensionClass import DocumentTemplate.DT_Util from cPickle import dumps, loads from Results import Results from App.Extensions import getBrain from AccessControl import getSecurityManager from AccessControl.DTML import RestrictedDTML from webdav.Resource import Resource from webdav.Lockable import ResourceLockedError try: from IOBTree import Bucket except: Bucket=lambda:{} class nvSQL(DocumentTemplate.HTML): # Non-validating SQL Template for use by SQLFiles. commands={} for k, v in DocumentTemplate.HTML.commands.items(): commands[k]=v commands['sqlvar' ]=sqlvar.SQLVar commands['sqltest']=sqltest.SQLTest commands['sqlgroup' ]=sqlgroup.SQLGroup _proxy_roles=() class SQL(RestrictedDTML, ExtensionClass.Base, nvSQL): # Validating SQL template for Zope SQL Methods. pass class DA( Aqueduct.BaseQuery,Acquisition.Implicit, Globals.Persistent, AccessControl.Role.RoleManager, OFS.SimpleItem.Item, Resource ): 'Database Adapter' _col=None max_rows_=1000 cache_time_=0 max_cache_=100 class_name_=class_file_='' _zclass=None allow_simple_one_argument_traversal=None template_class=SQL manage_options=( ( {'label':'Edit', 'action':'manage_main', 'help':('ZSQLMethods','Z-SQL-Method_Edit.stx')}, {'label':'Test', 'action':'manage_testForm', 'help':('ZSQLMethods','Z-SQL-Method_Test.stx')}, {'label':'Advanced', 'action':'manage_advancedForm', 'help':('ZSQLMethods','Z-SQL-Method_Advanced.stx')}, {'label':'Cache', 'action':'manage_viewCache',}, ) +AccessControl.Role.RoleManager.manage_options +OFS.SimpleItem.Item.manage_options ) # Specify how individual operations add up to "permissions": __ac_permissions__=( ('View management screens', ( 'manage_main', 'index_html', 'manage_advancedForm', 'PrincipiaSearchSource', 'document_src', 'manage_viewCache', 'size_of_cache', 'clean_cache', 'reset_cache', 'get_cache' )), ('Change Database Methods', ('manage_edit','manage_advanced', 'manage_testForm','manage_test', 'manage_product_zclass_info', 'PUT')), ('Use Database Methods', ('__call__',''), ('Anonymous','Manager')), ) def __init__(self, id, title, connection_id, arguments, template): self.id=str(id) self.manage_edit(title, connection_id, arguments, template) manage_advancedForm=DTMLFile('dtml/advanced', globals()) manage_viewCache=DTMLFile('dtml/viewCache', globals()) test_url___roles__=None def test_url_(self): 'Method for testing server connection information' return 'PING' _size_changes={ 'Bigger': (5,5), 'Smaller': (-5,-5), 'Narrower': (0,-5), 'Wider': (0,5), 'Taller': (5,0), 'Shorter': (-5,0), } def _er(self,title,connection_id,arguments,template, SUBMIT,sql_pref__cols,sql_pref__rows,REQUEST): dr,dc = self._size_changes[SUBMIT] rows=max(1,atoi(sql_pref__rows)+dr) cols=max(40,atoi(sql_pref__cols)+dc) e=(DateTime('GMT') + 365).rfc822() resp=REQUEST['RESPONSE'] resp.setCookie('sql_pref__rows',str(rows),path='/',expires=e) resp.setCookie('sql_pref__cols',str(cols),path='/',expires=e) return self.manage_main( self,REQUEST, title=title, arguments_src=arguments, connection_id=connection_id, src=template, sql_pref__cols=cols,sql_pref__rows=rows) def manage_edit(self,title,connection_id,arguments,template, SUBMIT='Change',sql_pref__cols='50', sql_pref__rows='20', REQUEST=None): """Change database method properties The 'connection_id' argument is the id of a database connection that resides in the current folder or in a folder above the current folder. The database should understand SQL. The 'arguments' argument is a string containing an arguments specification, as would be given in the SQL method cration form. The 'template' argument is a string containing the source for the SQL Template. """ if self._size_changes.has_key(SUBMIT): return self._er(title,connection_id,arguments,template, SUBMIT,sql_pref__cols,sql_pref__rows,REQUEST) if self.wl_isLocked(): raise ResourceLockedError, 'SQL Method is locked via WebDAV' self.title=str(title) self.connection_id=str(connection_id) arguments=str(arguments) self.arguments_src=arguments self._arg=parse(arguments) template=str(template) self.src=template self.template=t=self.template_class(template) t.cook() self._v_cache={}, Bucket() if REQUEST: if SUBMIT=='Change and Test': return self.manage_testForm(REQUEST) message='ZSQL Method content changed' return self.manage_main(self, REQUEST, manage_tabs_message=message) return '' def manage_advanced(self, max_rows, max_cache, cache_time, class_name, class_file, direct=None, REQUEST=None, zclass=''): """Change advanced properties The arguments are: max_rows -- The maximum number of rows to be returned from a query. max_cache -- The maximum number of results to cache cache_time -- The maximum amound of time to use a cached result. class_name -- The name of a class that provides additional attributes for result record objects. This class will be a base class of the result record class. class_file -- The name of the file containing the class definition. The class file normally resides in the 'Extensions' directory, however, the file name may have a prefix of 'product.', indicating that it should be found in a product directory. For example, if the class file is: 'ACMEWidgets.foo', then an attempt will first be made to use the file 'lib/python/Products/ACMEWidgets/Extensions/foo.py'. If this failes, then the file 'Extensions/ACMEWidgets.foo.py' will be used. """ # paranoid type checking if type(max_rows) is not type(1): max_rows=atoi(max_rows) if type(max_cache) is not type(1): max_cache=atoi(max_cache) if type(cache_time) is not type(1): cache_time=atoi(cache_time) class_name=str(class_name) class_file=str(class_file) self.max_rows_ = max_rows self.max_cache_, self.cache_time_ = max_cache, cache_time self._v_cache={}, Bucket() self.class_name_, self.class_file_ = class_name, class_file self._v_brain=getBrain(self.class_file_, self.class_name_, 1) self.allow_simple_one_argument_traversal=direct if zclass: for d in self.aq_acquire('_getProductRegistryData')('zclasses'): if ("%s/%s" % (d.get('product'),d.get('id'))) == zclass: self._zclass=d['meta_class'] break if REQUEST is not None: m="ZSQL Method advanced settings have been set" return self.manage_advancedForm(self,REQUEST,manage_tabs_message=m) ## return self.manage_editedDialog(REQUEST) #def getFindContent(self): # """Return content for use by the Find machinery.""" # return '%s\n%s' % (self.arguments_src, self.src) def PrincipiaSearchSource(self): """Return content for use by the Find machinery.""" return '%s\n%s' % (self.arguments_src, self.src) # WebDAV / FTP support default_content_type = 'text/plain' def document_src(self, REQUEST=None, RESPONSE=None): """Return unprocessed document source.""" if RESPONSE is not None: RESPONSE.setHeader('Content-Type', 'text/plain') return '%s\n%s' % (self.arguments_src, self.src) def manage_FTPget(self): """Get source for FTP download""" self.REQUEST.RESPONSE.setHeader('Content-Type', 'text/plain') return '%s\n%s' % (self.arguments_src, self.src) def PUT(self, REQUEST, RESPONSE): """Handle put requests""" self.dav__init(REQUEST, RESPONSE) self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1) body = REQUEST.get('BODY', '') m = re.match('\s*(.*)\s*\n', body, re.I | re.S) if m: self.arguments_src = m.group(1) self._arg=parse(self.arguments_src) body = body[m.end():] template = body self.src = template self.template=t=self.template_class(template) t.cook() self._v_cache={}, Bucket() RESPONSE.setStatus(204) return RESPONSE def manage_testForm(self, REQUEST): " " input_src=default_input_form(self.title_or_id(), self._arg, 'manage_test', '') return DocumentTemplate.HTML(input_src)(self, REQUEST, HTTP_REFERER='') def manage_test(self, REQUEST): """Test an SQL method.""" # Try to render the query template first so that the rendered # source will be available for the error message in case some # error occurs... try: src=self(REQUEST, src__=1) except: src="Could not render the query template!" result=() t=v=tb=None try: try: src, result=self(REQUEST, test__=1) if find(src,'\0'): src=join(split(src,'\0'),'\n'+'-'*60+'\n') if result._searchable_result_columns(): r=custom_default_report(self.id, result) else: r='This statement returned no results.' except: t, v, tb = sys.exc_info() r='Error, %s: %s' % (t, v) report=DocumentTemplate.HTML( '\n' '\n' '\n
\n%s\n\n' '
SQL used:
\n
\n%s\n
\n
\n' '' % (r,src)) report=apply(report,(self,REQUEST),{self.id:result}) if tb is not None: self.raise_standardErrorMessage( None, REQUEST, t, v, tb, None, report) return report finally: tb=None def index_html(self, REQUEST): """ """ REQUEST.RESPONSE.redirect("%s/manage_testForm" % REQUEST['URL1']) def _searchable_arguments(self): return self._arg def _searchable_result_columns(self): return self._col def _cached_result(self, DB__, query): ''' get the cached sql, look up the result, if its not in the cache, add it in ''' cache, tcache = self.__get_cache() # if the cache size is half of the max, # clean, otherwise carry on if len(cache) > self.max_cache_ / 2: self.__clean_cache(cache, tcache) now=time() t=now-self.cache_time_ # pull result out of cache based on # query if cache.has_key(query): k, r = cache[query] if k > t: return r result=apply(DB__.query, query) # update cache if necessary if self.cache_time_ > 0: tcache[int(now)]=query cache[query]= now, result return result def __get_cache(self): ''' get the cached sql queries ''' if hasattr(self,'_v_cache'): cache=self._v_cache else: cache=self._v_cache={}, Bucket() return cache def __clean_cache(self, cache, tcache): ''' clean the cache ''' max_cache=self.max_cache_ now=time() t=now-self.cache_time_ keys=tcache.keys() keys.reverse() while keys and (len(keys) > max_cache or keys[-1] < t): key=keys[-1] q=tcache[key] del tcache[key] if int(cache[q][0]) == key: del cache[q] del keys[-1] return cache, tcache def __reset_cache(self): self._v_cache={}, Bucket() def size_of_cache(self): ''' No of items in the cache ''' return len(self.__get_cache()[0]) def clean_cache(self, REQUEST=None): ''' Cleans the cache by removing only invalid objects ''' c, t = self.__get_cache() self.__clean_cache(c, t) if REQUEST: return self.manage_viewCache(self, REQUEST, manage_tabs_message='Cache cleaned') def reset_cache(self, REQUEST=None): ''' Removes all items from the cache ''' self.__reset_cache() if REQUEST: return self.manage_viewCache(self, REQUEST, manage_tabs_message='Cache reset') def get_cache(self): ''' Shows the cache ''' c = self.__get_cache()[0] # cache l = [] # easily presentable version... now=time() for k, v in c.items(): d = { 'query':k[0], 'expired': now > (self.cache_time_+int(v[0])), 'secs_since_run':int(now-int(v[0])), } l.append(d) return l def __call__(self, REQUEST=None, __ick__=None, src__=0, test__=0, **kw): """Call the database method The arguments to the method should be passed via keyword arguments, or in a single mapping object. If no arguments are given, and if the method was invoked through the Web, then the method will try to acquire and use the Web REQUEST object as the argument mapping. The returned value is a sequence of record objects. """ if REQUEST is None: if kw: REQUEST=kw else: if hasattr(self, 'REQUEST'): REQUEST=self.REQUEST else: REQUEST={} try: dbc=getattr(self, self.connection_id) except AttributeError: raise AttributeError, ( "The database connection %s cannot be found." % ( self.connection_id)) try: DB__=dbc() except: raise 'Database Error', ( '%s is not connected to a database' % self.id) if hasattr(self, 'aq_parent'): p=self.aq_parent if self._isBeingAccessedAsZClassDefinedInstanceMethod(): p=p.aq_parent else: p=None argdata=self._argdata(REQUEST) argdata['sql_delimiter']='\0' argdata['sql_quote__']=dbc.sql_quote__ for k,v in kw.items(): argdata[k] = v security=getSecurityManager() security.addContext(self) try: query=apply(self.template, (p,), argdata) finally: security.removeContext(self) if src__: return query if self.cache_time_ > 0 and self.max_cache_ > 0: result=self._cached_result(DB__, (query, self.max_rows_)) else: result=DB__.query(query, self.max_rows_) if hasattr(self, '_v_brain'): brain=self._v_brain else: brain=self._v_brain=getBrain(self.class_file_, self.class_name_) zc=self._zclass if zc is not None: zc=zc._zclass_ if type(result) is type(''): f=StringIO() f.write(result) f.seek(0) result=RDB.File(f,brain,p, zc) else: result=Results(result, brain, p, zc) columns=result._searchable_result_columns() if test__ and columns != self._col: self._col=columns # If run in test mode, return both the query and results so # that the template doesn't have to be rendered twice! if test__: return query, result return result def da_has_single_argument(self): return len(self._arg)==1 def __getitem__(self, key): args=self._arg if self.allow_simple_one_argument_traversal and len(args)==1: results=self({args.keys()[0]: key}) if results: if len(results) > 1: raise KeyError, key else: raise KeyError, key r=results[0] # if hasattr(self, 'aq_parent'): r=r.__of__(self.aq_parent) return r self._arg[key] # raise KeyError if not an arg return Traverse(self,{},key) def connectionIsValid(self): return (hasattr(self, self.connection_id) and hasattr(getattr(self, self.connection_id), 'connected')) def connected(self): return getattr(getattr(self, self.connection_id), 'connected')() def manage_product_zclass_info(self): r=[] Z=self._zclass Z=getattr(Z, 'aq_self', Z) for d in self.aq_acquire('_getProductRegistryData')('zclasses'): z=d['meta_class'] if hasattr(z._zclass_,'_p_deactivate'): # Eek, persistent continue x={} x.update(d) x['selected'] = (z is Z) and 'selected' or '' del x['meta_class'] r.append(x) return r Globals.default__class_init__(DA) ListType=type([]) class Traverse(ExtensionClass.Base): """Helper class for 'traversing' searches during URL traversal """ _r=None _da=None def __init__(self, da, args, name=None): self._da=da self._args=args self._name=name def __bobo_traverse__(self, REQUEST, key): name=self._name da=self.__dict__['_da'] args=self._args if name: if args.has_key(name): v=args[name] if type(v) is not ListType: v=[v] v.append(key) key=v args[name]=key if len(args) < len(da._arg): return self.__class__(da, args) key=self # "consume" key elif da._arg.has_key(key): return self.__class__(da, args, key) results=da(args) if results: if len(results) > 1: try: return results[atoi(key)].__of__(da) except: raise KeyError, key else: raise KeyError, key r=results[0] # if hasattr(da, 'aq_parent'): r=r.__of__(da.aq_parent) self._r=r if key is self: return r if hasattr(r,'__bobo_traverse__'): try: return r.__bobo_traverse__(REQUEST, key) except: pass try: return getattr(r,key) except AttributeError, v: if str(v) != key: raise AttributeError, v return r[key] def __getattr__(self, name): r=self.__dict__['_r'] if hasattr(r, name): return getattr(r,name) return getattr(self.__dict__['_da'], name) Shared/DC/ZRDB/dbi_db.py100666 0 0 20161 7114716040 15423 0ustar00unknownunknown 0 0 ############################################################################## # # Zope Public License (ZPL) Version 1.0 # ------------------------------------- # # Copyright (c) Digital Creations. All rights reserved. # # This license has been certified as Open Source(tm). # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions in source code must retain the above copyright # notice, this list of conditions, and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions, and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # 3. Digital Creations requests that attribution be given to Zope # in any manner possible. Zope includes a "Powered by Zope" # button that is installed by default. While it is not a license # violation to remove this button, it is requested that the # attribution remain. A significant investment has been put # into Zope, and this effort will continue if the Zope community # continues to grow. This is one way to assure that growth. # # 4. All advertising materials and documentation mentioning # features derived from or use of this software must display # the following acknowledgement: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # In the event that the product being advertised includes an # intact Zope distribution (with copyright and license included) # then this clause is waived. # # 5. Names associated with Zope or Digital Creations must not be used to # endorse or promote products derived from this software without # prior written permission from Digital Creations. # # 6. Modified redistributions of any form whatsoever must retain # the following acknowledgment: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # Intact (re-)distributions of any official Zope release do not # require an external acknowledgement. # # 7. Modifications are encouraged but must be packaged separately as # patches to official Zope releases. Distributions that do not # clearly separate the patches from the original work must be clearly # labeled as unofficial distributions. Modifications which do not # carry the name Zope may be packaged in any form, as long as they # conform to all of the clauses above. # # # Disclaimer # # THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # # This software consists of contributions made by Digital Creations and # many individuals on behalf of Digital Creations. Specific # attributions are listed in the accompanying credits file. # ############################################################################## __doc__='''short description $Id: dbi_db.py,v 1.8 2000/05/30 15:46:55 brian Exp $''' # Copyright # # Copyright 1997 Digital Creations, Inc, 910 Princess Anne # Street, Suite 300, Fredericksburg, Virginia 22401 U.S.A. All # rights reserved. # __version__='$Revision: 1.8 $'[11:-2] import string, sys from string import strip, split, find, join failures=0 calls=0 nonselect_desc=[ ('Query', 'STRING', 62, 62, 0, 0, 1), ('Status', 'STRING', 12, 12, 0, 0, 1), ('Calls', 'STRING', 12, 12, 0, 0, 1), ] class DB: _p_oid=_p_changed=_registered=None defs={'STRING':'s', 'NUMBER':'n', 'DATE':'d'} def Database_Connection(self, string): # Create a dbi-compatible database connection raise 'ImplementedBySubclass', ( 'attempt to create a database connection for an abstract dbi') Database_Error='Should be overriden by subclass' def __init__(self,connection): self.connection=connection db=self.db=self.Database_Connection(connection) self.cursor=db.cursor() def str(self,v, StringType=type('')): if v is None: return '' r=str(v) if r[-1:]=='L' and type(v) is not StringType: r=r[:-1] return r def __inform_commit__(self, *ignored): self._registered=None self.db.commit() def __inform_abort__(self, *ignored): self._registered=None self.db.rollback() def register(self): if self._registered: return get_transaction().register(self) self._registered=1 def query(self,query_string, max_rows=9999999): global failures, calls calls=calls+1 try: c=self.cursor self.register() queries=filter(None, map(strip,split(query_string, '\0'))) if not queries: raise 'Query Error', 'empty query' if len(queries) > 1: result=[] for qs in queries: r=c.execute(qs) if r is None: raise 'Query Error', ( 'select in multiple sql-statement query' ) result.append((qs, str(`r`), calls)) desc=nonselect_desc else: query_string=queries[0] r=c.execute(query_string) if r is None: result=c.fetchmany(max_rows) desc=c.description else: result=((query_string, str(`r`), calls),) desc=nonselect_desc failures=0 c.close() except self.Database_Error, mess: c.close() self.db.rollback() failures=failures+1 if ((find(mess,": invalid") < 0 and find(mess,"PARSE") < 0) or # DBI IS stupid find(mess, "Error while trying to retrieve text for error") > 0 or # If we have a large number of consecutive failures, # our connection is probably dead. failures > 100 ): # Hm. maybe the db is hosed. Let's try once to restart it. failures=0 c.close() self.db.close() db=self.db=self.Database_Connection(self.connection) self.cursor=db.cursor() c=self.cursor c.execute(query_string) result=c.fetchall() desc=c.description else: raise sys.exc_info() if result: result=join( map( lambda row, self=self: join(map(self.str,row),'\t'), result), '\n')+'\n' else: result='' return ( "%s\n%s\n%s" % ( join(map(lambda d: d[0],desc), '\t'), join( map( lambda d, defs=self.defs: "%d%s" % (d[2],defs[d[1]]), desc), '\t'), result, ) ) Shared/DC/ZRDB/dtml/advanced.dtml100666 0 0 6343 7226376432 17236 0ustar00unknownunknown 0 0
Maximum rows to retrieve
Maximum results to cache
Maximum time (sec) to cache
Allow "simple" direct traversal
checked />

You may specify a class for the data records. This class must be defined in a file that resides in the Extensions directory of this Zope installation.
Class Name
Class File

You may specify a ZClass for the data records.
ZClass
Shared/DC/ZRDB/dtml/connectionAdd.dtml100666 0 0 3132 7226376432 20232 0ustar00unknownunknown 0 0
Id
Title
Connection String
Connect Immediately?

Shared/DC/ZRDB/dtml/connectionEdit.dtml100666 0 0 2633 7226376432 20434 0ustar00unknownunknown 0 0
Id
Title
Connection String
Connect Immediately

Shared/DC/ZRDB/dtml/connectionStatus.dtml100666 0 0 1122 7226376432 21022 0ustar00unknownunknown 0 0

The database connection is openclosed.

Shared/DC/ZRDB/dtml/connectionTestForm.dtml100666 0 0 1751 7226376432 21312 0ustar00unknownunknown 0 0

You can write a test query and run it with this database connection using the form below. Click submit query to run the query.

This database connection is currently closed. You must click on the status tab and open the connection before you can test it.

Shared/DC/ZRDB/dtml/customDefaultReport.dtml100666 0 0 1714 7226376432 21501 0ustar00unknownunknown 0 0 (Previous results) %(else no_table)[ %(heading)s %(else)] %(row)s %(else no_table)[
%(else)] (Next results)
There was no data matching this query.
Shared/DC/ZRDB/dtml/searchAdd.dtml100666 0 0 5102 7226376432 17337 0ustar00unknownunknown 0 0

A Search Interface allows you to search Zope databases. The Search Interface will create a search-input form and a report for displaying the search results.

In the form below, seachable objects are the objects (usually SQL Methods) to be searched. report id and search input id are the ids of the report and search form objects that will be created. report style indicates the type of report to generate.

Select one
or more
searchable
objects
Report Id
Report Title
Report Style
Search Input Id
Search Input Title
Shared/DC/ZRDB/dtml/viewCache.dtml100666 0 0 1552 7355306614 17362 0ustar00unknownunknown 0 0

This shows you the current contents of a ZSQL Method cache.

Cache size: [ Clean ] [ Reset ]

StatusQueryLast run (secs)
ExpiredOk &dtml-query; &dtml-secs_since_run;
Cache is empty
Shared/DC/ZRDB/RDB.py100666 0 0 23672 7325007154 14644 0ustar00unknownunknown 0 0 ############################################################################## # # Zope Public License (ZPL) Version 1.0 # ------------------------------------- # # Copyright (c) Digital Creations. All rights reserved. # # This license has been certified as Open Source(tm). # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions in source code must retain the above copyright # notice, this list of conditions, and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions, and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # 3. Digital Creations requests that attribution be given to Zope # in any manner possible. Zope includes a "Powered by Zope" # button that is installed by default. While it is not a license # violation to remove this button, it is requested that the # attribution remain. A significant investment has been put # into Zope, and this effort will continue if the Zope community # continues to grow. This is one way to assure that growth. # # 4. All advertising materials and documentation mentioning # features derived from or use of this software must display # the following acknowledgement: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # In the event that the product being advertised includes an # intact Zope distribution (with copyright and license included) # then this clause is waived. # # 5. Names associated with Zope or Digital Creations must not be used to # endorse or promote products derived from this software without # prior written permission from Digital Creations. # # 6. Modified redistributions of any form whatsoever must retain # the following acknowledgment: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # Intact (re-)distributions of any official Zope release do not # require an external acknowledgement. # # 7. Modifications are encouraged but must be packaged separately as # patches to official Zope releases. Distributions that do not # clearly separate the patches from the original work must be clearly # labeled as unofficial distributions. Modifications which do not # carry the name Zope may be packaged in any form, as long as they # conform to all of the clauses above. # # # Disclaimer # # THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # # This software consists of contributions made by Digital Creations and # many individuals on behalf of Digital Creations. Specific # attributions are listed in the accompanying credits file. # ############################################################################## __doc__='''Class for reading RDB files $Id: RDB.py,v 1.30.16.1 2001/07/17 15:07:39 andreas Exp $''' __version__='$Revision: 1.30.16.1 $'[11:-2] from string import split, strip, lower, upper, atof, atoi, atol, find, join,find import DateTime,re from Missing import MV from array import array from Record import Record from Acquisition import Implicit import ExtensionClass def parse_text(s): if find(s,'\\') < 0 and (find(s,'\\t') < 0 and find(s,'\\n') < 0): return s r=[] for x in split(s,'\\\\'): x=join(split(x,'\\n'),'\n') r.append(join(split(x,'\\t'),'\t')) return join(r,'\\') Parsers={'n': atof, 'i': atoi, 'l': atol, 'd': DateTime.DateTime, 't': parse_text, } class SQLAlias(ExtensionClass.Base): def __init__(self, name): self._n=name def __of__(self, parent): return getattr(parent, self._n) class NoBrains: pass class DatabaseResults: """Class for reading RDB files """ _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,file,brains=NoBrains, parent=None, zbrains=None): self._file=file readline=file.readline line=readline() self._parent=parent if zbrains is None: zbrains=NoBrains while line and line.find('#') != -1 : line=readline() line=line[:-1] if line and line[-1:] in '\r\n': line=line[:-1] self._names=names=split(line,'\t') if not names: raise ValueError, 'No column names' aliases=[] self._schema=schema={} i=0 for name in names: name=strip(name) 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=lower(name) if n != name: aliases.append((n, SQLAlias(name))) n=upper(name) if n != name: aliases.append((n, SQLAlias(name))) i=i+1 self._nv=nv=len(names) line=readline() line=line[:-1] if line[-1:] in '\r\n': line=line[:-1] self._defs=defs=split(line,'\t') if not defs: raise ValueError, 'No column definitions' if len(defs) != nv: raise ValueError, ( """The number of column names and the number of column definitions are different.""") i=0 self._parsers=parsers=[] defre=re.compile(r'([0-9]*)([a-zA-Z])?') self._data_dictionary=dd={} self.__items__=items=[] for _def in defs: _def=strip(_def) if not _def: raise ValueError, ('Empty column definition for %s' % names[i]) mo = defre.match(_def) if mo is None: raise ValueError, ( 'Invalid column definition for, %s, for %s' % _def, names[i]) type = mo.group(2).lower() width = mo.group(1) if width: width=atoi(width) else: width=8 try: parser=Parsers[type] except: parser=str name=names[i] d={'name': name, 'type': type, 'width': width, 'parser': parser} items.append(d) dd[name]=d parsers.append((i,parser)) i=i+1 # 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 filter(lambda k: k[:2]=='__', Record.__dict__.keys()): setattr(r,k,getattr(Record,k)) # Add SQL Aliases d=r.__dict__ for k, v in aliases: if not hasattr(r,k): d[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) binit(self.__of__(parent)) r.__dict__['__init__']=__init__ self._class=r # OK, we've read meta data, now get line indexes p=file.tell() save=self._lines=array('i') save=save.append l=readline() while l: save(p) p=p+len(l) l=readline() 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._lines) def __getitem__(self,index): if index==self._index: return self._row file=self._file file.seek(self._lines[index]) line=file.readline() line=line[:-1] if line and line[-1:] in '\r\n': line=line[:-1] fields=split(line,'\t') l=len(fields) nv=self._nv if l != nv: if l < nv: fields=fields+['']*(nv-l) else: raise ValueError, ( """The number of items in record %s is invalid
%s\n%s\n%s\n%s
""" % (index, ('='*40), line, ('='*40), fields)) for i, parser in self._parsers: try: v=parser(fields[i]) except: if fields[i]: raise ValueError, ( """Invalid value, %s, for %s in record %s""" % (fields[i], self._names[i], index)) else: v=MV fields[i]=v parent=self._parent fields=self._class(fields, parent) self._index=index self._row=fields if parent is None: return fields return fields.__of__(parent) File=DatabaseResults Shared/DC/ZRDB/Results.py100666 0 0 20425 7263602640 15671 0ustar00unknownunknown 0 0 ############################################################################## # # Zope Public License (ZPL) Version 1.0 # ------------------------------------- # # Copyright (c) Digital Creations. All rights reserved. # # This license has been certified as Open Source(tm). # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions in source code must retain the above copyright # notice, this list of conditions, and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions, and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # 3. Digital Creations requests that attribution be given to Zope # in any manner possible. Zope includes a "Powered by Zope" # button that is installed by default. While it is not a license # violation to remove this button, it is requested that the # attribution remain. A significant investment has been put # into Zope, and this effort will continue if the Zope community # continues to grow. This is one way to assure that growth. # # 4. All advertising materials and documentation mentioning # features derived from or use of this software must display # the following acknowledgement: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # In the event that the product being advertised includes an # intact Zope distribution (with copyright and license included) # then this clause is waived. # # 5. Names associated with Zope or Digital Creations must not be used to # endorse or promote products derived from this software without # prior written permission from Digital Creations. # # 6. Modified redistributions of any form whatsoever must retain # the following acknowledgment: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # Intact (re-)distributions of any official Zope release do not # require an external acknowledgement. # # 7. Modifications are encouraged but must be packaged separately as # patches to official Zope releases. Distributions that do not # clearly separate the patches from the original work must be clearly # labeled as unofficial distributions. Modifications which do not # carry the name Zope may be packaged in any form, as long as they # conform to all of the clauses above. # # # Disclaimer # # THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # # This software consists of contributions made by Digital Creations and # many individuals on behalf of Digital Creations. Specific # attributions are listed in the accompanying credits file. # ############################################################################## import ExtensionClass import string from string import strip, lower, upper, join 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=strip(name) 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=lower(name) if n != name: aliases.append((n, SQLAlias(name))) n=upper(name) 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 d=r.__dict__ for k, v in aliases: if not hasattr(r,k): d[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) r.__dict__['__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)) join=string.join for i in indexes: item=items[i] t=lower(item['type']) 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=[join(self._names, '\t'), join(r,'\t')] append=r.append find=string.find split=string.split row=['']*len(items) tostr=str for d in self._data: for i in strings: v=tostr(d[i]) if v: if find(v,'\\') > 0: v=join(split(v,'\\'),'\\\\') if find(v,'\t') > 0: v=join(split(v,'\t'),'\\t') if find(v,'\n') > 0: v=join(split(v,'\n'),'\\n') row[i]=v for i in nstrings: row[i]=tostr(d[i]) append(join(row,'\t')) append('') return join(r,'\n') Shared/DC/ZRDB/Search.py100666 0 0 22040 7227577014 15436 0ustar00unknownunknown 0 0 ############################################################################## # # Zope Public License (ZPL) Version 1.0 # ------------------------------------- # # Copyright (c) Digital Creations. All rights reserved. # # This license has been certified as Open Source(tm). # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions in source code must retain the above copyright # notice, this list of conditions, and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions, and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # 3. Digital Creations requests that attribution be given to Zope # in any manner possible. Zope includes a "Powered by Zope" # button that is installed by default. While it is not a license # violation to remove this button, it is requested that the # attribution remain. A significant investment has been put # into Zope, and this effort will continue if the Zope community # continues to grow. This is one way to assure that growth. # # 4. All advertising materials and documentation mentioning # features derived from or use of this software must display # the following acknowledgement: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # In the event that the product being advertised includes an # intact Zope distribution (with copyright and license included) # then this clause is waived. # # 5. Names associated with Zope or Digital Creations must not be used to # endorse or promote products derived from this software without # prior written permission from Digital Creations. # # 6. Modified redistributions of any form whatsoever must retain # the following acknowledgment: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # Intact (re-)distributions of any official Zope release do not # require an external acknowledgement. # # 7. Modifications are encouraged but must be packaged separately as # patches to official Zope releases. Distributions that do not # clearly separate the patches from the original work must be clearly # labeled as unofficial distributions. Modifications which do not # carry the name Zope may be packaged in any form, as long as they # conform to all of the clauses above. # # # Disclaimer # # THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # # This software consists of contributions made by Digital Creations and # many individuals on behalf of Digital Creations. Specific # attributions are listed in the accompanying credits file. # ############################################################################## __doc__='''Search Interface Wizard $Id: Search.py,v 1.16 2001/01/12 17:52:28 chrism Exp $''' __version__='$Revision: 1.16 $'[11:-2] from Globals import DTMLFile from Aqueduct import custom_default_report, nicify, Args from string import join addForm=DTMLFile('dtml/searchAdd', globals()) def manage_addZSearch(self, report_id, report_title, report_style, input_id, input_title, queries=[], REQUEST=None): 'add a report' if not queries: raise ValueError, ( 'No searchable objects were selected') if not report_id: raise ValueError, ( 'No report id were specified') if input_title and not input_id: raise ValueError, ( 'No input id were specified') qs=map(lambda q, self=self: _getquery(self, q), queries) arguments={} keys=[] for q in qs: url=q.absolute_url() if input_id: for name, arg in q._searchable_arguments().items(): if len(qs) > 1: key="%s/%s" % (id,name) else: key=name arguments[key]=arg keys.append(key) if q._searchable_result_columns() is None: raise 'Unusable Searchable Error',( """The input searchable object, %s, has not been tested. Until it has been tested, it\'s output schema is unknown, and a report cannot be generated. Before creating a report from this query, you must try out the query. To try out the query, click here. """ % (q.title_and_id(), url)) if input_id: arguments=Args(arguments, keys) self.manage_addDocument( input_id,input_title, default_input_form(arguments, report_id)) self.manage_addDocument( report_id,report_title, ('\n%s\n' '' % join(map(lambda q, report_style=report_style: custom_default_report(q.id, q, no_table=report_style), qs), '\n
\n'))) if REQUEST: return self.manage_main(self,REQUEST) def ZQueryIds(self): # Note that report server configurations will expend on this t=[] ids={} old=ids.has_key o=self n=0 while 1: # Look for queries try: map=o.objectMap() except AttributeError: map=() for i in map: try: id=i['id'] if (not old(id) and hasattr(getattr(o,id),'_searchable_arguments') ): t.append(i['id']) ids[id]=1 except: pass # Now extend search to parent try: o=o.aq_parent except: return t if n > 100: return t # Seat belt n=n+1 def _getquery(self,id): o=self i=0 while 1: __traceback_info__=o q=getattr(o,id) try: if hasattr(q,'_searchable_arguments'): try: q=q.__of__(self.aq_parent) except: pass return q except: pass if i > 100: raise AttributeError, id i=i+1 o=o.aq_parent def default_input_form(arguments,action='query', tabs=''): if arguments: items=arguments.items() return ( "%s\n%s%s" % ( '\n%s\n' '
\n' '

\n' 'Enter query parameters:
' '\n' % (tabs,action), join( map( lambda a: ('\n' ' ' % (nicify(a[0]), ( a[1].has_key('type') and ("%s:%s" % (a[0],a[1]['type'])) or a[0] ), a[1].has_key('default') and a[1]['default'] or '' )) , items ), '\n'), '\n\n
%s' '
\n' '\n' '
\n
\n' '\n' ) ) else: return ( '\n%s\n' '
\n' '

\n' 'This query requires no input.

\n' '\n' '\n\n

\n' '\n' % (tabs, action) ) Shared/DC/ZRDB/sqlgroup.py100666 0 0 16776 7010015356 16112 0ustar00unknownunknown 0 0 ############################################################################## # # Zope Public License (ZPL) Version 1.0 # ------------------------------------- # # Copyright (c) Digital Creations. All rights reserved. # # This license has been certified as Open Source(tm). # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions in source code must retain the above copyright # notice, this list of conditions, and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions, and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # 3. Digital Creations requests that attribution be given to Zope # in any manner possible. Zope includes a "Powered by Zope" # button that is installed by default. While it is not a license # violation to remove this button, it is requested that the # attribution remain. A significant investment has been put # into Zope, and this effort will continue if the Zope community # continues to grow. This is one way to assure that growth. # # 4. All advertising materials and documentation mentioning # features derived from or use of this software must display # the following acknowledgement: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # In the event that the product being advertised includes an # intact Zope distribution (with copyright and license included) # then this clause is waived. # # 5. Names associated with Zope or Digital Creations must not be used to # endorse or promote products derived from this software without # prior written permission from Digital Creations. # # 6. Modified redistributions of any form whatsoever must retain # the following acknowledgment: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # Intact (re-)distributions of any official Zope release do not # require an external acknowledgement. # # 7. Modifications are encouraged but must be packaged separately as # patches to official Zope releases. Distributions that do not # clearly separate the patches from the original work must be clearly # labeled as unofficial distributions. Modifications which do not # carry the name Zope may be packaged in any form, as long as they # conform to all of the clauses above. # # # Disclaimer # # THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # # This software consists of contributions made by Digital Creations and # many individuals on behalf of Digital Creations. Specific # attributions are listed in the accompanying credits file. # ############################################################################## '''Inserting optional tests with 'sqlgroup' It is sometimes useful to make inputs to an SQL statement optinal. Doing so can be difficult, because not only must the test be inserted conditionally, but SQL boolean operators may or may not need to be inserted depending on whether other, possibly optional, comparisons have been done. The 'sqlgroup' tag automates the conditional insertion of boolean operators. The 'sqlgroup' tag is a block tag. It can have any number of 'and' and 'or' continuation tags. The 'sqlgroup' tag has an optional attribure, 'required' to specify groups that must include at least one test. This is useful when you want to make sure that a query is qualified, but want to be very flexible about how it is qualified. Suppose we want to find people with a given first or nick name, city or minimum and maximum age. Suppose we want all inputs to be optional, but want to require *some* input. We can use DTML source like the following:: age >= age <= This example illustrates how groups can be nested to control boolean evaluation order. It also illustrates that the grouping facility can also be used with other DTML tags like 'if' tags. The 'sqlgroup' tag checks to see if text to be inserted contains other than whitespace characters. If it does, then it is inserted with the appropriate boolean operator, as indicated by use of an 'and' or 'or' tag, otherwise, no text is inserted. ''' ############################################################################ # Copyright # # Copyright 1996 Digital Creations, L.C., 910 Princess Anne # Street, Suite 300, Fredericksburg, Virginia 22401 U.S.A. All # rights reserved. # ############################################################################ __rcs_id__='$Id: sqlgroup.py,v 1.7 1999/11/03 16:22:22 brian Exp $' __version__='$Revision: 1.7 $'[11:-2] from DocumentTemplate.DT_Util import parse_params str=__builtins__['str'] from string import strip, join import sys class SQLGroup: blockContinuations='and','or' name='sqlgroup' required=None where=None def __init__(self, blocks): self.blocks=blocks tname, args, section = blocks[0] self.__name__="%s %s" % (tname, args) args = parse_params(args, required=1, where=1) if args.has_key(''): args[args['']]=1 if args.has_key('required'): self.required=args['required'] if args.has_key('where'): self.where=args['where'] def render(self,md): r=[] for tname, args, section in self.blocks: __traceback_info__=tname s=strip(section(None, md)) if s: if r: r.append(tname) r.append("%s\n" % s) if r: if len(r) > 1: r="(%s)\n" % join(r,' ') else: r=r[0] if self.where: r="where\n"+r return r if self.required: raise 'Input Error', 'Not enough input was provided!

' return '' __call__=render Shared/DC/ZRDB/sqltest.py100666 0 0 22707 7114716040 15727 0ustar00unknownunknown 0 0 ############################################################################## # # Zope Public License (ZPL) Version 1.0 # ------------------------------------- # # Copyright (c) Digital Creations. All rights reserved. # # This license has been certified as Open Source(tm). # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions in source code must retain the above copyright # notice, this list of conditions, and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions, and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # 3. Digital Creations requests that attribution be given to Zope # in any manner possible. Zope includes a "Powered by Zope" # button that is installed by default. While it is not a license # violation to remove this button, it is requested that the # attribution remain. A significant investment has been put # into Zope, and this effort will continue if the Zope community # continues to grow. This is one way to assure that growth. # # 4. All advertising materials and documentation mentioning # features derived from or use of this software must display # the following acknowledgement: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # In the event that the product being advertised includes an # intact Zope distribution (with copyright and license included) # then this clause is waived. # # 5. Names associated with Zope or Digital Creations must not be used to # endorse or promote products derived from this software without # prior written permission from Digital Creations. # # 6. Modified redistributions of any form whatsoever must retain # the following acknowledgment: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # Intact (re-)distributions of any official Zope release do not # require an external acknowledgement. # # 7. Modifications are encouraged but must be packaged separately as # patches to official Zope releases. Distributions that do not # clearly separate the patches from the original work must be clearly # labeled as unofficial distributions. Modifications which do not # carry the name Zope may be packaged in any form, as long as they # conform to all of the clauses above. # # # Disclaimer # # THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # # This software consists of contributions made by Digital Creations and # many individuals on behalf of Digital Creations. Specific # attributions are listed in the accompanying credits file. # ############################################################################## '''Inserting optional tests with 'sqlgroup' It is sometimes useful to make inputs to an SQL statement optinal. Doing so can be difficult, because not only must the test be inserted conditionally, but SQL boolean operators may or may not need to be inserted depending on whether other, possibly optional, comparisons have been done. The 'sqlgroup' tag automates the conditional insertion of boolean operators. The 'sqlgroup' tag is a block tag that has no attributes. It can have any number of 'and' and 'or' continuation tags. Suppose we want to find all people with a given first or nick name and optionally constrain the search by city and minimum and maximum age. Suppose we want all inputs to be optional. We can use DTML source like the following:: age >= age <= This example illustrates how groups can be nested to control boolean evaluation order. It also illustrates that the grouping facility can also be used with other DTML tags like 'if' tags. The 'sqlgroup' tag checks to see if text to be inserted contains other than whitespace characters. If it does, then it is inserted with the appropriate boolean operator, as indicated by use of an 'and' or 'or' tag, otherwise, no text is inserted. ''' __rcs_id__='$Id: sqltest.py,v 1.13 2000/05/30 15:46:55 brian Exp $' ############################################################################ # Copyright # # Copyright 1996 Digital Creations, L.C., 910 Princess Anne # Street, Suite 300, Fredericksburg, Virginia 22401 U.S.A. All # rights reserved. # ############################################################################ __version__='$Revision: 1.13 $'[11:-2] import sys from DocumentTemplate.DT_Util import ParseError, parse_params, name_param str=__builtins__['str'] from string import find, split, join, atoi, atof from types import ListType, TupleType, StringType class SQLTest: name='sqltest' optional=multiple=None def __init__(self, args): args = parse_params(args, name='', type=None, column=None, multiple=1, optional=1, op=None) self.__name__ = name_param(args,'sqlvar') has_key=args.has_key if not has_key('type'): raise ParseError, ('the type attribute is required', 'sqltest') self.type=t=args['type'] if not valid_type(t): raise ParseError, ('invalid type, %s' % t, 'sqltest') if has_key('optional'): self.optional=args['optional'] if has_key('multiple'): self.multiple=args['multiple'] if has_key('column'): self.column=args['column'] else: self.column=self.__name__ # Deal with optional operator specification op = '=' # Default if has_key('op'): op = args['op'] # Try to get it from the chart, otherwise use the one provided op = comparison_operators.get(op, op) self.op = op def render(self, md): name=self.__name__ t=self.type try: v = md[name] except KeyError, key: if str(key)==name and self.optional: return '' raise KeyError, key, sys.exc_info()[2] if type(v) in (ListType, TupleType): if len(v) > 1 and not self.multiple: raise 'Multiple Values', ( 'multiple values are not allowed for %s' % name) else: v=[v] vs=[] for v in v: if not v and type(v) is StringType and t != 'string': continue if t=='int': try: if type(v) is StringType: atoi(v) else: v=str(int(v)) except: raise ValueError, ( 'Invalid integer value for %s' % name) elif t=='float': if not v and type(v) is StringType: continue try: if type(v) is StringType: atof(v) else: v=str(float(v)) except: raise ValueError, ( 'Invalid floating-point value for %s' % name) else: v=str(v) v=md.getitem('sql_quote__',0)(v) #if find(v,"\'") >= 0: v=join(split(v,"\'"),"''") #v="'%s'" % v vs.append(v) if not vs: if self.optional: return '' raise 'Missing Input', ( 'No input was provided for %s' % name) if len(vs) > 1: vs=join(map(str,vs),', ') return "%s in (%s)" % (self.column,vs) return "%s %s %s" % (self.column, self.op, vs[0]) __call__=render valid_type={'int':1, 'float':1, 'string':1, 'nb': 1}.has_key comparison_operators = { 'eq': '=', 'ne': '<>', 'lt': '<', 'le': '<=', 'lte': '<=', 'gt': '>', 'ge': '>=', 'gte': '>=' } Shared/DC/ZRDB/sqlvar.py100666 0 0 20244 7155702070 15535 0ustar00unknownunknown 0 0 ############################################################################## # # Zope Public License (ZPL) Version 1.0 # ------------------------------------- # # Copyright (c) Digital Creations. All rights reserved. # # This license has been certified as Open Source(tm). # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions in source code must retain the above copyright # notice, this list of conditions, and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions, and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # 3. Digital Creations requests that attribution be given to Zope # in any manner possible. Zope includes a "Powered by Zope" # button that is installed by default. While it is not a license # violation to remove this button, it is requested that the # attribution remain. A significant investment has been put # into Zope, and this effort will continue if the Zope community # continues to grow. This is one way to assure that growth. # # 4. All advertising materials and documentation mentioning # features derived from or use of this software must display # the following acknowledgement: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # In the event that the product being advertised includes an # intact Zope distribution (with copyright and license included) # then this clause is waived. # # 5. Names associated with Zope or Digital Creations must not be used to # endorse or promote products derived from this software without # prior written permission from Digital Creations. # # 6. Modified redistributions of any form whatsoever must retain # the following acknowledgment: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # Intact (re-)distributions of any official Zope release do not # require an external acknowledgement. # # 7. Modifications are encouraged but must be packaged separately as # patches to official Zope releases. Distributions that do not # clearly separate the patches from the original work must be clearly # labeled as unofficial distributions. Modifications which do not # carry the name Zope may be packaged in any form, as long as they # conform to all of the clauses above. # # # Disclaimer # # THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # # This software consists of contributions made by Digital Creations and # many individuals on behalf of Digital Creations. Specific # attributions are listed in the accompanying credits file. # ############################################################################## '''Inserting values with the 'sqlvar' tag The 'sqlvar' tag is used to type-safely insert values into SQL text. The 'sqlvar' tag is similar to the 'var' tag, except that it replaces text formatting parameters with SQL type information. The sqlvar tag has the following attributes: name -- The name of the variable to insert. As with other DTML tags, the 'name=' prefix may be, and usually is, ommitted. type -- The data type of the value to be inserted. This attribute is required and may be one of 'string', 'int', 'float', or 'nb'. The 'nb' data type indicates a string that must have a length that is greater than 0. optional -- A flag indicating that a value is optional. If a value is optional and is not provided (or is blank when a non-blank value is expected), then the string 'null' is inserted. For example, given the tag:: if the value of 'x' is:: Let\'s do it then the text inserted is: 'Let''s do it' however, if x is ommitted or an empty string, then the value inserted is 'null'. ''' __rcs_id__='$Id: sqlvar.py,v 1.11 2000/09/07 17:04:07 brian Exp $' ############################################################################ # Copyright # # Copyright 1996 Digital Creations, L.C., 910 Princess Anne # Street, Suite 300, Fredericksburg, Virginia 22401 U.S.A. All # rights reserved. # ############################################################################ __version__='$Revision: 1.11 $'[11:-2] from DocumentTemplate.DT_Util import ParseError, parse_params, name_param from string import find, split, join, atoi, atof StringType=type('') str=__builtins__['str'] class SQLVar: name='sqlvar' def __init__(self, args): args = parse_params(args, name='', expr='', type=None, optional=1) name,expr=name_param(args,'sqlvar',1) if expr is None: expr=name else: expr=expr.eval self.__name__, self.expr = name, expr self.args=args if not args.has_key('type'): raise ParseError, ('the type attribute is required', 'dtvar') t=args['type'] if not valid_type(t): raise ParseError, ('invalid type, %s' % t, 'dtvar') def render(self, md): name=self.__name__ args=self.args t=args['type'] try: expr=self.expr if type(expr) is type(''): v=md[expr] else: v=expr(md) except: if args.has_key('optional') and args['optional']: return 'null' if type(expr) is not type(''): raise raise 'Missing Input', 'Missing input variable, %s' % name if t=='int': try: if type(v) is StringType: if v[-1:]=='L': v=v[:-1] atoi(v) else: v=str(int(v)) except: if not v and args.has_key('optional') and args['optional']: return 'null' raise ValueError, ( 'Invalid integer value for %s' % name) elif t=='float': try: if type(v) is StringType: if v[-1:]=='L': v=v[:-1] atof(v) else: v=str(float(v)) except: if not v and args.has_key('optional') and args['optional']: return 'null' raise ValueError, ( 'Invalid floating-point value for %s' % name) else: v=str(v) if not v and t=='nb': if args.has_key('optional') and args['optional']: return 'null' else: raise ValueError, ( 'Invalid empty string value for %s' % name) v=md.getitem('sql_quote__',0)(v) #if find(v,"\'") >= 0: v=join(split(v,"\'"),"''") #v="'%s'" % v return v __call__=render valid_type={'int':1, 'float':1, 'string':1, 'nb': 1}.has_key Shared/DC/ZRDB/THUNK.py100666 0 0 11316 6770134720 15121 0ustar00unknownunknown 0 0 ############################################################################## # # Zope Public License (ZPL) Version 1.0 # ------------------------------------- # # Copyright (c) Digital Creations. All rights reserved. # # This license has been certified as Open Source(tm). # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions in source code must retain the above copyright # notice, this list of conditions, and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions, and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # 3. Digital Creations requests that attribution be given to Zope # in any manner possible. Zope includes a "Powered by Zope" # button that is installed by default. While it is not a license # violation to remove this button, it is requested that the # attribution remain. A significant investment has been put # into Zope, and this effort will continue if the Zope community # continues to grow. This is one way to assure that growth. # # 4. All advertising materials and documentation mentioning # features derived from or use of this software must display # the following acknowledgement: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # In the event that the product being advertised includes an # intact Zope distribution (with copyright and license included) # then this clause is waived. # # 5. Names associated with Zope or Digital Creations must not be used to # endorse or promote products derived from this software without # prior written permission from Digital Creations. # # 6. Modified redistributions of any form whatsoever must retain # the following acknowledgment: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # Intact (re-)distributions of any official Zope release do not # require an external acknowledgement. # # 7. Modifications are encouraged but must be packaged separately as # patches to official Zope releases. Distributions that do not # clearly separate the patches from the original work must be clearly # labeled as unofficial distributions. Modifications which do not # carry the name Zope may be packaged in any form, as long as they # conform to all of the clauses above. # # # Disclaimer # # THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # # This software consists of contributions made by Digital Creations and # many individuals on behalf of Digital Creations. Specific # attributions are listed in the accompanying credits file. # ############################################################################## import TM, ThreadLock from TM import Surrogate thunk_lock=ThreadLock.allocate_lock() class THUNKED_TM(TM.TM): """A big heavy hammer for handling non-thread safe DAs """ def _register(self): if not self._registered: thunk_lock.acquire() try: get_transaction().register(Surrogate(self)) self._begin() except: thunk_lock.release() raise else: self._registered=1 def tpc_finish(self, *ignored): if self._registered: try: self._finish() finally: thunk_lock.release() self._registered=0 def abort(self, *ignored): if self._registered: try: self._abort() finally: thunk_lock.release() self._registered=0 Shared/DC/ZRDB/TM.py100666 0 0 12135 7021445624 14546 0ustar00unknownunknown 0 0 ############################################################################## # # Zope Public License (ZPL) Version 1.0 # ------------------------------------- # # Copyright (c) Digital Creations. All rights reserved. # # This license has been certified as Open Source(tm). # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions in source code must retain the above copyright # notice, this list of conditions, and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions, and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # 3. Digital Creations requests that attribution be given to Zope # in any manner possible. Zope includes a "Powered by Zope" # button that is installed by default. While it is not a license # violation to remove this button, it is requested that the # attribution remain. A significant investment has been put # into Zope, and this effort will continue if the Zope community # continues to grow. This is one way to assure that growth. # # 4. All advertising materials and documentation mentioning # features derived from or use of this software must display # the following acknowledgement: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # In the event that the product being advertised includes an # intact Zope distribution (with copyright and license included) # then this clause is waived. # # 5. Names associated with Zope or Digital Creations must not be used to # endorse or promote products derived from this software without # prior written permission from Digital Creations. # # 6. Modified redistributions of any form whatsoever must retain # the following acknowledgment: # # "This product includes software developed by Digital Creations # for use in the Z Object Publishing Environment # (http://www.zope.org/)." # # Intact (re-)distributions of any official Zope release do not # require an external acknowledgement. # # 7. Modifications are encouraged but must be packaged separately as # patches to official Zope releases. Distributions that do not # clearly separate the patches from the original work must be clearly # labeled as unofficial distributions. Modifications which do not # carry the name Zope may be packaged in any form, as long as they # conform to all of the clauses above. # # # Disclaimer # # THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # # This software consists of contributions made by Digital Creations and # many individuals on behalf of Digital Creations. Specific # attributions are listed in the accompanying credits file. # ############################################################################## """Provide support for linking an external transaction manager with Zope's """ class TM: """Mix-in class that provides transaction management support A sub class should call self._register() whenever it performs any transaction-dependent operations (e.g. sql statements). The sub class will need to override _finish, to finallize work, _abort, to roll-back work, and perhaps _begin, if any work is needed at the start of a transaction. """ _registered=None def _begin(self): pass def _register(self): if not self._registered: try: get_transaction().register(Surrogate(self)) self._begin() self._registered=1 except: pass def tpc_begin(self, *ignored): pass commit=tpc_abort=tpc_begin def _finish(self): self.db.commit() def _abort(self): self.db.rollback() def tpc_finish(self, *ignored): try: self._finish() finally: self._registered=0 def abort(self, *ignored): try: self._abort() finally: self._registered=0 class Surrogate: def __init__(self, db): self._p_jar=db self.__inform_commit__=db.tpc_finish self.__inform_abort__=db.tpc_abort Shared/DC/ZRDB/www/DBAdapterFolder_icon.gif100666 0 0 1601 6441016312 21066 0ustar00unknownunknown 0 0 GIF89aPPP@@@@@!,^ :X #`H1C4