annotate RestDbInterface.py @ 0:09361041be51

first checkin
author casties
date Fri, 11 Feb 2011 15:05:23 +0100
parents
children 881fcea6a57d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
09361041be51 first checkin
casties
parents:
diff changeset
1 '''
09361041be51 first checkin
casties
parents:
diff changeset
2 Created on 19.5.2010
09361041be51 first checkin
casties
parents:
diff changeset
3
09361041be51 first checkin
casties
parents:
diff changeset
4 @author: casties
09361041be51 first checkin
casties
parents:
diff changeset
5 '''
09361041be51 first checkin
casties
parents:
diff changeset
6
09361041be51 first checkin
casties
parents:
diff changeset
7 from OFS.Folder import Folder
09361041be51 first checkin
casties
parents:
diff changeset
8 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
09361041be51 first checkin
casties
parents:
diff changeset
9 from AccessControl import getSecurityManager, Unauthorized
09361041be51 first checkin
casties
parents:
diff changeset
10 from Products.ZSQLExtend import ZSQLExtend
09361041be51 first checkin
casties
parents:
diff changeset
11 import logging
09361041be51 first checkin
casties
parents:
diff changeset
12 import re
09361041be51 first checkin
casties
parents:
diff changeset
13 import json
09361041be51 first checkin
casties
parents:
diff changeset
14 import time
09361041be51 first checkin
casties
parents:
diff changeset
15 import psycopg2
09361041be51 first checkin
casties
parents:
diff changeset
16 # make psycopg use unicode objects
09361041be51 first checkin
casties
parents:
diff changeset
17 import psycopg2.extensions
09361041be51 first checkin
casties
parents:
diff changeset
18 psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
09361041be51 first checkin
casties
parents:
diff changeset
19 psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
09361041be51 first checkin
casties
parents:
diff changeset
20
09361041be51 first checkin
casties
parents:
diff changeset
21 from zope.interface import implements
09361041be51 first checkin
casties
parents:
diff changeset
22 from zope.publisher.interfaces import IPublishTraverse
09361041be51 first checkin
casties
parents:
diff changeset
23 from ZPublisher.BaseRequest import DefaultPublishTraverse
09361041be51 first checkin
casties
parents:
diff changeset
24
09361041be51 first checkin
casties
parents:
diff changeset
25
09361041be51 first checkin
casties
parents:
diff changeset
26 def unicodify(s,alternate='latin-1'):
09361041be51 first checkin
casties
parents:
diff changeset
27 """decode str (utf-8 or latin-1 representation) into unicode object"""
09361041be51 first checkin
casties
parents:
diff changeset
28 if not s:
09361041be51 first checkin
casties
parents:
diff changeset
29 return u""
09361041be51 first checkin
casties
parents:
diff changeset
30 if isinstance(s, str):
09361041be51 first checkin
casties
parents:
diff changeset
31 try:
09361041be51 first checkin
casties
parents:
diff changeset
32 return s.decode('utf-8')
09361041be51 first checkin
casties
parents:
diff changeset
33 except:
09361041be51 first checkin
casties
parents:
diff changeset
34 return s.decode(alternate)
09361041be51 first checkin
casties
parents:
diff changeset
35 else:
09361041be51 first checkin
casties
parents:
diff changeset
36 return s
09361041be51 first checkin
casties
parents:
diff changeset
37
09361041be51 first checkin
casties
parents:
diff changeset
38 def utf8ify(s):
09361041be51 first checkin
casties
parents:
diff changeset
39 """encode unicode object or string into byte string in utf-8 representation.
09361041be51 first checkin
casties
parents:
diff changeset
40 assumes string objects to be utf-8"""
09361041be51 first checkin
casties
parents:
diff changeset
41 if not s:
09361041be51 first checkin
casties
parents:
diff changeset
42 return ""
09361041be51 first checkin
casties
parents:
diff changeset
43 if isinstance(s, str):
09361041be51 first checkin
casties
parents:
diff changeset
44 return s
09361041be51 first checkin
casties
parents:
diff changeset
45 else:
09361041be51 first checkin
casties
parents:
diff changeset
46 return s.encode('utf-8')
09361041be51 first checkin
casties
parents:
diff changeset
47
09361041be51 first checkin
casties
parents:
diff changeset
48 def getTextFromNode(node):
09361041be51 first checkin
casties
parents:
diff changeset
49 """get the cdata content of a XML node"""
09361041be51 first checkin
casties
parents:
diff changeset
50 if node is None:
09361041be51 first checkin
casties
parents:
diff changeset
51 return ""
09361041be51 first checkin
casties
parents:
diff changeset
52
09361041be51 first checkin
casties
parents:
diff changeset
53 if isinstance(node, list):
09361041be51 first checkin
casties
parents:
diff changeset
54 nodelist = node
09361041be51 first checkin
casties
parents:
diff changeset
55 else:
09361041be51 first checkin
casties
parents:
diff changeset
56 nodelist=node.childNodes
09361041be51 first checkin
casties
parents:
diff changeset
57
09361041be51 first checkin
casties
parents:
diff changeset
58 rc = ""
09361041be51 first checkin
casties
parents:
diff changeset
59 for node in nodelist:
09361041be51 first checkin
casties
parents:
diff changeset
60 if node.nodeType == node.TEXT_NODE:
09361041be51 first checkin
casties
parents:
diff changeset
61 rc = rc + node.data
09361041be51 first checkin
casties
parents:
diff changeset
62 return rc
09361041be51 first checkin
casties
parents:
diff changeset
63
09361041be51 first checkin
casties
parents:
diff changeset
64 def sqlName(s,lc=True):
09361041be51 first checkin
casties
parents:
diff changeset
65 """returns restricted ASCII-only version of string"""
09361041be51 first checkin
casties
parents:
diff changeset
66 if s is None:
09361041be51 first checkin
casties
parents:
diff changeset
67 return ""
09361041be51 first checkin
casties
parents:
diff changeset
68
09361041be51 first checkin
casties
parents:
diff changeset
69 # all else -> "_"
09361041be51 first checkin
casties
parents:
diff changeset
70 s = re.sub(r'[^A-Za-z0-9_]','_',s)
09361041be51 first checkin
casties
parents:
diff changeset
71 if lc:
09361041be51 first checkin
casties
parents:
diff changeset
72 return s.lower()
09361041be51 first checkin
casties
parents:
diff changeset
73
09361041be51 first checkin
casties
parents:
diff changeset
74 return s
09361041be51 first checkin
casties
parents:
diff changeset
75
09361041be51 first checkin
casties
parents:
diff changeset
76
09361041be51 first checkin
casties
parents:
diff changeset
77 class RestDbInterface(Folder):
09361041be51 first checkin
casties
parents:
diff changeset
78 """Object for RESTful database queries
09361041be51 first checkin
casties
parents:
diff changeset
79 path schema: /db/{schema}/{table}/
09361041be51 first checkin
casties
parents:
diff changeset
80 omitting table gives a list of schemas
09361041be51 first checkin
casties
parents:
diff changeset
81 omitting table and schema gives a list of schemas
09361041be51 first checkin
casties
parents:
diff changeset
82 """
09361041be51 first checkin
casties
parents:
diff changeset
83 implements(IPublishTraverse)
09361041be51 first checkin
casties
parents:
diff changeset
84
09361041be51 first checkin
casties
parents:
diff changeset
85 meta_type="RESTdb"
09361041be51 first checkin
casties
parents:
diff changeset
86 manage_options=Folder.manage_options+(
09361041be51 first checkin
casties
parents:
diff changeset
87 {'label':'Config','action':'manage_editRestDbInterfaceForm'},
09361041be51 first checkin
casties
parents:
diff changeset
88 )
09361041be51 first checkin
casties
parents:
diff changeset
89
09361041be51 first checkin
casties
parents:
diff changeset
90 # management templates
09361041be51 first checkin
casties
parents:
diff changeset
91 manage_editRestDbInterfaceForm=PageTemplateFile('zpt/editRestDbInterface',globals())
09361041be51 first checkin
casties
parents:
diff changeset
92
09361041be51 first checkin
casties
parents:
diff changeset
93 # data templates
09361041be51 first checkin
casties
parents:
diff changeset
94 XML_index = PageTemplateFile('zpt/XML_index', globals())
09361041be51 first checkin
casties
parents:
diff changeset
95 XML_schema = PageTemplateFile('zpt/XML_schema', globals())
09361041be51 first checkin
casties
parents:
diff changeset
96 XML_schema_table = PageTemplateFile('zpt/XML_schema_table', globals())
09361041be51 first checkin
casties
parents:
diff changeset
97 HTML_index = PageTemplateFile('zpt/HTML_index', globals())
09361041be51 first checkin
casties
parents:
diff changeset
98 HTML_schema = PageTemplateFile('zpt/HTML_schema', globals())
09361041be51 first checkin
casties
parents:
diff changeset
99 HTML_schema_table = PageTemplateFile('zpt/HTML_schema_table', globals())
09361041be51 first checkin
casties
parents:
diff changeset
100 JSONHTML_index = PageTemplateFile('zpt/JSONHTML_index', globals())
09361041be51 first checkin
casties
parents:
diff changeset
101 JSONHTML_schema = PageTemplateFile('zpt/JSONHTML_schema', globals())
09361041be51 first checkin
casties
parents:
diff changeset
102 JSONHTML_schema_table = PageTemplateFile('zpt/JSONHTML_schema_table', globals())
09361041be51 first checkin
casties
parents:
diff changeset
103 # JSON_* templates are scripts
09361041be51 first checkin
casties
parents:
diff changeset
104 def JSON_index(self):
09361041be51 first checkin
casties
parents:
diff changeset
105 """JSON index function"""
09361041be51 first checkin
casties
parents:
diff changeset
106 self.REQUEST.RESPONSE.setHeader("Content-Type", "application/json")
09361041be51 first checkin
casties
parents:
diff changeset
107 json.dump(self.getListOfSchemas(), self.REQUEST.RESPONSE)
09361041be51 first checkin
casties
parents:
diff changeset
108
09361041be51 first checkin
casties
parents:
diff changeset
109 def JSON_schema(self,schema):
09361041be51 first checkin
casties
parents:
diff changeset
110 """JSON index function"""
09361041be51 first checkin
casties
parents:
diff changeset
111 self.REQUEST.RESPONSE.setHeader("Content-Type", "application/json")
09361041be51 first checkin
casties
parents:
diff changeset
112 json.dump(self.getListOfTables(schema), self.REQUEST.RESPONSE)
09361041be51 first checkin
casties
parents:
diff changeset
113
09361041be51 first checkin
casties
parents:
diff changeset
114 def JSON_schema_table(self,schema,table):
09361041be51 first checkin
casties
parents:
diff changeset
115 """JSON index function"""
09361041be51 first checkin
casties
parents:
diff changeset
116 self.REQUEST.RESPONSE.setHeader("Content-Type", "application/json")
09361041be51 first checkin
casties
parents:
diff changeset
117 json.dump(self.getTable(schema, table), self.REQUEST.RESPONSE)
09361041be51 first checkin
casties
parents:
diff changeset
118
09361041be51 first checkin
casties
parents:
diff changeset
119
09361041be51 first checkin
casties
parents:
diff changeset
120 def __init__(self, id, title, connection_id=None):
09361041be51 first checkin
casties
parents:
diff changeset
121 """init"""
09361041be51 first checkin
casties
parents:
diff changeset
122 self.id = id
09361041be51 first checkin
casties
parents:
diff changeset
123 self.title = title
09361041be51 first checkin
casties
parents:
diff changeset
124 # database connection id
09361041be51 first checkin
casties
parents:
diff changeset
125 self.connection_id = connection_id
09361041be51 first checkin
casties
parents:
diff changeset
126 # create template folder
09361041be51 first checkin
casties
parents:
diff changeset
127 self.manage_addFolder('template')
09361041be51 first checkin
casties
parents:
diff changeset
128
09361041be51 first checkin
casties
parents:
diff changeset
129
09361041be51 first checkin
casties
parents:
diff changeset
130 def getRestDbUrl(self):
09361041be51 first checkin
casties
parents:
diff changeset
131 """returns url to the RestDb instance"""
09361041be51 first checkin
casties
parents:
diff changeset
132 return self.absolute_url()
09361041be51 first checkin
casties
parents:
diff changeset
133
09361041be51 first checkin
casties
parents:
diff changeset
134 def getJsonString(self,object):
09361041be51 first checkin
casties
parents:
diff changeset
135 """returns a JSON formatted string from object"""
09361041be51 first checkin
casties
parents:
diff changeset
136 return json.dumps(object)
09361041be51 first checkin
casties
parents:
diff changeset
137
09361041be51 first checkin
casties
parents:
diff changeset
138 def getCursor(self,autocommit=True):
09361041be51 first checkin
casties
parents:
diff changeset
139 """returns fresh DB cursor"""
09361041be51 first checkin
casties
parents:
diff changeset
140 conn = getattr(self,"_v_database_connection",None)
09361041be51 first checkin
casties
parents:
diff changeset
141 if conn is None:
09361041be51 first checkin
casties
parents:
diff changeset
142 # create a new connection object
09361041be51 first checkin
casties
parents:
diff changeset
143 try:
09361041be51 first checkin
casties
parents:
diff changeset
144 if self.connection_id is None:
09361041be51 first checkin
casties
parents:
diff changeset
145 # try to take the first existing ID
09361041be51 first checkin
casties
parents:
diff changeset
146 connids = SQLConnectionIDs(self)
09361041be51 first checkin
casties
parents:
diff changeset
147 if len(connids) > 0:
09361041be51 first checkin
casties
parents:
diff changeset
148 connection_id = connids[0][0]
09361041be51 first checkin
casties
parents:
diff changeset
149 self.connection_id = connection_id
09361041be51 first checkin
casties
parents:
diff changeset
150 logging.debug("connection_id: %s"%repr(connection_id))
09361041be51 first checkin
casties
parents:
diff changeset
151
09361041be51 first checkin
casties
parents:
diff changeset
152 da = getattr(self, self.connection_id)
09361041be51 first checkin
casties
parents:
diff changeset
153 da.connect('')
09361041be51 first checkin
casties
parents:
diff changeset
154 # we copy the DAs database connection
09361041be51 first checkin
casties
parents:
diff changeset
155 conn = da._v_database_connection
09361041be51 first checkin
casties
parents:
diff changeset
156 #conn._register() # register with the Zope transaction system
09361041be51 first checkin
casties
parents:
diff changeset
157 self._v_database_connection = conn
09361041be51 first checkin
casties
parents:
diff changeset
158 except Exception, e:
09361041be51 first checkin
casties
parents:
diff changeset
159 raise IOError("No database connection! (%s)"%str(e))
09361041be51 first checkin
casties
parents:
diff changeset
160
09361041be51 first checkin
casties
parents:
diff changeset
161 cursor = conn.getcursor()
09361041be51 first checkin
casties
parents:
diff changeset
162 if autocommit:
09361041be51 first checkin
casties
parents:
diff changeset
163 # is there a better version to get to the connection?
09361041be51 first checkin
casties
parents:
diff changeset
164 cursor.connection.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
09361041be51 first checkin
casties
parents:
diff changeset
165
09361041be51 first checkin
casties
parents:
diff changeset
166 return cursor
09361041be51 first checkin
casties
parents:
diff changeset
167
09361041be51 first checkin
casties
parents:
diff changeset
168 def getFieldNameMap(self,fields):
09361041be51 first checkin
casties
parents:
diff changeset
169 """returns a dict mapping field names to row indexes"""
09361041be51 first checkin
casties
parents:
diff changeset
170 map = {}
09361041be51 first checkin
casties
parents:
diff changeset
171 i = 0
09361041be51 first checkin
casties
parents:
diff changeset
172 for f in fields:
09361041be51 first checkin
casties
parents:
diff changeset
173 map[f[0]] = i
09361041be51 first checkin
casties
parents:
diff changeset
174 i += 1
09361041be51 first checkin
casties
parents:
diff changeset
175
09361041be51 first checkin
casties
parents:
diff changeset
176 return map
09361041be51 first checkin
casties
parents:
diff changeset
177
09361041be51 first checkin
casties
parents:
diff changeset
178 def executeSQL(self, query, args=None, hasResult=True, autocommit=True):
09361041be51 first checkin
casties
parents:
diff changeset
179 """execute query with args on database and return all results.
09361041be51 first checkin
casties
parents:
diff changeset
180 result format: {"fields":fields, "rows":data}"""
09361041be51 first checkin
casties
parents:
diff changeset
181 logging.debug("executeSQL query=%s args=%s"%(query,args))
09361041be51 first checkin
casties
parents:
diff changeset
182 cur = self.getCursor(autocommit=autocommit)
09361041be51 first checkin
casties
parents:
diff changeset
183 if args is not None:
09361041be51 first checkin
casties
parents:
diff changeset
184 # make sure args is a list
09361041be51 first checkin
casties
parents:
diff changeset
185 if isinstance(args,basestring):
09361041be51 first checkin
casties
parents:
diff changeset
186 args = (args,)
09361041be51 first checkin
casties
parents:
diff changeset
187
09361041be51 first checkin
casties
parents:
diff changeset
188 cur.execute(query, args)
09361041be51 first checkin
casties
parents:
diff changeset
189 # description of returned fields
09361041be51 first checkin
casties
parents:
diff changeset
190 fields = cur.description
09361041be51 first checkin
casties
parents:
diff changeset
191 if hasResult:
09361041be51 first checkin
casties
parents:
diff changeset
192 # get all data in an array
09361041be51 first checkin
casties
parents:
diff changeset
193 data = cur.fetchall()
09361041be51 first checkin
casties
parents:
diff changeset
194 cur.close()
09361041be51 first checkin
casties
parents:
diff changeset
195 #logging.debug("fields: %s"%repr(fields))
09361041be51 first checkin
casties
parents:
diff changeset
196 #logging.debug("rows: %s"%repr(data))
09361041be51 first checkin
casties
parents:
diff changeset
197 return {"fields":fields, "rows":data}
09361041be51 first checkin
casties
parents:
diff changeset
198 else:
09361041be51 first checkin
casties
parents:
diff changeset
199 cur.close()
09361041be51 first checkin
casties
parents:
diff changeset
200 return None
09361041be51 first checkin
casties
parents:
diff changeset
201
09361041be51 first checkin
casties
parents:
diff changeset
202 def isAllowed(self,action,schema,table,user=None):
09361041be51 first checkin
casties
parents:
diff changeset
203 """returns if the requested action on the table is allowed"""
09361041be51 first checkin
casties
parents:
diff changeset
204 if user is None:
09361041be51 first checkin
casties
parents:
diff changeset
205 user = self.REQUEST.get('AUTHENTICATED_USER',None)
09361041be51 first checkin
casties
parents:
diff changeset
206 logging.debug("isAllowed action=%s schema=%s table=%s user=%s"%(action,schema,table,user))
09361041be51 first checkin
casties
parents:
diff changeset
207 # no default policy!
09361041be51 first checkin
casties
parents:
diff changeset
208 return True
09361041be51 first checkin
casties
parents:
diff changeset
209
09361041be51 first checkin
casties
parents:
diff changeset
210
09361041be51 first checkin
casties
parents:
diff changeset
211 def publishTraverse(self,request,name):
09361041be51 first checkin
casties
parents:
diff changeset
212 """change the traversal"""
09361041be51 first checkin
casties
parents:
diff changeset
213 # get stored path
09361041be51 first checkin
casties
parents:
diff changeset
214 path = request.get('restdb_path', [])
09361041be51 first checkin
casties
parents:
diff changeset
215 logging.debug("publishtraverse: name=%s restdb_path=%s"%(name,path))
09361041be51 first checkin
casties
parents:
diff changeset
216
09361041be51 first checkin
casties
parents:
diff changeset
217 if name in ("index_html", "PUT"):
09361041be51 first checkin
casties
parents:
diff changeset
218 # end of traversal
09361041be51 first checkin
casties
parents:
diff changeset
219 if request.get("method") == "POST" and request.get("action",None) == "PUT":
09361041be51 first checkin
casties
parents:
diff changeset
220 # fake PUT by POST with action=PUT
09361041be51 first checkin
casties
parents:
diff changeset
221 name = "PUT"
09361041be51 first checkin
casties
parents:
diff changeset
222
09361041be51 first checkin
casties
parents:
diff changeset
223 return getattr(self, name)
09361041be51 first checkin
casties
parents:
diff changeset
224 #TODO: should we check more?
09361041be51 first checkin
casties
parents:
diff changeset
225 else:
09361041be51 first checkin
casties
parents:
diff changeset
226 # traverse
09361041be51 first checkin
casties
parents:
diff changeset
227 if len(path) == 0:
09361041be51 first checkin
casties
parents:
diff changeset
228 # first segment
09361041be51 first checkin
casties
parents:
diff changeset
229 if name == 'db':
09361041be51 first checkin
casties
parents:
diff changeset
230 # virtual path -- continue traversing
09361041be51 first checkin
casties
parents:
diff changeset
231 path = [name]
09361041be51 first checkin
casties
parents:
diff changeset
232 request['restdb_path'] = path
09361041be51 first checkin
casties
parents:
diff changeset
233 else:
09361041be51 first checkin
casties
parents:
diff changeset
234 # try real path
09361041be51 first checkin
casties
parents:
diff changeset
235 tr = DefaultPublishTraverse(self, request)
09361041be51 first checkin
casties
parents:
diff changeset
236 ob = tr.publishTraverse(request, name)
09361041be51 first checkin
casties
parents:
diff changeset
237 return ob
09361041be51 first checkin
casties
parents:
diff changeset
238 else:
09361041be51 first checkin
casties
parents:
diff changeset
239 path.append(name)
09361041be51 first checkin
casties
parents:
diff changeset
240
09361041be51 first checkin
casties
parents:
diff changeset
241 # continue traversing
09361041be51 first checkin
casties
parents:
diff changeset
242 return self
09361041be51 first checkin
casties
parents:
diff changeset
243
09361041be51 first checkin
casties
parents:
diff changeset
244
09361041be51 first checkin
casties
parents:
diff changeset
245 def index_html(self,REQUEST,RESPONSE):
09361041be51 first checkin
casties
parents:
diff changeset
246 """index method"""
09361041be51 first checkin
casties
parents:
diff changeset
247 # ReST path was stored in request
09361041be51 first checkin
casties
parents:
diff changeset
248 path = REQUEST.get('restdb_path',[])
09361041be51 first checkin
casties
parents:
diff changeset
249
09361041be51 first checkin
casties
parents:
diff changeset
250 # type and format are real parameter
09361041be51 first checkin
casties
parents:
diff changeset
251 resultFormat = REQUEST.get('format','HTML').upper()
09361041be51 first checkin
casties
parents:
diff changeset
252 queryType = REQUEST.get('type',None)
09361041be51 first checkin
casties
parents:
diff changeset
253
09361041be51 first checkin
casties
parents:
diff changeset
254 logging.debug("index_html path=%s resultFormat=%s queryType=%s"%(path,resultFormat,queryType))
09361041be51 first checkin
casties
parents:
diff changeset
255
09361041be51 first checkin
casties
parents:
diff changeset
256 if queryType is not None:
09361041be51 first checkin
casties
parents:
diff changeset
257 # non-empty queryType -- look for template
09361041be51 first checkin
casties
parents:
diff changeset
258 pt = getattr(self.template, "%s_%s"%(resultFormat,queryType), None)
09361041be51 first checkin
casties
parents:
diff changeset
259 if pt is not None:
09361041be51 first checkin
casties
parents:
diff changeset
260 return pt(format=resultFormat,type=queryType,path=path)
09361041be51 first checkin
casties
parents:
diff changeset
261
09361041be51 first checkin
casties
parents:
diff changeset
262 if len(path) == 1:
09361041be51 first checkin
casties
parents:
diff changeset
263 # list of schemas
09361041be51 first checkin
casties
parents:
diff changeset
264 return self.showListOfSchemas(format=resultFormat)
09361041be51 first checkin
casties
parents:
diff changeset
265 elif len(path) == 2:
09361041be51 first checkin
casties
parents:
diff changeset
266 # list of tables
09361041be51 first checkin
casties
parents:
diff changeset
267 return self.showListOfTables(format=resultFormat,schema=path[1])
09361041be51 first checkin
casties
parents:
diff changeset
268 elif len(path) == 3:
09361041be51 first checkin
casties
parents:
diff changeset
269 # table
09361041be51 first checkin
casties
parents:
diff changeset
270 if REQUEST.get("method") == "POST" and REQUEST.get("create_table_file",None) is not None:
09361041be51 first checkin
casties
parents:
diff changeset
271 # POST to table to check
09361041be51 first checkin
casties
parents:
diff changeset
272 return self.checkTable(format=resultFormat,schema=path[1],table=path[2])
09361041be51 first checkin
casties
parents:
diff changeset
273 # else show table
09361041be51 first checkin
casties
parents:
diff changeset
274 return self.showTable(format=resultFormat,schema=path[1],table=path[2])
09361041be51 first checkin
casties
parents:
diff changeset
275
09361041be51 first checkin
casties
parents:
diff changeset
276 # don't know what to do
09361041be51 first checkin
casties
parents:
diff changeset
277 return str(REQUEST)
09361041be51 first checkin
casties
parents:
diff changeset
278
09361041be51 first checkin
casties
parents:
diff changeset
279 def showTable(self,format='XML',schema='public',table=None,REQUEST=None,RESPONSE=None):
09361041be51 first checkin
casties
parents:
diff changeset
280 """returns PageTemplate with tables"""
09361041be51 first checkin
casties
parents:
diff changeset
281 logging.debug("showtable")
09361041be51 first checkin
casties
parents:
diff changeset
282 if REQUEST is None:
09361041be51 first checkin
casties
parents:
diff changeset
283 REQUEST = self.REQUEST
09361041be51 first checkin
casties
parents:
diff changeset
284
09361041be51 first checkin
casties
parents:
diff changeset
285 # should be cross-site accessible
09361041be51 first checkin
casties
parents:
diff changeset
286 if RESPONSE is None:
09361041be51 first checkin
casties
parents:
diff changeset
287 RESPONSE = self.REQUEST.RESPONSE
09361041be51 first checkin
casties
parents:
diff changeset
288
09361041be51 first checkin
casties
parents:
diff changeset
289 RESPONSE.setHeader('Access-Control-Allow-Origin', '*')
09361041be51 first checkin
casties
parents:
diff changeset
290
09361041be51 first checkin
casties
parents:
diff changeset
291 # everything else has its own template
09361041be51 first checkin
casties
parents:
diff changeset
292 pt = getattr(self.template, '%s_schema_table'%format, None)
09361041be51 first checkin
casties
parents:
diff changeset
293 if pt is None:
09361041be51 first checkin
casties
parents:
diff changeset
294 return "ERROR!! template %s_schema_table not found"%format
09361041be51 first checkin
casties
parents:
diff changeset
295
09361041be51 first checkin
casties
parents:
diff changeset
296 #data = self.getTable(schema,table)
09361041be51 first checkin
casties
parents:
diff changeset
297 return pt(schema=schema,table=table)
09361041be51 first checkin
casties
parents:
diff changeset
298
09361041be51 first checkin
casties
parents:
diff changeset
299 def getTable(self,schema='public',table=None,sortBy=1,username='guest'):
09361041be51 first checkin
casties
parents:
diff changeset
300 """return table data"""
09361041be51 first checkin
casties
parents:
diff changeset
301 logging.debug("gettable")
09361041be51 first checkin
casties
parents:
diff changeset
302 if sortBy:
09361041be51 first checkin
casties
parents:
diff changeset
303 data = self.executeSQL('select * from "%s"."%s" order by %s'%(schema,table,sortBy))
09361041be51 first checkin
casties
parents:
diff changeset
304 else:
09361041be51 first checkin
casties
parents:
diff changeset
305 data = self.executeSQL('select * from "%s"."%s"'%(schema,table))
09361041be51 first checkin
casties
parents:
diff changeset
306 return data
09361041be51 first checkin
casties
parents:
diff changeset
307
09361041be51 first checkin
casties
parents:
diff changeset
308 def hasTable(self,schema='public',table=None,username='guest'):
09361041be51 first checkin
casties
parents:
diff changeset
309 """return if table exists"""
09361041be51 first checkin
casties
parents:
diff changeset
310 logging.debug("hastable")
09361041be51 first checkin
casties
parents:
diff changeset
311 data = self.executeSQL('select 1 from information_schema.tables where table_schema=%s and table_name=%s',(schema,table))
09361041be51 first checkin
casties
parents:
diff changeset
312 ret = bool(data['rows'])
09361041be51 first checkin
casties
parents:
diff changeset
313 return ret
09361041be51 first checkin
casties
parents:
diff changeset
314
09361041be51 first checkin
casties
parents:
diff changeset
315 def showListOfTables(self,format='XML',schema='public',REQUEST=None,RESPONSE=None):
09361041be51 first checkin
casties
parents:
diff changeset
316 """returns PageTemplate with list of tables"""
09361041be51 first checkin
casties
parents:
diff changeset
317 logging.debug("showlistoftables")
09361041be51 first checkin
casties
parents:
diff changeset
318 # should be cross-site accessible
09361041be51 first checkin
casties
parents:
diff changeset
319 if RESPONSE is None:
09361041be51 first checkin
casties
parents:
diff changeset
320 RESPONSE = self.REQUEST.RESPONSE
09361041be51 first checkin
casties
parents:
diff changeset
321 RESPONSE.setHeader('Access-Control-Allow-Origin', '*')
09361041be51 first checkin
casties
parents:
diff changeset
322
09361041be51 first checkin
casties
parents:
diff changeset
323 pt = getattr(self.template, '%s_schema'%format, None)
09361041be51 first checkin
casties
parents:
diff changeset
324 if pt is None:
09361041be51 first checkin
casties
parents:
diff changeset
325 return "ERROR!! template %s_schema not found"%format
09361041be51 first checkin
casties
parents:
diff changeset
326
09361041be51 first checkin
casties
parents:
diff changeset
327 #data = self.getListOfTables(schema)
09361041be51 first checkin
casties
parents:
diff changeset
328 return pt(schema=schema)
09361041be51 first checkin
casties
parents:
diff changeset
329
09361041be51 first checkin
casties
parents:
diff changeset
330 def getListOfTables(self,schema='public',username='guest'):
09361041be51 first checkin
casties
parents:
diff changeset
331 """return list of tables"""
09361041be51 first checkin
casties
parents:
diff changeset
332 logging.debug("getlistoftables")
09361041be51 first checkin
casties
parents:
diff changeset
333 # get list of fields and types of db table
09361041be51 first checkin
casties
parents:
diff changeset
334 #qstr="""SELECT c.relname AS tablename FROM pg_catalog.pg_class c
09361041be51 first checkin
casties
parents:
diff changeset
335 # LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
09361041be51 first checkin
casties
parents:
diff changeset
336 # WHERE c.relkind IN ('r','') AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
09361041be51 first checkin
casties
parents:
diff changeset
337 # AND pg_catalog.pg_table_is_visible(c.oid)
09361041be51 first checkin
casties
parents:
diff changeset
338 # AND c.relname ORDER BY 1"""
09361041be51 first checkin
casties
parents:
diff changeset
339 qstr = """SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE'
09361041be51 first checkin
casties
parents:
diff changeset
340 AND table_schema = %s ORDER BY 1"""
09361041be51 first checkin
casties
parents:
diff changeset
341 data=self.executeSQL(qstr,(schema,))
09361041be51 first checkin
casties
parents:
diff changeset
342 return data
09361041be51 first checkin
casties
parents:
diff changeset
343
09361041be51 first checkin
casties
parents:
diff changeset
344 def showListOfSchemas(self,format='XML',REQUEST=None,RESPONSE=None):
09361041be51 first checkin
casties
parents:
diff changeset
345 """returns PageTemplate with list of schemas"""
09361041be51 first checkin
casties
parents:
diff changeset
346 logging.debug("showlistofschemas")
09361041be51 first checkin
casties
parents:
diff changeset
347 # should be cross-site accessible
09361041be51 first checkin
casties
parents:
diff changeset
348 if RESPONSE is None:
09361041be51 first checkin
casties
parents:
diff changeset
349 RESPONSE = self.REQUEST.RESPONSE
09361041be51 first checkin
casties
parents:
diff changeset
350 RESPONSE.setHeader('Access-Control-Allow-Origin', '*')
09361041be51 first checkin
casties
parents:
diff changeset
351
09361041be51 first checkin
casties
parents:
diff changeset
352 pt = getattr(self.template, '%s_index'%format, None)
09361041be51 first checkin
casties
parents:
diff changeset
353 if pt is None:
09361041be51 first checkin
casties
parents:
diff changeset
354 return "ERROR!! template %s_index not found"%format
09361041be51 first checkin
casties
parents:
diff changeset
355
09361041be51 first checkin
casties
parents:
diff changeset
356 #data = self.getListOfSchemas()
09361041be51 first checkin
casties
parents:
diff changeset
357 return pt()
09361041be51 first checkin
casties
parents:
diff changeset
358
09361041be51 first checkin
casties
parents:
diff changeset
359 def getListOfSchemas(self,username='guest'):
09361041be51 first checkin
casties
parents:
diff changeset
360 """return list of schemas"""
09361041be51 first checkin
casties
parents:
diff changeset
361 logging.debug("getlistofschemas")
09361041be51 first checkin
casties
parents:
diff changeset
362 # TODO: really look up schemas
09361041be51 first checkin
casties
parents:
diff changeset
363 data={'fields': (('schemas',),), 'rows': [('public',),]}
09361041be51 first checkin
casties
parents:
diff changeset
364 return data
09361041be51 first checkin
casties
parents:
diff changeset
365
09361041be51 first checkin
casties
parents:
diff changeset
366 def manage_editRestDbInterface(self, title=None, connection_id=None,
09361041be51 first checkin
casties
parents:
diff changeset
367 REQUEST=None):
09361041be51 first checkin
casties
parents:
diff changeset
368 """Change the object"""
09361041be51 first checkin
casties
parents:
diff changeset
369 if title is not None:
09361041be51 first checkin
casties
parents:
diff changeset
370 self.title = title
09361041be51 first checkin
casties
parents:
diff changeset
371
09361041be51 first checkin
casties
parents:
diff changeset
372 if connection_id is not None:
09361041be51 first checkin
casties
parents:
diff changeset
373 self.connection_id = connection_id
09361041be51 first checkin
casties
parents:
diff changeset
374
09361041be51 first checkin
casties
parents:
diff changeset
375 #checkPermission=getSecurityManager().checkPermission
09361041be51 first checkin
casties
parents:
diff changeset
376 REQUEST.RESPONSE.redirect('manage_main')
09361041be51 first checkin
casties
parents:
diff changeset
377
09361041be51 first checkin
casties
parents:
diff changeset
378
09361041be51 first checkin
casties
parents:
diff changeset
379 manage_addRestDbInterfaceForm=PageTemplateFile('zpt/addRestDbInterface',globals())
09361041be51 first checkin
casties
parents:
diff changeset
380
09361041be51 first checkin
casties
parents:
diff changeset
381 def manage_addRestDbInterface(self, id, title='', label='', description='',
09361041be51 first checkin
casties
parents:
diff changeset
382 createPublic=0,
09361041be51 first checkin
casties
parents:
diff changeset
383 createUserF=0,
09361041be51 first checkin
casties
parents:
diff changeset
384 REQUEST=None):
09361041be51 first checkin
casties
parents:
diff changeset
385 """Add a new object with id *id*."""
09361041be51 first checkin
casties
parents:
diff changeset
386
09361041be51 first checkin
casties
parents:
diff changeset
387 ob=RestDbInterface(str(id),title)
09361041be51 first checkin
casties
parents:
diff changeset
388 self._setObject(id, ob)
09361041be51 first checkin
casties
parents:
diff changeset
389
09361041be51 first checkin
casties
parents:
diff changeset
390 #checkPermission=getSecurityManager().checkPermission
09361041be51 first checkin
casties
parents:
diff changeset
391 REQUEST.RESPONSE.redirect('manage_main')
09361041be51 first checkin
casties
parents:
diff changeset
392
09361041be51 first checkin
casties
parents:
diff changeset
393