comparison DBInterface.py @ 2:881fcea6a57d

new base class (unused)
author casties
date Mon, 14 Feb 2011 11:11:34 +0100
parents
children d70e57193731
comparison
equal deleted inserted replaced
1:083b771b1ca9 2:881fcea6a57d
1 '''
2 Created on 14.2.2011
3
4 @author: casties
5 '''
6
7 import logging
8 import psycopg2
9 # make psycopg use unicode objects
10 import psycopg2.extensions
11 psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
12 psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
13
14 from Products.ZSQLMethods.SQL import SQLConnectionIDs
15
16
17 def unicodify(s,alternate='latin-1'):
18 """decode str (utf-8 or latin-1 representation) into unicode object"""
19 if not s:
20 return u""
21 if isinstance(s, str):
22 try:
23 return s.decode('utf-8')
24 except:
25 return s.decode(alternate)
26 else:
27 return s
28
29 def utf8ify(s):
30 """encode unicode object or string into byte string in utf-8 representation.
31 assumes string objects to be utf-8"""
32 if not s:
33 return ""
34 if isinstance(s, str):
35 return s
36 else:
37 return s.encode('utf-8')
38
39 def getTextFromNode(node):
40 """get the cdata content of a XML node"""
41 if node is None:
42 return ""
43
44 if isinstance(node, list):
45 nodelist = node
46 else:
47 nodelist=node.childNodes
48
49 rc = ""
50 for node in nodelist:
51 if node.nodeType == node.TEXT_NODE:
52 rc = rc + node.data
53 return rc
54
55 def sqlName(s,lc=True):
56 """returns restricted ASCII-only version of string"""
57 if s is None:
58 return ""
59
60 # all else -> "_"
61 s = re.sub(r'[^A-Za-z0-9_]','_',s)
62 if lc:
63 return s.lower()
64
65 return s
66
67
68 class DbInterface:
69 """Object for database queries
70 """
71 def __init__(self, id, title, connection_id=None):
72 """init"""
73 self.id = id
74 self.title = title
75 # database connection id
76 self.connection_id = connection_id
77
78 def getCursor(self,autocommit=True):
79 """returns fresh DB cursor"""
80 conn = getattr(self,"_v_database_connection",None)
81 if conn is None:
82 # create a new connection object
83 try:
84 if self.connection_id is None:
85 # try to take the first existing ID
86 connids = SQLConnectionIDs(self)
87 if len(connids) > 0:
88 connection_id = connids[0][0]
89 self.connection_id = connection_id
90 logging.debug("connection_id: %s"%repr(connection_id))
91
92 da = getattr(self, self.connection_id)
93 da.connect('')
94 # we copy the DAs database connection
95 conn = da._v_database_connection
96 #conn._register() # register with the Zope transaction system
97 self._v_database_connection = conn
98 except Exception, e:
99 raise IOError("No database connection! (%s)"%str(e))
100
101 cursor = conn.getcursor()
102 if autocommit:
103 # is there a better version to get to the connection?
104 cursor.connection.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
105
106 return cursor
107
108 def getFieldNameMap(self,fields):
109 """returns a dict mapping field names to row indexes"""
110 map = {}
111 i = 0
112 for f in fields:
113 map[f[0]] = i
114 i += 1
115
116 return map
117
118 def executeSQL(self, query, args=None, hasResult=True, autocommit=True):
119 """execute query with args on database and return all results.
120 result format: {"fields":fields, "rows":data}"""
121 logging.debug("executeSQL query=%s args=%s"%(query,args))
122 cur = self.getCursor(autocommit=autocommit)
123 if args is not None:
124 # make sure args is a list
125 if isinstance(args,basestring):
126 args = (args,)
127
128 cur.execute(query, args)
129 # description of returned fields
130 fields = cur.description
131 if hasResult:
132 # get all data in an array
133 data = cur.fetchall()
134 cur.close()
135 #logging.debug("fields: %s"%repr(fields))
136 #logging.debug("rows: %s"%repr(data))
137 return {"fields":fields, "rows":data}
138 else:
139 cur.close()
140 return None
141