annotate RestDbJsonStore.py @ 47:698ef00f2717

more json store
author casties
date Fri, 03 Sep 2010 14:00:09 +0200
parents 562717546168
children 2ba80c8bb47f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
42
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
1 '''
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
2 Created on 2.9.2010
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
3
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
4 @author: casties
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
5 '''
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
6
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
7 from OFS.Folder import Folder
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
8 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
9 import logging
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
10 import re
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
11 import psycopg2
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
12 import json
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
13 import time
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
14
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
15 from zope.interface import implements
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
16 from zope.publisher.interfaces import IPublishTraverse
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
17 from ZPublisher.BaseRequest import DefaultPublishTraverse
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
18 import Shared.DC.ZRDB.DA
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
19 from Products.ZSQLMethods.SQL import SQLConnectionIDs
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
20
43
562717546168 refactoring...
casties
parents: 42
diff changeset
21 from RestDbInterface import *
42
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
22
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
23
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
24 class RestDbJsonStore(RestDbInterface):
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
25 """Object for RESTful database queries
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
26 path schema: /db/{schema}/{table}/
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
27 omitting table gives a list of schemas
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
28 omitting table and schema gives a list of schemas
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
29 """
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
30 implements(IPublishTraverse)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
31
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
32 meta_type="RESTdbJSONStore"
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
33 manage_options=Folder.manage_options+(
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
34 {'label':'Config','action':'manage_editRestDbJsonStoreForm'},
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
35 )
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
36
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
37 # management templates
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
38 manage_editRestDbJsonStoreForm=PageTemplateFile('zpt/editRestDbJsonStore',globals())
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
39
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
40 # JSON_* templates are scripts
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
41 def JSON_index(self,data):
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
42 """JSON index function"""
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
43 self.REQUEST.RESPONSE.setHeader("Content-Type", "application/json")
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
44 json.dump(data, self.REQUEST.RESPONSE)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
45
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
46 def JSON_schema(self,data,schema):
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
47 """JSON index function"""
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
48 self.REQUEST.RESPONSE.setHeader("Content-Type", "application/json")
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
49 json.dump(data, self.REQUEST.RESPONSE)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
50
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
51 def JSON_schema_table(self,data,tablename):
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
52 """JSON index function"""
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
53 self.REQUEST.RESPONSE.setHeader("Content-Type", "application/json")
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
54 json.dump(data, self.REQUEST.RESPONSE)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
55
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
56
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
57 def __init__(self, id, title, connection_id=None):
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
58 """init"""
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
59 self.id = id
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
60 self.title = title
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
61 # database connection id
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
62 self.connection_id = connection_id
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
63
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
64 def getJsonString(self,object):
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
65 """returns a JSON formatted string from object"""
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
66 return json.dumps(object)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
67
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
68
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
69 def publishTraverse(self,request,name):
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
70 """change the traversal"""
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
71 # get stored path
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
72 path = request.get('restdb_path', [])
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
73 logging.debug("publishtraverse: name=%s restdb_path=%s"%(name,path))
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
74
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
75 if name in ("index_html", "PUT"):
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
76 # end of traversal
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
77 if request.get("method") == "POST" and request.get("action",None) == "PUT":
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
78 # fake PUT by POST with action=PUT
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
79 name = "PUT"
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
80
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
81 return getattr(self, name)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
82 #TODO: should we check more?
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
83 else:
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
84 # traverse
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
85 if len(path) == 0:
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
86 # first segment
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
87 if name == 'db':
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
88 # virtual path -- continue traversing
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
89 path = [name]
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
90 request['restdb_path'] = path
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
91 else:
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
92 # try real path
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
93 tr = DefaultPublishTraverse(self, request)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
94 ob = tr.publishTraverse(request, name)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
95 return ob
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
96 else:
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
97 path.append(name)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
98
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
99 # continue traversing
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
100 return self
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
101
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
102 def index_html(self,REQUEST,RESPONSE):
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
103 """index method"""
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
104 # ReST path was stored in request
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
105 path = REQUEST.get('restdb_path',[])
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
106
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
107 # type and format are real parameter
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
108 resultFormat = REQUEST.get('format','HTML').upper()
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
109 queryType = REQUEST.get('type',None)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
110
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
111 logging.debug("index_html path=%s resultFormat=%s queryType=%s"%(path,resultFormat,queryType))
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
112
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
113 if queryType is not None:
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
114 # non-empty queryType -- look for template
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
115 pt = getattr(self.template, "%s_%s"%(resultFormat,queryType), None)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
116 if pt is not None:
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
117 return pt(format=resultFormat,type=queryType,path=path)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
118
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
119 if len(path) == 1:
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
120 # list of schemas
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
121 return self.showListOfSchemas(resultFormat=resultFormat)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
122 elif len(path) == 2:
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
123 # list of tables
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
124 return self.showListOfTables(resultFormat=resultFormat,schema=path[1])
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
125 elif len(path) == 3:
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
126 # table
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
127 if REQUEST.get("method") == "POST" and REQUEST.get("create_table_file",None) is not None:
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
128 # POST to table to check
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
129 return self.checkTable(resultFormat=resultFormat,schema=path[1],table=path[2])
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
130 # else show table
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
131 return self.showTable(resultFormat=resultFormat,schema=path[1],table=path[2])
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
132
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
133 # don't know what to do
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
134 return str(REQUEST)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
135
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
136 def PUT(self, REQUEST, RESPONSE):
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
137 """
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
138 Implement WebDAV/HTTP PUT/FTP put method for this object.
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
139 """
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
140 logging.debug("RestDbInterface PUT")
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
141 #logging.debug("req=%s"%REQUEST)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
142 #self.dav__init(REQUEST, RESPONSE)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
143 #self.dav__simpleifhandler(REQUEST, RESPONSE)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
144 # ReST path was stored in request
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
145 path = REQUEST.get('restdb_path',[])
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
146 if len(path) == 3:
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
147 schema = path[1]
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
148 tablename = path[2]
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
149 file = REQUEST.get("create_table_file",None)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
150 if file is None:
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
151 RESPONSE.setStatus(400)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
152 return
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
153
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
154 fields = None
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
155 fieldsStr = REQUEST.get("create_table_fields",None)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
156 logging.debug("put with schema=%s table=%s file=%s fields=%s"%(schema,tablename,file,repr(fieldsStr)))
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
157 if fieldsStr is not None:
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
158 # unpack fields
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
159 fields = [{"name":n, "type": t} for (n,t) in [f.split(":") for f in fieldsStr.split(",")]]
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
160
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
161 ret = self.createTableFromXML(schema, tablename, file, fields)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
162 # return the result as JSON
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
163 format = REQUEST.get("format","JSON")
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
164 if format == "JSON":
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
165 RESPONSE.setHeader("Content-Type", "application/json")
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
166 json.dump(ret, RESPONSE)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
167
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
168 elif format == "JSONHTML":
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
169 RESPONSE.setHeader("Content-Type", "text/html")
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
170 RESPONSE.write("<html>\n<body>\n<pre>")
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
171 json.dump(ret, RESPONSE)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
172 RESPONSE.write("</pre>\n</body>\n</html>")
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
173
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
174 else:
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
175 # 400 Bad Request
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
176 RESPONSE.setStatus(400)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
177 return
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
178
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
179
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
180 manage_addRestDbInterfaceForm=PageTemplateFile('zpt/addRestDbInterface',globals())
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
181
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
182 def manage_addRestDbInterface(self, id, title='', label='', description='',
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
183 createPublic=0,
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
184 createUserF=0,
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
185 REQUEST=None):
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
186 """Add a new object with id *id*."""
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
187
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
188 ob=RestDbInterface(str(id),title)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
189 self._setObject(id, ob)
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
190
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
191 #checkPermission=getSecurityManager().checkPermission
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
192 REQUEST.RESPONSE.redirect('manage_main')
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
193
291aed5f0e0d new class for JSON store
casties
parents:
diff changeset
194