Skip to content

Commit

Permalink
enable pooling by default
Browse files Browse the repository at this point in the history
  • Loading branch information
Anand committed May 27, 2008
1 parent 479ee3d commit d2a1c0b
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 41 deletions.
3 changes: 1 addition & 2 deletions test/db.py
Expand Up @@ -68,8 +68,7 @@ def testNestedTransactions(self):
self.assertRows(2)

def testPooling(self):
db = webtest.setup_database(self.dbname)
db.has_pooling = True
db = webtest.setup_database(self.dbname, pooling=True)
self.assertEquals(db.ctx.db.__class__.__module__, 'DBUtils.PooledDB')
db.select('person', limit=1)

Expand Down
6 changes: 3 additions & 3 deletions test/webtest.py
Expand Up @@ -119,11 +119,11 @@ def suite(module_names):
suite.addTest(module_suite(mod))
return suite

def setup_database(dbname):
def setup_database(dbname, pooling=False):
if dbname == 'sqlite':
db = web.database(dbn=dbname, db='webpy.db')
db = web.database(dbn=dbname, db='webpy.db', pooling=pooling)
else:
db = web.database(dbn=dbname, db='webpy', user='scott', pw='tiger')
db = web.database(dbn=dbname, db='webpy', user='scott', pw='tiger', pooling=pooling)

if '-v' in sys.argv:
db.printing = True
Expand Down
86 changes: 50 additions & 36 deletions web/db.py
Expand Up @@ -394,20 +394,33 @@ def rollback(self):

class DB:
"""Database"""
def __init__(self):
def __init__(self, db_module, keywords):
"""Creates a database.
"""
self.db_module = db_module
self.keywords = keywords

self._ctx = threadeddict()

# flag to enable/disable printing queries
self.printing = False
self.has_pooling = False
self.supports_multiple_insert = False


try:
import DBUtils
# enable pooling if DBUtils module is available.
self.has_pooling = True
except ImportError:
self.has_pooling = False

# Pooling can be disabled by passing pooling=False in the keywords.
self.has_pooling = self.has_pooling and self.keywords.pop('pooling', True)

def _getctx(self):
if not self._ctx.get('db'):
self._load_context(self._ctx)
return self._ctx
ctx = property(_getctx)

def _load_context(self, ctx):
ctx.dbq_count = 0
ctx.transactions = [] # stack of transactions
Expand Down Expand Up @@ -511,7 +524,7 @@ def query(self, sql_query, vars=None, processed=False, _test=False):
If `processed=True`, `vars` is a `reparam`-style list to use
instead of interpolating.
>>> db = DB()
>>> db = DB(None, {})
>>> db.query("SELECT * FROM foo", _test=True)
<sql: 'SELECT * FROM foo'>
>>> db.query("SELECT * FROM foo WHERE x = $x", vars=dict(x='f'), _test=True)
Expand Down Expand Up @@ -543,7 +556,8 @@ def iterwrapper():
else:
out = db_cursor.rowcount

if not self.ctx.transactions: self.ctx.db.commit()
if not self.ctx.transactions:
self.ctx.db.commit()
return out

