annotate DBInterface.py @ 2:881fcea6a57d

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