Author: jure
Date: Thu Jan 31 14:20:50 2013
New Revision: 1440970
URL: http://svn.apache.org/viewvc?rev=1440970&view=rev
Log:
#288, properly keep connection context by using connection wrapper, apply
multi-product upgrades on test database
Modified:
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py
Modified:
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py
URL:
http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1440970&r1=1440969&r2=1440970&view=diff
==============================================================================
---
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py
(original)
+++
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py
Thu Jan 31 14:20:50 2013
@@ -97,7 +97,7 @@ class MultiProductSystem(Component):
self.log.debug("upgrading existing environment for %s plugin." %
PLUGIN_NAME)
db_installed_version = self.get_version()
- with self.env.db_transaction as db:
+ with self.env.db_direct_transaction as db:
if db_installed_version < 1:
# Initial installation
db("ALTER TABLE ticket ADD COLUMN product TEXT")
Modified:
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py
URL:
http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py?rev=1440970&r1=1440969&r2=1440970&view=diff
==============================================================================
---
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py
(original)
+++
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py
Thu Jan 31 14:20:50 2013
@@ -32,10 +32,17 @@ SKIP_TABLES = ['system', 'auth_cookie',
'ticket_change', 'ticket_custom',
'report',
'bloodhound_product', 'bloodhound_productresourcemap',
'bloodhound_productconfig',
+ 'sqlite_master'
]
TRANSLATE_TABLES = ['ticket', 'enum', 'component', 'milestone', 'version',
'permission', 'wiki']
PRODUCT_COLUMN = 'product'
-DEFAULT_PRODUCT = ''
+GLOBAL_PRODUCT = ''
+
+# Singleton used to mark translator as unset
+class empty_translator(object):
+ pass
+
+translator_not_set = empty_translator()
class BloodhoundIterableCursor(trac.db.util.IterableCursor):
__slots__ = trac.db.util.IterableCursor.__slots__ + ['_translator']
@@ -43,20 +50,18 @@ class BloodhoundIterableCursor(trac.db.u
def __init__(self, cursor, log=None):
super(BloodhoundIterableCursor, self).__init__(cursor, log=log)
- self._translator = None
-
- @property
- def translator(self):
- if not self._translator:
- product_prefix = self.env.product.prefix if (self.env and
self.env.product) else DEFAULT_PRODUCT
- self._translator = BloodhoundProductSQLTranslate(SKIP_TABLES,
- TRANSLATE_TABLES,
- PRODUCT_COLUMN,
- product_prefix)
- return self._translator
+ self._translator = translator_not_set
def _translate_sql(self, sql):
- return self.translator.translate(sql) if (self.env and
self.env.product) else sql
+ if self._translator is translator_not_set:
+ self._translator = None
+ if not self.env is None:
+ product_prefix = self.env.product.prefix if self.env.product
else GLOBAL_PRODUCT
+ self._translator = BloodhoundProductSQLTranslate(SKIP_TABLES,
+
TRANSLATE_TABLES,
+
PRODUCT_COLUMN,
+
product_prefix)
+ return self._translator.translate(sql) if (self._translator is not
None) else sql
def execute(self, sql, args=None):
return super(BloodhoundIterableCursor,
self).execute(self._translate_sql(sql), args=args)
@@ -76,6 +81,28 @@ class BloodhoundIterableCursor(trac.db.u
def get_env(cls):
return cls._tls.env
+# replace trac.db.util.IterableCursor with BloodhoundIterableCursor
+trac.db.util.IterableCursor = BloodhoundIterableCursor
+
+class BloodhoundConnectionWrapper(object):
+
+ def __init__(self, connection, env):
+ self.connection = connection
+ self.env = env
+
+ def __getattr__(self, name):
+ return getattr(self.connection, name)
+
+ def execute(self, query, params=None):
+ BloodhoundIterableCursor.set_env(self.env)
+ return self.connection.execute(query, params=params)
+
+ __call__ = execute
+
+ def executemany(self, query, params=None):
+ BloodhoundIterableCursor.set_env(self.env)
+ return self.connection.executemany(query, params=params)
+
class ProductEnvContextManager(object):
"""Wrap an underlying database context manager so as to keep track
of (nested) product context.
@@ -98,16 +125,12 @@ class ProductEnvContextManager(object):
"""Keep track of previous product context and override it with `env`;
then enter the inner database context.
"""
- self._last_env = BloodhoundIterableCursor.get_env()
- BloodhoundIterableCursor.set_env(self.env)
- return self.db_context.__enter__()
+ return BloodhoundConnectionWrapper(self.db_context.__enter__(),
self.env)
def __exit__(self, et, ev, tb):
"""Uninstall current product context by restoring the last one;
then leave the inner database context.
"""
- BloodhoundIterableCursor.set_env(self._last_env)
- del self._last_env
return self.db_context.__exit__(et, ev, tb)
def __call__(self, *args, **kwargs):
@@ -129,8 +152,6 @@ class ProductEnvContextManager(object):
BloodhoundIterableCursor.set_env(self.env)
return self.db_context.executemany(sql, params=params)
-# replace trac.db.util.IterableCursor with BloodhoundIterableCursor
-trac.db.util.IterableCursor = BloodhoundIterableCursor
class BloodhoundProductSQLTranslate(object):
_join_statements = ['LEFT JOIN', 'LEFT OUTER JOIN',
Modified:
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py
URL:
http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1440970&r1=1440969&r2=1440970&view=diff
==============================================================================
---
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py
(original)
+++
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py
Thu Jan 31 14:20:50 2013
@@ -20,6 +20,7 @@
import os.path
from urlparse import urlsplit
+from sqlite3 import OperationalError
from trac.config import ConfigSection, Option
from trac.core import Component, ComponentManager, implements
@@ -89,6 +90,14 @@ class EnvironmentStub(trac.test.Environm
super(EnvironmentStub, self).__init__(default_data=default_data,
enable=enable, disable=disable,
path=path, destroying=destroying)
+ # Apply multi product upgrades. This is required as the database proxy
(translator)
+ # is installed in any case, we want it to see multi-product enabled
database
+ # schema...
+ mpsystem = MultiProductSystem(self)
+ try:
+ mpsystem.upgrade_environment()
+ except OperationalError:
+ pass
# replace trac.test.EnvironmentStub
trac.test.EnvironmentStub = EnvironmentStub