Mercurial > hg > ChinaGisRestApi
view RestDbJsonStore.py @ 51:17dcf148beb3
more JSON store
author | casties |
---|---|
date | Thu, 09 Sep 2010 10:01:16 +0200 |
parents | 29c822d15bc1 |
children | 435d6664ed90 |
line wrap: on
line source
''' Created on 2.9.2010 @author: casties ''' from OFS.Folder import Folder from Products.PageTemplates.PageTemplateFile import PageTemplateFile import logging import re import psycopg2 import json import time from zope.interface import implements from zope.publisher.interfaces import IPublishTraverse from ZPublisher.BaseRequest import DefaultPublishTraverse import Shared.DC.ZRDB.DA from Products.ZSQLMethods.SQL import SQLConnectionIDs from RestDbInterface import * class RestDbJsonStore(RestDbInterface): """Object for RESTful access to JSON objects path schema: /db/{schema}/{table}/{tag}/{type}/{item} """ implements(IPublishTraverse) meta_type="RESTjson" manage_options=Folder.manage_options+( {'label':'Config','action':'manage_editRestDbJsonStoreForm'}, ) # management templates manage_editRestDbJsonStoreForm=PageTemplateFile('zpt/editRestDbJsonStore',globals()) # JSON_* templates are scripts def JSON_index(self,data): """JSON index function""" self.REQUEST.RESPONSE.setHeader("Content-Type", "application/json") json.dump(data, self.REQUEST.RESPONSE) def __init__(self, id, title, connection_id=None): """init""" self.id = id self.title = title # database connection id self.connection_id = connection_id def getJsonString(self,object): """returns a JSON formatted string from object""" return json.dumps(object) def publishTraverse(self,request,name): """change the traversal""" # get stored path path = request.get('restdb_path', []) logging.debug("publishtraverse: name=%s restdb_path=%s"%(name,path)) if name in ("index_html", "PUT"): # end of traversal if request.get("method") == "POST" and request.get("action",None) == "PUT": # fake PUT by POST with action=PUT name = "PUT" return getattr(self, name) #TODO: should we check more? else: # traverse if len(path) == 0: # first segment if name == 'db': # virtual path -- continue traversing path = [name] request['restdb_path'] = path else: # try real path tr = DefaultPublishTraverse(self, request) ob = tr.publishTraverse(request, name) return ob else: path.append(name) # continue traversing return self def index_html(self,REQUEST,RESPONSE): """index method""" # ReST path was stored in request path = REQUEST.get('restdb_path',[]) # type and format are real parameter resultFormat = REQUEST.get('format','HTML').upper() queryType = REQUEST.get('type',None) logging.debug("index_html path=%s resultFormat=%s queryType=%s"%(path,resultFormat,queryType)) if queryType is not None: # non-empty queryType -- look for template pt = getattr(self.template, "%s_%s"%(resultFormat,queryType), None) if pt is not None: return pt(format=resultFormat,type=queryType,path=path) if len(path) == 3: # list of tags return self.showListOfTags(resultFormat=resultFormat,schema=path[1],table=path[2]) elif len(path) == 4: # list of types return self.showListOfTypes(resultFormat=resultFormat,schema=path[1],table=path[2],tag=path[3]) elif len(path) == 5: # list of types return self.showListOfItems(resultFormat=resultFormat,schema=path[1],table=path[2],tag=path[3],type=path[4]) elif len(path) == 6: # show item return self.showItem(resultFormat=resultFormat,schema=path[1],table=path[2],tag=path[3],type=path[4],item=path[5]) # don't know what to do return str(REQUEST) def PUT(self, REQUEST, RESPONSE): """ Implement WebDAV/HTTP PUT/FTP put method for this object. """ path = REQUEST.get('restdb_path',[]) logging.debug("RestDbInterface PUT (path=%s)"%repr(path)) #logging.debug("req=%s"%REQUEST) #self.dav__init(REQUEST, RESPONSE) #self.dav__simpleifhandler(REQUEST, RESPONSE) # ReST path was stored in request if len(path) == 3: schema = path[1] tablename = path[2] file = REQUEST.get("create_table_file",None) if file is None: RESPONSE.setStatus(400) return fields = None fieldsStr = REQUEST.get("create_table_fields",None) logging.debug("put with schema=%s table=%s file=%s fields=%s"%(schema,tablename,file,repr(fieldsStr))) if fieldsStr is not None: # unpack fields fields = [{"name":n, "type": t} for (n,t) in [f.split(":") for f in fieldsStr.split(",")]] ret = self.createTableFromXML(schema, tablename, file, fields) # return the result as JSON format = REQUEST.get("format","JSON") if format == "JSON": RESPONSE.setHeader("Content-Type", "application/json") json.dump(ret, RESPONSE) elif format == "JSONHTML": RESPONSE.setHeader("Content-Type", "text/html") RESPONSE.write("<html>\n<body>\n<pre>") json.dump(ret, RESPONSE) RESPONSE.write("</pre>\n</body>\n</html>") else: # 400 Bad Request RESPONSE.setStatus(400) return def showListOfTags(self,resultFormat,schema,table): """returns the list of existing tags""" tags = self.getListOfTags(schema, table) if resultFormat == 'JSON': self.REQUEST.RESPONSE.setHeader("Content-Type", "application/json") json.dump(tags, self.REQUEST.RESPONSE) else: json.dump(tags, self.REQUEST.RESPONSE) def getListOfTags(self,schema,table): """returns the list of existing tags""" logging.debug("getlistoftags schema=%s table=%s"%(schema,table)) sql = 'select distinct json_tag from "%s"."%s"'%(schema,table) res = self.executeSQL(sql) if len(res['rows']) > 0: tags = [r[0] for r in res['rows']] return tags return [] def showListOfTypes(self,resultFormat,schema,table,tag): """returns the list of existing types""" types = self.getListOfTypes(schema, table,tag) if resultFormat == 'JSON': self.REQUEST.RESPONSE.setHeader("Content-Type", "application/json") json.dump(types, self.REQUEST.RESPONSE) else: json.dump(types, self.REQUEST.RESPONSE) def getListOfTypes(self,schema,table,tag): """returns the list of existing tags""" logging.debug("getlistoftypes schema=%s table=%s tag=%s"%(schema,table,tag)) sql = 'select distinct json_type from "%s"."%s" where json_tag = %%s'%(schema,table) res = self.executeSQL(sql,(tag,)) if len(res['rows']) > 0: tags = [r[0] for r in res['rows']] return tags return [] def showListOfItems(self,resultFormat,schema,table,tag,type): """returns the list of existing items""" items = self.getListOfItems(schema, table, tag, type) if resultFormat == 'JSON': self.REQUEST.RESPONSE.setHeader("Content-Type", "application/json") json.dump(items, self.REQUEST.RESPONSE) else: json.dump(items, self.REQUEST.RESPONSE) def getListOfItems(self,schema,table,tag,type): """returns the list of existing tags""" logging.debug("getlistofitems schema=%s table=%s tag=%s type=%s"%(schema,table,tag,type)) sql = 'select distinct json_item from "%s"."%s" where json_tag = %%s and json_type = %%s'%(schema,table) res = self.executeSQL(sql,(tag,type)) if len(res['rows']) > 0: items = [r[0] for r in res['rows']] return items return [] def showItem(self,resultFormat,schema,table,tag,type,item): """returns the item""" item = self.getItem(schema, table, tag, type, item) if resultFormat == 'JSON': self.REQUEST.RESPONSE.setHeader("Content-Type", "application/json") json.dump(item, self.REQUEST.RESPONSE) else: json.dump(item, self.REQUEST.RESPONSE) def getItem(self,schema,table,tag,type,item): """returns the list of existing tags""" logging.debug("getitem schema=%s table=%s tag=%s type=%s item=%s"%(schema,table,tag,type,item)) sql = 'select json_value from "%s"."%s" where json_tag = %%s and json_type = %%s and json_item = %%s'%(schema,table) res = self.executeSQL(sql,(tag,type,item)) if len(res['rows']) > 0: # just one item item = res['rows'][0][0] return item return {} manage_addRestDbJsonStoreForm=PageTemplateFile('zpt/addRestDbJsonStore',globals()) def manage_addRestDbJsonStore(self, id, title='', label='', description='', createPublic=0, createUserF=0, REQUEST=None): """Add a new object with id *id*.""" ob=RestDbJsonStore(str(id),title) self._setObject(id, ob) #checkPermission=getSecurityManager().checkPermission REQUEST.RESPONSE.redirect('manage_main')