#288: Create prototype for legacy database schema proxy
---------------------------+-----------------------------------
Reporter: jure | Owner: jure
Type: enhancement | Status: new
Priority: major | Milestone:
Component: multiproduct | Version:
Resolution: | Keywords: bep-0003 multiproduct
---------------------------+-----------------------------------
Comment (by olemis):
I'd like to propose some features related to #288 for you to consider .
These are aimed at succeeding with tests cases for permissions , and
ticket API . I've ben working the last few days towards that goal . The
proposal is presented in the form of two patches .
[attachment:t288_r1438538_sql_translate_global_env.diff The first one]
incorporates the following features :
1. Add a context manager for switching product environments
with the goal in mind of better tracking of active environment
when using nested transactions . JFTR notice that «active
environment»
is stored in TLS .
2. Add two methods `db_direct_query` and `db_direct_transaction`
providing direct DB access (i.e. no product prefix translation).
3. Default product prefix will be '' rather than 'default' and will
be reserved for global environment (i.e. `trac.env.Environment`).
4. `ProductEnvironment(env, None) is env` and
`ProductEnvironment(env, '') is env` in order to be consistent with
(3) above.
Up to this point patch order is as follows ...
{{{
#!sh
$ hg qapplied
t288/t288_r1438538_sql_translate_global_env.diff
t355/t355_r1437383_trac_test_perm.diff
t355/t355_r1437383_trac_test_ticket_api.diff
}}}
... and everything is still looking ok and all tests (except those in
tests.perm and tests.ticket.api) succeed . The next logical step forward
is to implement the actual translation for the global environment with the
help of (1) and (2) above.
In the mechanism mentioned in (2) both , aforementioned context manager
and TLS variable participate following the following sequence
* context manager sets env in TLS
* iterable cursor checks env var in TLS .
- if set to product env , translate SQL considering product = prefix
- if set to global env , translate SQL considering product = ''
- if set to `None` (e.g. after invoking `db_direct_query`
and `db_direct_transaction` ) then do not translate SQL
query.
... at least that's the idea I tried to sketch in
[attachment:t288_r1438538_sql_translate_global_env_pending.diff the second
patch] , but up to that point tests won't work anymore :'(
When patches applied this way
{{{
#!sh
$ hg qapplied
t288/t288_r1438538_sql_translate_global_env.diff
t288/t288_r1438538_sql_translate_global_env_pending.diff
t355/t355_r1437383_trac_test_perm.diff
t355/t355_r1437383_trac_test_ticket_api.diff
}}}
... this is what I get :
{{{
#!sh
$ python setup.py test -m tests.env
[...]
Testing env.get_known_users ... ERROR
Testing env.get_version ... ERROR
Testing env.__getattr__ ... ok
Testing env.is_component_enabled ... ok
Testing env.path ... ok
Testing env.__init__ ... ok
======================================================================
ERROR: Testing env.get_known_users
----------------------------------------------------------------------
Traceback (most recent call last):
File "/path/to/bloodhound/bloodhound_multiproduct/tests/env.py", line
182, in setUp
EnvironmentTestCase.setUp(self)
File "/path/to/bloodhound/trac/trac/tests/env.py", line 16, in setUp
self.env = Environment(env_path, create=True)
File "/path/to/bloodhound/trac/trac/core.py", line 140, in __call__
self.__init__(*args, **kwargs)
File "/path/to/bloodhound/trac/trac/core.py", line 107, in new_init
original_init(self, *args, **kwargs)
File "/path/to/bloodhound/bloodhound_multiproduct/multiproduct/env.py",
line 54, in __init__
super(Environment, self).__init__(path, create=create,
options=options)
File "/path/to/bloodhound/trac/trac/core.py", line 107, in new_init
original_init(self, *args, **kwargs)
File "/path/to/bloodhound/trac/trac/env.py", line 289, in __init__
setup_participant.environment_created()
File "/path/to/bloodhound/trac/trac/env.py", line 743, in
environment_created
vals)
File "/path/to/bloodhound/trac/trac/db/util.py", line 139, in
executemany
cursor.executemany(query, params)
File
"/path/to/bloodhound/bloodhound_multiproduct/multiproduct/dbcursor.py",
line 79, in executemany
return super(BloodhoundIterableCursor,
self).executemany(self._translate_sql(sql), args=args)
File "/path/to/bloodhound/trac/trac/db/util.py", line 85, in executemany
return self.cursor.executemany(sql_escape_percent(sql), args)
File "/path/to/bloodhound/trac/trac/db/sqlite_backend.py", line 62, in
executemany
args)
File "/path/to/bloodhound/trac/trac/db/sqlite_backend.py", line 48, in
_rollback_on_error
return function(self, *args, **kwargs)
OperationalError: table component has no column named product
[...]
}}}
So I guess something in there is breaking multi-product upgrades . It
seems to be related to the translation of CREATE and/or ALTER statements ,
but I'm not 100% sure . Anyway ...
@jure : could you please take a look and review ?
I'll continue trying to figure out what else needs to be done , hoping
I'll find the root cause , but I share the code soon looking forward to
your feedback .
--
Ticket URL: <https://issues.apache.org/bloodhound/ticket/288#comment:18>
Apache Bloodhound <https://issues.apache.org/bloodhound/>
The Apache Bloodhound (incubating) issue tracker