You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bloodhound.apache.org by gj...@apache.org on 2012/04/20 18:52:57 UTC
svn commit: r1328447 -
/incubator/bloodhound/trunk/bloodhound_multiproduct/multiproduct/model.py
Author: gjm
Date: Fri Apr 20 16:52:57 2012
New Revision: 1328447
URL: http://svn.apache.org/viewvc?rev=1328447&view=rev
Log:
multiproduct: unique product names, update product ticket on name change and provide a Product.get_tickets class method #38
Modified:
incubator/bloodhound/trunk/bloodhound_multiproduct/multiproduct/model.py
Modified: incubator/bloodhound/trunk/bloodhound_multiproduct/multiproduct/model.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_multiproduct/multiproduct/model.py?rev=1328447&r1=1328446&r2=1328447&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_multiproduct/multiproduct/model.py (original)
+++ incubator/bloodhound/trunk/bloodhound_multiproduct/multiproduct/model.py Fri Apr 20 16:52:57 2012
@@ -17,6 +17,8 @@
# under the License.
"""Models to support multi-product"""
+from datetime import datetime
+
from pkg_resources import resource_filename
from trac.core import Component, TracError, implements
from trac.resource import ResourceNotFound
@@ -25,6 +27,9 @@ from trac.env import IEnvironmentSetupPa
from trac.web.chrome import ITemplateProvider
from trac.resource import Resource
from trac.ticket.api import TicketSystem
+from trac.ticket.model import Ticket
+from trac.ticket.query import Query
+from trac.util.datefmt import utc
DB_VERSION = 1
DB_SYSTEM_KEY = 'bloodhound_multi_product_version'
@@ -146,11 +151,18 @@ class ModelBase(object):
def insert(self):
"""Create new record in the database"""
+ sdata = None
if self._exists or len(self.select(self._env, where =
dict([(k,self._data[k])
for k in self._meta['key_fields']]))):
sdata = {'keys':','.join(["%s='%s'" % (k, self._data[k])
for k in self._meta['key_fields']])}
+ elif len(self.select(self._env, where =
+ dict([(k,self._data[k])
+ for k in self._meta['unique_fields']]))):
+ sdata = {'keys':','.join(["%s='%s'" % (k, self._data[k])
+ for k in self._meta['unique_fields']])}
+ if sdata:
sdata.update(self._meta)
raise TracError('%(object_name)s %(keys)s already exists' %
sdata)
@@ -174,13 +186,23 @@ class ModelBase(object):
self._old_data.update(self._data)
TicketSystem(self._env).reset_ticket_fields()
+ def _update_relations(self, db):
+ """Extra actions due to update"""
+ pass
+
def update(self):
"""Update the matching record in the database"""
+ if self._old_data == self._data:
+ return
if not self._exists:
raise TracError('%(object_name)s does not exist' % self._meta)
- for key in self._meta['key_fields']:
+ for key in self._meta['no_change_fields']:
if self._data[key] != self._old_data[key]:
raise TracError('%s cannot be changed' % key)
+ for key in self._meta['key_fields'] + self._meta['unique_fields']:
+ if self._data[key] != self._old_data[key]:
+ if len(self.select(self._env, where = {key:self._data[key]})):
+ raise TracError('%s already exists' % key)
setsql, setvalues = fields_to_kv_str(self._meta['non_key_fields'],
self._data, sep=',')
@@ -193,6 +215,7 @@ class ModelBase(object):
WHERE %(where)s""" % sdata
with self._env.db_transaction as db:
db(sql, setvalues + values)
+ self._update_relations(db)
self._old_data.update(self._data)
TicketSystem(self._env).reset_ticket_fields()
@@ -222,6 +245,8 @@ class Product(ModelBase):
'object_name':'Product',
'key_fields':['prefix',],
'non_key_fields':['name', 'description', 'owner'],
+ 'no_change_fields':['prefix',],
+ 'unique_fields':['name'],
}
@property
@@ -245,7 +270,25 @@ class Product(ModelBase):
for prm in ProductResourceMap.select(self._env, where=where):
prm._data['product_id'] = resources_to
prm.update()
-
+
+ def _update_relations(self, db=None, author=None):
+ """Extra actions due to update"""
+ # tickets need to be updated
+ old_name = self._old_data['name']
+ new_name = self._data['name']
+ now = datetime.now(utc)
+ comment = 'Product %s renamed to %s' % (old_name, new_name)
+ if old_name != new_name:
+ for t in Product.get_tickets(self._env, old_name):
+ ticket = Ticket(self._env, t['id'], db)
+ ticket['product'] = new_name
+ ticket.save_changes(author, comment, now)
+
+ @classmethod
+ def get_tickets(cls, env, product=''):
+ """Retrieve all tickets associated with the product."""
+ q = Query.from_string(env, 'product=%s' % product)
+ return q.execute()
class ProductResourceMap(ModelBase):
"""Table representing the mapping of resources to their product"""
@@ -253,6 +296,8 @@ class ProductResourceMap(ModelBase):
'object_name':'ProductResourceMapping',
'key_fields':['id',],
'non_key_fields':['product_id','resource_type','resource_id',],
+ 'no_change_fields':['id',],
+ 'unique_fields':[],
}
def reparent_resource(self, product=None):
@@ -273,7 +318,7 @@ class MultiProductEnvironmentProvider(Co
implements(IEnvironmentSetupParticipant, ITemplateProvider)
SCHEMA = [
- Table('bloodhound_product', key = 'prefix') [
+ Table('bloodhound_product', key = ['prefix', 'name']) [
Column('prefix'),
Column('name'),
Column('description'),