Return-Path: X-Original-To: apmail-incubator-bloodhound-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-bloodhound-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 366DAE0BD for ; Wed, 30 Jan 2013 11:14:43 +0000 (UTC) Received: (qmail 75191 invoked by uid 500); 30 Jan 2013 11:14:43 -0000 Delivered-To: apmail-incubator-bloodhound-commits-archive@incubator.apache.org Received: (qmail 75143 invoked by uid 500); 30 Jan 2013 11:14:42 -0000 Mailing-List: contact bloodhound-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: bloodhound-dev@incubator.apache.org Delivered-To: mailing list bloodhound-commits@incubator.apache.org Received: (qmail 75122 invoked by uid 99); 30 Jan 2013 11:14:41 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 30 Jan 2013 11:14:41 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 30 Jan 2013 11:14:38 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id EBB3C2388978; Wed, 30 Jan 2013 11:14:17 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1440346 - in /incubator/bloodhound/branches/bep_0003_multiproduct: bloodhound_dashboard/bhdashboard/ bloodhound_multiproduct/multiproduct/ Date: Wed, 30 Jan 2013 11:14:17 -0000 To: bloodhound-commits@incubator.apache.org From: jure@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20130130111417.EBB3C2388978@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: jure Date: Wed Jan 30 11:14:17 2013 New Revision: 1440346 URL: http://svn.apache.org/viewvc?rev=1440346&view=rev Log: #288, product environment context manager from t288_r1438538_sql_translate_global_env.diff (from olemis) and some changes to make it work properly Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py 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_dashboard/bhdashboard/model.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py?rev=1440346&r1=1440345&r2=1440346&view=diff ============================================================================== --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py Wed Jan 30 11:14:17 2013 @@ -158,7 +158,7 @@ class ModelBase(object): sdata) for key in self._meta['key_fields']: - if not self._data[key]: + if self._data[key] is None: sdata = {'key':key} sdata.update(self._meta) raise TracError('%(key)s required for %(object_name)s' % 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=1440346&r1=1440345&r2=1440346&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 Wed Jan 30 11:14:17 2013 @@ -118,10 +118,13 @@ class MultiProductSystem(Component): db_installed_version = self._update_db_version(db, 2) if db_installed_version < 3: - from multiproduct.dbcursor import DEFAULT_PRODUCT from multiproduct.model import Product import trac.db_default + + DEFAULT_PRODUCT = 'default' + migrate_tables = ['enum', 'component', 'milestone', 'version', 'permission', 'wiki'] + # extend trac default schema by adding product column and extending key with product table_defs = [copy.deepcopy(t) for t in trac.db_default.schema if t.name in migrate_tables] for t in table_defs: 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=1440346&r1=1440345&r2=1440346&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 Wed Jan 30 11:14:17 2013 @@ -35,7 +35,7 @@ SKIP_TABLES = ['system', 'auth_cookie', ] TRANSLATE_TABLES = ['ticket', 'enum', 'component', 'milestone', 'version', 'permission', 'wiki'] PRODUCT_COLUMN = 'product' -DEFAULT_PRODUCT = 'default' +DEFAULT_PRODUCT = '' class BloodhoundIterableCursor(trac.db.util.IterableCursor): __slots__ = trac.db.util.IterableCursor.__slots__ + ['_translator'] @@ -72,6 +72,63 @@ class BloodhoundIterableCursor(trac.db.u def set_env(cls, env): cls._tls.env = env + @classmethod + def get_env(cls): + return cls._tls.env + +class ProductEnvContextManager(object): + """Wrap an underlying database context manager so as to keep track + of (nested) product context. + """ + def __init__(self, context, env=None): + """Initialize product database context. + + :param context: Inner database context (e.g. `QueryContextManager`, + `TransactionContextManager` ) + :param env: An instance of either `trac.env.Environment` or + `multiproduct.env.ProductEnvironment` used to + reduce the scope of database queries. If set + to `None` then SQL queries will not be translated, + which is equivalent to having direct database access. + """ + self.db_context = context + self.env = env + + def __enter__(self): + """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__() + + 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): + """Forward attribute access to nested database context on failure. + """ + BloodhoundIterableCursor.set_env(self.env) + return self.db_context(*args, **kwargs) + + def __getattr__(self, attrnm): + """Forward attribute access to nested database context on failure. + """ + return getattr(self.db_context, attrnm) + + def execute(self, sql, params=None): + BloodhoundIterableCursor.set_env(self.env) + return self.db_context.execute(sql, params=params) + + def executemany(self, sql, params=None): + 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 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=1440346&r1=1440345&r2=1440346&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 Wed Jan 30 11:14:17 2013 @@ -23,7 +23,7 @@ from urlparse import urlsplit from trac.config import ConfigSection, Option from trac.core import Component, ComponentManager, implements -from trac.db.api import with_transaction, TransactionContextManager, QueryContextManager +from trac.db.api import TransactionContextManager, QueryContextManager from trac.util import get_pkginfo, lazy from trac.util.compat import sha1 from trac.versioncontrol import RepositoryManager @@ -31,8 +31,8 @@ from trac.web.href import Href from multiproduct.api import MultiProductSystem from multiproduct.config import Configuration +from multiproduct.dbcursor import ProductEnvContextManager from multiproduct.model import Product -from multiproduct.dbcursor import BloodhoundIterableCursor import trac.env @@ -54,13 +54,19 @@ class Environment(trac.env.Environment): @property def db_query(self): - BloodhoundIterableCursor.set_env(self) - return super(Environment, self).db_query + return ProductEnvContextManager(super(Environment, self).db_query, self) @property def db_transaction(self): - BloodhoundIterableCursor.set_env(self) - return super(Environment, self).db_transaction + return ProductEnvContextManager(super(Environment, self).db_transaction, self) + + @property + def db_direct_query(self): + return ProductEnvContextManager(super(Environment, self).db_query) + + @property + def db_direct_transaction(self): + return ProductEnvContextManager(super(Environment, self).db_transaction) # replace trac.env.Environment with Environment trac.env.Environment = Environment @@ -84,16 +90,6 @@ class EnvironmentStub(trac.test.Environm enable=enable, disable=disable, path=path, destroying=destroying) - @property - def db_query(self): - BloodhoundIterableCursor.set_env(self) - return super(EnvironmentStub, self).db_query - - @property - def db_transaction(self): - BloodhoundIterableCursor.set_env(self) - return super(EnvironmentStub, self).db_transaction - # replace trac.test.EnvironmentStub trac.test.EnvironmentStub = EnvironmentStub @@ -349,15 +345,16 @@ class ProductEnvironment(Component, Comp return self.parent.db_exc() def with_transaction(self, db=None): - """Decorator for transaction functions :deprecated:""" - return with_transaction(self, db) + """Decorator for transaction functions :deprecated: + """ + raise NotImplementedError('Deprecated method') def get_read_db(self): """Return a database connection for read purposes :deprecated: - See `trac.db.api.get_read_db` for detailed documentation.""" - # database connection is shared with global environment - return self.parent.get_read_db() + See `trac.db.api.get_read_db` for detailed documentation. + """ + raise NotImplementedError('Deprecated method') @property def db_query(self): @@ -391,8 +388,7 @@ class ProductEnvironment(Component, Comp context was the outermost context (`db_query` or `db_transaction`). """ - BloodhoundIterableCursor.set_env(self) - return QueryContextManager(self.parent) + return ProductEnvContextManager(QueryContextManager(self.parent), self) @property def db_transaction(self): @@ -427,8 +423,7 @@ class ProductEnvironment(Component, Comp context, if this context was the outermost context (`db_query` or `db_transaction`). """ - BloodhoundIterableCursor.set_env(self) - return TransactionContextManager(self.parent) + return ProductEnvContextManager(TransactionContextManager(self.parent), self) def shutdown(self, tid=None): """Close the environment."""