def select(self, tables, vars=None, what='*', where=None, order=None, group=None,
Expand All @@ -553,7 +567,7 @@ def select(self, tables, vars=None, what='*', where=None, order=None, group=None
`group`, `limit`, and `offset`. Uses vars to interpolate.
Otherwise, each clause can be a SQLQuery.
>>> db = DB()
>>> db = DB(None, {})
>>> db.select('foo', _test=True)
<sql: 'SELECT * FROM foo'>
>>> db.select(['foo', 'bar'], where="foo.bar_id = bar.id", limit=5, _test=True)
Expand All @@ -571,7 +585,7 @@ def where(self, table, what='*', order=None, group=None, limit=None,
"""
Selects from `table` where keys are equal to values in `kwargs`.
>>> db = DB()
>>> db = DB(None, {})
>>> db.where('foo', bar_id=3, _test=True)
<sql: 'SELECT * FROM foo WHERE bar_id = 3'>
>>> db.where('foo', source=2, crust='dewey', _test=True)
Expand Down Expand Up @@ -620,7 +634,7 @@ def insert(self, tablename, seqname=None, _test=False, **values):
Set `seqname` to the ID if it's not the default, or to `False`
if there isn't one.
>>> db = DB()
>>> db = DB(None, {})
>>> q = db.insert('foo', name='bob', age=2, created=SQLLiteral('NOW()'), _test=True)
>>> q
<sql: "INSERT INTO foo (age, name, created) VALUES (2, 'bob', NOW())">
Expand Down Expand Up @@ -658,7 +672,8 @@ def q(x): return "(" + x + ")"
except Exception:
out = None

if not self.ctx.transactions: self.ctx.db.commit()
if not self.ctx.transactions:
self.ctx.db.commit()
return out

def multiple_insert(self, tablename, values, seqname=None, _test=False):
Expand All @@ -669,7 +684,7 @@ def multiple_insert(self, tablename, values, seqname=None, _test=False):
Set `seqname` to the ID if it's not the default, or to `False`
if there isn't one.
>>> db = DB()
>>> db = DB(None, {})
>>> db.supports_multiple_insert = True
>>> values = [{"name": "foo", "email": "foo@example.com"}, {"name": "bar", "email": "bar@example.com"}]
>>> db.multiple_insert('person', values=values, _test=True)
Expand Down Expand Up @@ -722,7 +737,8 @@ def multiple_insert(self, tablename, values, seqname=None, _test=False):
except Exception:
out = None

if not self.ctx.transactions: self.ctx.db.commit()
if not self.ctx.transactions:
self.ctx.db.commit()
return out


Expand All @@ -731,7 +747,7 @@ def update(self, tables, where, vars=None, _test=False, **values):
Update `tables` with clause `where` (interpolated using `vars`)
and setting `values`.
>>> db = DB()
>>> db = DB(None, {})
>>> name = 'Joseph'
>>> q = db.update('foo', where='name = $name', name='bob', age=2,
... created=SQLLiteral('NOW()'), vars=locals(), _test=True)
Expand All @@ -754,14 +770,15 @@ def update(self, tables, where, vars=None, _test=False, **values):

db_cursor = self._db_cursor()
self._db_execute(db_cursor, query)
if not self.ctx.transactions: self.ctx.db.commit()
if not self.ctx.transactions:
self.ctx.db.commit()
return db_cursor.rowcount

def delete(self, table, where, using=None, vars=None, _test=False):
"""
Deletes from `table` with clauses `where` and `using`.
>>> db = DB()
>>> db = DB(None, {})
>>> name = 'Joe'
>>> db.delete('foo', where='name = $name', vars=locals(), _test=True)
<sql: "DELETE FROM foo WHERE name = 'Joe'">
Expand All @@ -777,7 +794,8 @@ def delete(self, table, where, using=None, vars=None, _test=False):

db_cursor = self._db_cursor()
self._db_execute(db_cursor, q)
if not self.ctx.transactions: self.ctx.db.commit()
if not self.ctx.transactions:
self.ctx.db.commit()
return db_cursor.rowcount

def _process_insert_query(self, query, tablename, seqname):
Expand All @@ -790,19 +808,18 @@ def transaction(self):
class PostgresDB(DB):
"""Postgres driver."""
def __init__(self, **keywords):
DB.__init__(self)
if 'pw' in keywords:
keywords['password'] = keywords['pw']
del keywords['pw']
keywords['database'] = keywords['db']
del keywords['db']

db_module = self.get_db_module()
keywords['database'] = keywords.pop('db')
self.dbname = "postgres"
self.db_module = self.get_db_module()
self.paramstyle = self.db_module.paramstyle
self.keywords = keywords
self.paramstyle = db_module.paramstyle
self.supports_multiple_insert = True

DB.__init__(self, db_module, keywords)

def get_db_module(self):
try:
import psycopg2 as db
Expand Down Expand Up @@ -832,23 +849,20 @@ def _connect_with_pooling(self, keywords):

class MySQLDB(DB):
def __init__(self, **keywords):
DB.__init__(self)
import MySQLdb as db
if 'pw' in keywords:
keywords['passwd'] = keywords['pw']
del keywords['pw']
self.paramstyle = db.paramstyle = 'pyformat' # it's both, like psycopg
self.db_module = db
self.keywords = keywords
self.dbname = "mysql"
self.supports_multiple_insert = True
DB.__init__(self, db, keywords)

def _process_insert_query(self, query, tablename, seqname):
return query, SQLQuery('SELECT last_insert_id();')

class SqliteDB(DB):
def __init__(self, **keywords):
DB.__init__(self)
try:
import sqlite3 as db
db.paramstyle = 'qmark'
Expand All @@ -859,11 +873,9 @@ def __init__(self, **keywords):
except ImportError:
import sqlite as db
self.paramstyle = db.paramstyle
keywords['database'] = keywords['db']
del keywords['db']
self.keywords = keywords
self.db_module = db
self.dbname = "sqlite"
keywords['database'] = keywords.pop('db')
self.dbname = "sqlite"
DB.__init__(self, db, keywords)

def _process_insert_query(self, query, tablename, seqname):
return query, SQLQuery('SELECT last_insert_rowid();')
Expand Down Expand Up @@ -913,9 +925,8 @@ def __init__(self, **keywords):
del keywords['pw']
keywords['database'] = keywords['db']
del keywords['db']
self.keywords = keywords
self.db_module = db

DB.__init__(self, db, keywords)

def delete(self, table, where=None, using=None, vars=None, _test=False):
# firebird doesn't support using clause
using=None
Expand All @@ -936,6 +947,9 @@ def sql_clauses(self, what, tables, where, group, order, limit, offset):
_databases = {}
def database(dburl=None, **params):
"""Creates appropriate database using params.
Pooling will be enabled if DBUtils module is available.
Pooling can be disabled by passing pooling=False in params.
"""
dbn = params.pop('dbn')
if dbn in _databases:
Expand Down

0 comments on commit d2a1c0b

Please sign in to comment.