diff --git a/controllers/demo/due.py b/controllers/demo/due.py
index 6652729..993fc44 100644
--- a/controllers/demo/due.py
+++ b/controllers/demo/due.py
@@ -3,12 +3,12 @@
from decorators import WSGITemplate # decoratore ( singleton )
-wsgit = WSGITemplate()
+wsgitmpl = WSGITemplate()
#
# esempio minimo di controller WSGI
#
-@wsgit.template( 'template1.tmpl' )
+@wsgitmpl.template( 'template1.tmpl' )
def application( environ, start_response ):
from pprint import pformat
diff --git a/controllers/demo/sql.py b/controllers/demo/sql.py
new file mode 100644
index 0000000..5eabd67
--- /dev/null
+++ b/controllers/demo/sql.py
@@ -0,0 +1,50 @@
+#!/usr/bin/python
+# -*- coding: utf-8; tab-width: 4; indent-tabs-mode: nil; -*-
+
+from decorators import WSGIMySQL # decoratore ( singleton )
+
+wsgisql = WSGIMySQL()
+
+#
+# esempio minimo di controller WSGI
+#
+@wsgisql.db( 'mywiki', 'shoot' )
+def application( environ, start_response ):
+
+ cur = environ['mysql.mywiki.cur']
+
+ #
+ # esecuzione query
+ #
+ cur.execute( 'SHOW tables;' )
+
+ #
+ # recupero record e generazione html
+ #
+
+ start_response( '200 OK', [('content-type', 'text/html; charset=utf-8')] )
+
+ yield "
elenco tabelle presenti nel db mywiki
"
+
+ for record in cur.fetchall():
+ yield str( record ) + "
"
+
+ #
+ # recupero secondo cursore
+ #
+
+ cur2 = environ['mysql.shoot.cur']
+
+ #
+ # esecuzione query
+ #
+ cur2.execute( 'SHOW tables;' )
+
+ #
+ # recupero record e generazione html
+ #
+
+ yield "elenco tabelle presenti nel db shoot
"
+
+ for record in cur2.fetchall():
+ yield str( record ) + "
"
diff --git a/decorators.py b/decorators.py
index 866934c..d2294b4 100644
--- a/decorators.py
+++ b/decorators.py
@@ -36,41 +36,82 @@ class WSGIMySQL( object ):
__metaclass__ = Singleton
def __init__( self, dsn, *args ):
+ """ inizializza le connessioni a 1 o più database.
+ In caso di connessioni a databese multipli,
+ le connessioni sono identificate tramite ALIAS
+ o in mancanza di questo tramite DB
+
+ ogni singolo dsn deve essere un dizionario con le chiavi:
+ - DB : nome del database
+ - HOST : host a cui connettersi
+ - USER : username da utilizzare per connettersi
+ - PASSWORD : password da utilizzare per connettersi
+ - ALIAS : (opzionale) identificativo della connessione
+ """
import MySQLdb
- self.__dsn = dsn
- self.__pool = [ self.__newconn() ]
+ #
+ # aggiungiamo il primo dsn in cima alla lista
+ #
+ args = list( args )
+ args.insert( 0, dsn )
+
+ #
+ # creiamo il nostro dizionario di dizionari
+ #
+ self.__dsn = { dsndict.get( 'ALIAS', dsndict['DB'] ):dsndict for dsndict in args }
+
+ #
+ # verifichiamo che non ci siano alias duplicati
+ #
+ if len( self.__dsn.keys() ) != len( args ):
+ raise Exception( "WSGIMySQL :: conflicting alias in dsn list" )
+
+ #
+ # tentiamo di creare la prima connessione verso TUTTI i dsn passati
+ #
+
+ for alias, dsndict in self.__dsn.iteritems():
+ dsndict['pool'] = [ self.__newconn( alias ) ]
+
self.__dict_cursor = MySQLdb.cursors.DictCursor
- def __newconn( self ):
+ def __newconn( self, alias ):
import MySQLdb
return MySQLdb.connect(
- host = self.__dsn["HOST"],
- user = self.__dsn["USER"],
- passwd = self.__dsn["PASSWORD"],
- db = self.__dsn["DB"]
+ host = self.__dsn[ alias ]["HOST"],
+ user = self.__dsn[ alias ]["USER"],
+ passwd = self.__dsn[ alias ]["PASSWORD"],
+ db = self.__dsn[ alias ]["DB"]
)
def db( self, *args ):
def real_decorator( wsgi_application ):
def wrapper( environ, start_response ):
- try:
- conn = self.__pool.pop( 0 )
- except IndexError:
- conn = self.__newconn()
+ connections = []
+
+ for arg in args:
+ try:
+ conn = self.__dsn[ arg ]['pool'].pop( 0 )
+ except IndexError:
+ conn = self.__newconn( arg )
+
+ connections.append( conn )
- cur = conn.cursor( self.__dict_cursor )
+ cur = conn.cursor( self.__dict_cursor )
- environ['mysql.cur'] = cur
+ environ['mysql.' + arg + '.cur'] = cur
try:
for item in wsgi_application( environ, start_response ):
yield item
finally:
- conn.commit()
- self.__pool.append( conn )
+ for arg in args:
+ conn = connections.pop(0)
+ conn.commit()
+ self.__dsn[ arg ]['pool'].append( conn )
return wrapper
@@ -78,5 +119,9 @@ class WSGIMySQL( object ):
def __del__( self ):
- for conn in self.__pool:
- conn.close()
+ #
+ # chiudiamo tutte le connessioni attualmente aperte
+ #
+ for dsndict in self.__dsn.items():
+ for conn in dsndict['pool']:
+ conn.close()
diff --git a/dispatch_wsgi.py b/dispatch_wsgi.py
index fee191b..0681f63 100755
--- a/dispatch_wsgi.py
+++ b/dispatch_wsgi.py
@@ -21,12 +21,19 @@ WSGITemplate( basedir='views' )
#
from decorators import WSGIMySQL
WSGIMySQL(
- dsn = dict(
+ dict(
DB = "mywiki",
HOST = "localhost",
USER = "corso",
PASSWORD = "pwdcorso"
- )
+ ),
+ dict(
+ DB = "shootout",
+ HOST = "localhost",
+ USER = "root",
+ PASSWORD = "server",
+ ALIAS = "shoot"
+ ),
)