This is related to #406 (Database upgrade to multiproduct) and #404 (Populate default schema on product addition).

Some time ago decision was made to also keep the component (3rd party plugin) table(s) scoped to a product. This has been implemented as part of #288. For custom tables created by plugins, the DDL and DML statements are translated by pre-pending the product prefix (from the current product environment) to the table name(s). In effect this causes 3rd party plugins to only get product scoped view of the database (both system and custom tables) = separate table(s) for each product.

What I'd like to discuss is how to handle product additions and database upgrades.

My suggestions would be the following:

Product addition, from the component (IEnvironmentSetupParticipant) view, should be handled as new environment creation. This means that upon product addition, the IEnvironmentSetupParticipant.environment_created should be invoked for all components that implement that interface in the context of the newly created product environment. As this would provide product scoped interface to the database, the components would be able to properly create tables, insert data, etc. in the proper product scope. Also, they would get properly scoped references to product resources residing in system tables.

Database upgrades (IEnvironmentSetupParticipant.environment_needs_upgrade and IEnvironmentSetupParticipan.upgrade_environment) that are handled by trac.trac.env.Environment class, should be handled in a similar way that is handled now, but for each defined product. This would mean that both methods (upgrade required detection & actual upgrade) would need to invoke aforementioned interface methods for components implementing the IEnvironmentSetupParticipant for all existing products at the time of upgrade.

As a side effect of the above, the 'system' table (where the components store their database version) will also need to be made product aware.

For components that are multi-product aware (Bloodhound multi-product plugin for example) I would suggest introducing a new interface based on IEnvironmentSetupParticipant (calles IGlobalSetupParticipant for example). This interface would get invoked in the same way as the IEnvironmentSetupParticipant is invoked now - that is once per environment creation and once during upgrade. It would always get invoked within global environment/scope. If required, we might add additional methods for product addition/archival/migration notifications at a later stage.

Any comments/suggestions on this? :)

Cheers,
Jure

Reply via email to