/usr/share/pyshared/paste/webkit/FakeWebware/MiscUtils/DBPool.py is in python-pastewebkit 1.0-7.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | """
DBPool.py
Implements a pool of cached connections to a database. This should result in
a speedup for persistent apps. The pool of connections is threadsafe
regardless of whether the DB API module question in general has a
threadsafety of 1 or 2.
For more information on the DB API, see:
http://www.python.org/topics/database/DatabaseAPI-2.0.html
The idea behind DBPool is that it's completely seamless, so once you have
established your connection, use it just as you would any other DB-API
compliant module. For example:
dbPool = DBPool(MySQLdb, 5, host=xxx, user=xxx, ...)
db = dbPool.getConnection()
Now use "db" exactly as if it were a MySQLdb connection. It's really
just a proxy class.
db.close() will return the connection to the pool, not actually
close it. This is so your existing code works nicely.
FUTURE
* If in the presence of WebKit, register ourselves as a Can.
CREDIT
* Contributed by Dan Green
* thread safety bug found by Tom Schwaller
* Fixes by Geoff Talvola (thread safety in _threadsafe_getConnection()).
* Clean up by Chuck Esterbrook.
* Fix unthreadsafe functions which were leaking, Jay Love
* Eli Green's webware-discuss comments were lifted for additional docs.
"""
import threading
class DBPoolError(Exception): pass
class UnsupportedError(DBPoolError): pass
class PooledConnection:
""" A wrapper for database connections to help with DBPool. You don't normally deal with this class directly, but use DBPool to get new connections. """
def __init__(self, pool, con):
self._con = con
self._pool = pool
def close(self):
if self._con is not None:
self._pool.returnConnection(self)
self._con = None
def __getattr__(self, name):
return getattr(self._con, name)
def __del__(self):
self.close()
class DBPool:
def __init__(self, dbModule, maxConnections, *args, **kwargs):
if dbModule.threadsafety==0:
raise UnsupportedError, "Database module does not support any level of threading."
elif dbModule.threadsafety==1:
from Queue import Queue
self._queue = Queue(maxConnections)
self.addConnection = self._unthreadsafe_addConnection
self.getConnection = self._unthreadsafe_getConnection
self.returnConnection = self._unthreadsafe_returnConnection
elif dbModule.threadsafety>=2:
self._lock = threading.Lock()
self._nextCon = 0
self._connections = []
self.addConnection = self._threadsafe_addConnection
self.getConnection = self._threadsafe_getConnection
self.returnConnection = self._threadsafe_returnConnection
# @@ 2000-12-04 ce: Should we really make all the connections now?
# Couldn't we do this on demand?
for i in range(maxConnections):
con = apply(dbModule.connect, args, kwargs)
self.addConnection(con)
# threadsafe/unthreadsafe refers to the database _module_, not THIS class..
# this class is definitely threadsafe (um. that is, I hope so - Dan)
def _threadsafe_addConnection(self, con):
self._connections.append(con)
def _threadsafe_getConnection(self):
self._lock.acquire()
try:
con = PooledConnection(self, self._connections[self._nextCon])
self._nextCon = self._nextCon + 1
if self._nextCon >= len(self._connections):
self._nextCon = 0
return con
finally:
self._lock.release()
def _threadsafe_returnConnection(self, con):
return
# These functions are used with DB modules that have connection level threadsafety, like PostgreSQL.
#
def _unthreadsafe_addConnection(self, con):
self._queue.put(con)
def _unthreadsafe_getConnection(self):
return PooledConnection(self, self._queue.get())
def _unthreadsafe_returnConnection(self, conpool):
"""
This should never be called explicitly outside of this module.
"""
self.addConnection(conpool._con)
|