# HG changeset patch # User casties # Date 1297678294 -3600 # Node ID 881fcea6a57dab1982dd9598459c055e90df1e9a # Parent 083b771b1ca973ba7ef3b43b117e0dfedcd121e5 new base class (unused) diff -r 083b771b1ca9 -r 881fcea6a57d DBInterface.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DBInterface.py Mon Feb 14 11:11:34 2011 +0100 @@ -0,0 +1,141 @@ +''' +Created on 14.2.2011 + +@author: casties +''' + +import logging +import psycopg2 +# make psycopg use unicode objects +import psycopg2.extensions +psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) +psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY) + +from Products.ZSQLMethods.SQL import SQLConnectionIDs + + +def unicodify(s,alternate='latin-1'): + """decode str (utf-8 or latin-1 representation) into unicode object""" + if not s: + return u"" + if isinstance(s, str): + try: + return s.decode('utf-8') + except: + return s.decode(alternate) + else: + return s + +def utf8ify(s): + """encode unicode object or string into byte string in utf-8 representation. + assumes string objects to be utf-8""" + if not s: + return "" + if isinstance(s, str): + return s + else: + return s.encode('utf-8') + +def getTextFromNode(node): + """get the cdata content of a XML node""" + if node is None: + return "" + + if isinstance(node, list): + nodelist = node + else: + nodelist=node.childNodes + + rc = "" + for node in nodelist: + if node.nodeType == node.TEXT_NODE: + rc = rc + node.data + return rc + +def sqlName(s,lc=True): + """returns restricted ASCII-only version of string""" + if s is None: + return "" + + # all else -> "_" + s = re.sub(r'[^A-Za-z0-9_]','_',s) + if lc: + return s.lower() + + return s + + +class DbInterface: + """Object for database queries + """ + def __init__(self, id, title, connection_id=None): + """init""" + self.id = id + self.title = title + # database connection id + self.connection_id = connection_id + + def getCursor(self,autocommit=True): + """returns fresh DB cursor""" + conn = getattr(self,"_v_database_connection",None) + if conn is None: + # create a new connection object + try: + if self.connection_id is None: + # try to take the first existing ID + connids = SQLConnectionIDs(self) + if len(connids) > 0: + connection_id = connids[0][0] + self.connection_id = connection_id + logging.debug("connection_id: %s"%repr(connection_id)) + + da = getattr(self, self.connection_id) + da.connect('') + # we copy the DAs database connection + conn = da._v_database_connection + #conn._register() # register with the Zope transaction system + self._v_database_connection = conn + except Exception, e: + raise IOError("No database connection! (%s)"%str(e)) + + cursor = conn.getcursor() + if autocommit: + # is there a better version to get to the connection? + cursor.connection.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) + + return cursor + + def getFieldNameMap(self,fields): + """returns a dict mapping field names to row indexes""" + map = {} + i = 0 + for f in fields: + map[f[0]] = i + i += 1 + + return map + + def executeSQL(self, query, args=None, hasResult=True, autocommit=True): + """execute query with args on database and return all results. + result format: {"fields":fields, "rows":data}""" + logging.debug("executeSQL query=%s args=%s"%(query,args)) + cur = self.getCursor(autocommit=autocommit) + if args is not None: + # make sure args is a list + if isinstance(args,basestring): + args = (args,) + + cur.execute(query, args) + # description of returned fields + fields = cur.description + if hasResult: + # get all data in an array + data = cur.fetchall() + cur.close() + #logging.debug("fields: %s"%repr(fields)) + #logging.debug("rows: %s"%repr(data)) + return {"fields":fields, "rows":data} + else: + cur.close() + return None + diff -r 083b771b1ca9 -r 881fcea6a57d RestDbInterface.py --- a/RestDbInterface.py Fri Feb 11 15:08:26 2011 +0100 +++ b/RestDbInterface.py Mon Feb 14 11:11:34 2011 +0100 @@ -7,7 +7,6 @@ from OFS.Folder import Folder from Products.PageTemplates.PageTemplateFile import PageTemplateFile from AccessControl import getSecurityManager, Unauthorized -from Products.ZSQLExtend import ZSQLExtend import logging import re import json