Welcome, guest | Sign In | My Account | Store | Cart
# The actual web service.

import MySQLdb
import signal
import netsvc
import netsvc.xmlrpc
import netsvc.soap


class Cursor(netsvc.Service):

  def __init__(self,name,cursor,timeout):
    netsvc.Service.__init__(self,name)
    self.joinGroup("database-services")
    self._cursor = cursor
    self._timeout = timeout
    self._restart()
    self.exportMethod(self.execute)
    self.exportMethod(self.executemany)
    self.exportMethod(self.description)
    self.exportMethod(self.rowcount)
    self.exportMethod(self.fetchone)
    self.exportMethod(self.fetchmany)
    self.exportMethod(self.fetchall)
    self.exportMethod(self.arraysize)
    self.exportMethod(self.close)

  def encodeObject(self,object):
    if hasattr(MySQLdb,"DateTime"):
      if type(object) == MySQLdb.DateTimeType:
	return ("xsd:string",object.strftime())
      elif type(object) == MySQLdb.DateTimeDeltaType:
	return ("xsd:string",str(object))
    return netsvc.Service.encodeObject(self,object)

  def executeMethod(self,name,method,params):
    try:
      return netsvc.Service.executeMethod(self,name,method,params)
    except MySQLdb.ProgrammingError,exception:
      self.abortResponse(1,"Programming Error","db",str(exception))
    except MySQLdb.Error,(error,description):
      self.abortResponse(error,description,"mysql")

  def _restart(self):
    self.cancelTimer("idle")
    self.startTimer(self._expire,self._timeout,"idle")

  def _expire(self,name):
    if name == "idle":
      self.close()

  def execute(self,query,args=None):
    result = self._cursor.execute(query,args)
    self._restart()
    return result

  def executemany(self,query,args=None):
    result = self._cursor.executemany(query,args)
    self._restart()
    return result

  def description(self):
    self._restart()
    return self._cursor.description

  def rowcount(self):
    self._restart()
    return self._cursor.rowcount

  def fetchone(self):
    result = self._cursor.fetchone()
    self._restart()
    return result

  def fetchmany(self,size=None):
    if size == None:
      size = self._cursor.arraysize
    result = self._cursor.fetchmany(size)
    self._restart()
    return result

  def fetchall(self):
    result = self._cursor.fetchall()
    self._restart()
    return result

  def arraysize(self):
    self._restart()
    return self._cursor.arraysize

  def close(self):
    self._cursor.close()
    self.cancelTimer("idle")
    self.destroyReferences()
    return 0


class Database(netsvc.Service):

  def __init__(self,name,**kw):
    netsvc.Service.__init__(self,name)
    self._name = name
    self.joinGroup("database-services")
    self._database = MySQLdb.connect(**kw)
    self._cursors = 0
    self.exportMethod(self.execute)
    self.exportMethod(self.executemany)
    self.exportMethod(self.cursor)

  def encodeObject(self,object):
    if hasattr(MySQLdb,"DateTime"):
      if type(object) == MySQLdb.DateTimeType:
	return ("xsd:string",object.strftime())
      elif type(object) == MySQLdb.DateTimeDeltaType:
	return ("xsd:string",str(object))
    return netsvc.Service.encodeObject(self,object)

  def executeMethod(self,name,method,params):
    try:
      return netsvc.Service.executeMethod(self,name,method,params)
    except MySQLdb.ProgrammingError,exception:
      self.abortResponse(1,"Programming Error","db",str(exception))
    except MySQLdb.Error,(error,description):
      self.abortResponse(error,description,"mysql")

  def execute(self,query,args=None):
    cursor = self._database.cursor()
    cursor.execute(query,args)
    if cursor.description == None:
      return cursor.rowcount
    return cursor.fetchall()

  def executemany(self,query,args=None):
    cursor = self._database.cursor()
    cursor.executemany(query,args)
    if cursor.description == None:
      return cursor.rowcount
    return cursor.fetchall()

  def cursor(self,timeout):
    self._cursors = self._cursors + 1
    name = "%s/%d" % (self._name,self._cursors)
    cursor = self._database.cursor()
    Cursor(name,cursor,timeout)
    child = "%d" % self._cursors
    return child


dispatcher = netsvc.Dispatcher()
dispatcher.monitor(signal.SIGINT)
httpd = netsvc.HttpDaemon(8000)

server = Database("test",db="test")

rpcgw1 = netsvc.xmlrpc.RpcGateway("database-services")
httpd.attach("/xmlrpc/database",rpcgw1)

rpcgw2 = netsvc.soap.RpcGateway("database-services")
httpd.attach("/soap/database",rpcgw2)

httpd.start()
dispatcher.run()

# Example of XML-RPC client using PythonWare "xmlrpclib" module.

import xmlrpclib
 
url = "http://localhost:8000/xmlrpc/database/test"
 
service = xmlrpclib.Server(url)
 
tables = service.execute("show tables")
 
if tables == []:
  print "no tables"
else:
  for entry in tables:
    table = entry[0]
    print "table: " + table
 
    # create cursor specific to queries
    name = service.cursor(30)
    print "cursor: " + url + "/" + name
    cursor = xmlrpclib.Server(url+"/"+name)
 
    cursor.execute("select * from "+table)
    desc = cursor.description()
    print "desc: " + str(desc)
    data = cursor.fetchall()
    print "data: " + str(data)
    cursor.close()

# Example of SOAP client using pywebsvcs "SOAP" module.

import SOAP
 
url = "http://localhost:8000/soap/database/test"
 
service = SOAP.SOAPProxy(url)
 
tables = service.execute("show tables")
 
if tables == []:
  print "no tables"
else:
  for entry in tables:
    table = entry[0]
    print "table: " + table
 
    # create cursor specific to queries
    name = service.cursor(30)
    print "cursor: " + url + "/" + name
    cursor = SOAP.SOAPProxy(url+"/"+name)
 
    cursor.execute("select * from "+table)
    desc = cursor.description()
    print "desc: " + str(desc)
    data = cursor.fetchall()
    print "data: " + str(data)
    cursor.close()

History

  • revision 3 (22 years ago)
  • previous revisions are not available