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