annotate DBInterface.py @ 4:0ade331198de

first version of ZDBInlineSearch
author casties
date Tue, 15 Feb 2011 19:59:07 +0100
parents d70e57193731
children 1b25a85a2165
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
1 '''
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
2 Created on 14.2.2011
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
3
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
4 @author: casties
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
5 '''
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
6
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
7 import logging
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
8 import psycopg2
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
9 # make psycopg use unicode objects
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
10 import psycopg2.extensions
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
11 psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
12 psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
13
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
14 from Products.ZSQLMethods.SQL import SQLConnectionIDs
3
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
15 from Shared.DC.ZRDB.Results import Results
2
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
16
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
17
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
18 def unicodify(s,alternate='latin-1'):
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
19 """decode str (utf-8 or latin-1 representation) into unicode object"""
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
20 if not s:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
21 return u""
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
22 if isinstance(s, str):
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
23 try:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
24 return s.decode('utf-8')
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
25 except:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
26 return s.decode(alternate)
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
27 else:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
28 return s
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
29
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
30 def utf8ify(s):
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
31 """encode unicode object or string into byte string in utf-8 representation.
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
32 assumes string objects to be utf-8"""
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
33 if not s:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
34 return ""
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
35 if isinstance(s, str):
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
36 return s
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
37 else:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
38 return s.encode('utf-8')
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
39
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
40 def getTextFromNode(node):
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
41 """get the cdata content of a XML node"""
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
42 if node is None:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
43 return ""
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
44
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
45 if isinstance(node, list):
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
46 nodelist = node
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
47 else:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
48 nodelist=node.childNodes
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
49
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
50 rc = ""
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
51 for node in nodelist:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
52 if node.nodeType == node.TEXT_NODE:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
53 rc = rc + node.data
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
54 return rc
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
55
4
0ade331198de first version of ZDBInlineSearch
casties
parents: 3
diff changeset
56 def sqlName(s, lc=True, more=''):
2
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
57 """returns restricted ASCII-only version of string"""
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
58 if s is None:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
59 return ""
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
60
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
61 # all else -> "_"
4
0ade331198de first version of ZDBInlineSearch
casties
parents: 3
diff changeset
62 s = re.sub('[^A-Za-z0-9_'+more+']','_',s)
2
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
63 if lc:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
64 return s.lower()
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
65
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
66 return s
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
67
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
68
3
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
69 class DBInterface:
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
70 """Object for database queries"""
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
71
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
72 def __init__(self, connection_id=None):
2
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
73 """init"""
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
74 # database connection id
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
75 self.connection_id = connection_id
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
76
3
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
77 def getConnectionIDs(self):
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
78 """return list of available connection ids"""
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
79 return SQLConnectionIDs(self)
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
80
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
81 def getDB(self):
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
82 """returns DB object"""
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
83 # TODO: can we cache and reuse a DB object?
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
84 if self.connection_id is None:
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
85 # try to take the first existing ID
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
86 connids = self.getConnectionIDs()
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
87 if len(connids) > 0:
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
88 connection_id = connids[0][1]
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
89 self.connection_id = connection_id
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
90 logging.debug("connection_id: %s"%repr(connection_id))
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
91
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
92 # get Connection instance
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
93 con = getattr(self, self.connection_id)
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
94 # call to get db object
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
95 db = con()
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
96 return db
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
97
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
98 def executeZSQL(self, query, args=None, max_rows=None):
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
99 """execute query with args on the database and return all results as Result object."""
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
100 logging.debug("executeZSQL query=%s args=%s"%(query,args))
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
101 dbc = self.getDB()
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
102 res = dbc.query(query, max_rows=max_rows, query_data=args)
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
103 # return result set as Result object with Brains
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
104 return Results(res)
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
105
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
106
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
107 #
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
108 # Old way using cursor from DA
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
109 #
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
110
2
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
111 def getCursor(self,autocommit=True):
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
112 """returns fresh DB cursor"""
3
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
113 conn = getattr(self,"_v_database_connection", None)
2
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
114 if conn is None:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
115 # create a new connection object
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
116 try:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
117 if self.connection_id is None:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
118 # try to take the first existing ID
3
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
119 connids = self.getConnectionIDs()
2
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
120 if len(connids) > 0:
3
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
121 connection_id = connids[0][1]
2
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
122 self.connection_id = connection_id
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
123 logging.debug("connection_id: %s"%repr(connection_id))
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
124
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
125 da = getattr(self, self.connection_id)
3
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
126 logging.debug('da=%s'%da)
2
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
127 da.connect('')
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
128 # we copy the DAs database connection
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
129 conn = da._v_database_connection
3
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
130 #conn._register() # register with the Zope transaction system(?)
2
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
131 self._v_database_connection = conn
3
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
132
2
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
133 except Exception, e:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
134 raise IOError("No database connection! (%s)"%str(e))
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
135
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
136 cursor = conn.getcursor()
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
137 if autocommit:
3
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
138 # TODO: is there a better version to get to the connection?
2
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
139 cursor.connection.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
140
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
141 return cursor
3
d70e57193731 new executeZSQL method that returns Zope Results.
casties
parents: 2
diff changeset
142
2
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
143 def getFieldNameMap(self,fields):
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
144 """returns a dict mapping field names to row indexes"""
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
145 map = {}
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
146 i = 0
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
147 for f in fields:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
148 map[f[0]] = i
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
149 i += 1
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
150
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
151 return map
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
152
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
153 def executeSQL(self, query, args=None, hasResult=True, autocommit=True):
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
154 """execute query with args on database and return all results.
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
155 result format: {"fields":fields, "rows":data}"""
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
156 logging.debug("executeSQL query=%s args=%s"%(query,args))
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
157 cur = self.getCursor(autocommit=autocommit)
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
158 if args is not None:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
159 # make sure args is a list
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
160 if isinstance(args,basestring):
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
161 args = (args,)
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
162
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
163 cur.execute(query, args)
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
164 # description of returned fields
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
165 fields = cur.description
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
166 if hasResult:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
167 # get all data in an array
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
168 data = cur.fetchall()
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
169 cur.close()
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
170 #logging.debug("fields: %s"%repr(fields))
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
171 #logging.debug("rows: %s"%repr(data))
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
172 return {"fields":fields, "rows":data}
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
173 else:
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
174 cur.close()
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
175 return None
881fcea6a57d new base class (unused)
casties
parents:
diff changeset
176