Modify

Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#3636 closed enhancement (invalid)

Python script to upgrade ticket blockers from 0.10 to 0.11

Reported by: ftiede Owned by: coderanger
Priority: lowest Component: MasterTicketsPlugin
Severity: trivial Keywords:
Cc: ftiede Trac Release: 0.11

Description

Though there should have been nobody using this plugin in Trac 0.10, there were some who did so. For those I have a script here, to upgrade blockers to MasterTicketsPlugin 0.11.

Just call

update-mastertickets.py /path/to/trac-environment

The only flaw so far is: If there are more than one ticket blocked, there will be made a comment for each ticket, not one for all.

Attachments (1)

update-mastertickets.py (1.0 KB) - added by ftiede 6 years ago.

Download all attachments as: .zip

Change History (6)

Changed 6 years ago by ftiede

comment:1 follow-up: Changed 6 years ago by apatrushev@…

This script has a problems with:

  • multiple blockers on single ticket
  • continue update after error (primary key problems)

I can't fix this problems, but want to inform another users about such problems.

comment:2 in reply to: ↑ 1 Changed 6 years ago by ftiede

Replying to apatrushev@gmail.com:

This script has a problems with:

  • multiple blockers on single ticket

That's the flaw I mentioned in the description above.

  • continue update after error (primary key problems)

I can't fix this problems, but want to inform another users about such problems.

And I won't fix them. This is a quick'n'dirty hack doing something which should according to the plugin's author not be necessary in the first place.

comment:3 follow-up: Changed 6 years ago by coderanger

  • Keywords Upgrade path removed
  • Resolution set to invalid
  • Status changed from new to closed

Leaving this ticket here for informational purposes. Not actually a bug.

comment:4 Changed 6 years ago by victorhg@…

Solving problem of multiple blockers

  • Tested with trac 0.10.4 and 0.11.3
  • This method is ONLY for migration porposes. Once you're done with it, INSTALL THE OFFICAL VERSION of MasterTicketsPlugin. Use it

Just for information purposes. If you want to migrate from 0.10 to 0.11, you'll have to hack the model.py file from the MasterTicketsPlugin's code: source:masterticketsplugin/0.11/mastertickets/model.py

The problem with multiple blockers is that the unique key (ticket, time, value) is created always with the same timestamp... to solve it, you'll have to chage that

Remove the following lines:

if when is None:
   when = datetime.now(utc)
when_ts = to_timestamp(when)        

Add the following lines just after the second for statement on the save method:

time.sleep(0.3)
when_ts = to_timestamp(datetime.now(utc))

the save method in model.py file should look like that:

def save(self, author, comment='', when=None, db=None):
        """Save new links."""
        handle_commit = False
        if db is None:
            db = self.env.get_db_cnx()
            handle_commit = True
        cursor = db.cursor()
        
        to_check = [
            # new, old, field
            (self.blocking, self._old_blocking, 'blockedby', ('source', 'dest')),
            (self.blocked_by, self._old_blocked_by, 'blocking', ('dest', 'source')),
        ]
        
        for new_ids, old_ids, field, sourcedest in to_check:
            for n in new_ids | old_ids:
                update_field = None
                time.sleep(0.3)
                when_ts = to_timestamp(datetime.now(utc))
                if n in new_ids and n not in old_ids:
                    # New ticket added
                    cursor.execute('INSERT INTO mastertickets (%s, %s) VALUES (%%s, %%s)'%sourcedest, (self.tkt.id, n))
                    update_field = lambda lst: lst.append(str(self.tkt.id))
                elif n not in new_ids and n in old_ids:
                    # Old ticket removed
                    cursor.execute('DELETE FROM mastertickets WHERE %s=%%s AND %s=%%s'%sourcedest, (self.tkt.id, n))
                    update_field = lambda lst: lst.remove(str(self.tkt.id))
               
                if update_field is not None:
                    cursor.execute('SELECT value FROM ticket_custom WHERE ticket=%s AND name=%s',
                                   (n, field))
                    old_value = (cursor.fetchone() or ('',))[0]
                    new_value = [x.strip() for x in old_value.split(',') if x.strip()]
                    update_field(new_value)
                    
                    new_value = ', '.join(sorted(new_value, key=lambda x: int(x)))
            
                    cursor.execute('INSERT INTO ticket_change (ticket, time, author, field, oldvalue, newvalue) VALUES (%s, %s, %s, %s, %s, %s)', 
                                   (n, when_ts, author, field, old_value, new_value))
                                   
                    if comment:
                        cursor.execute('INSERT INTO ticket_change (ticket, time, author, field, oldvalue, newvalue) VALUES (%s, %s, %s, %s, %s, %s)', 
                                       (n, when_ts, author, 'comment', '', '(In #%s) %s'%(self.tkt.id, comment)))
                                   
                           
                    cursor.execute('UPDATE ticket_custom SET value=%s WHERE ticket=%s AND name=%s',
                                   (new_value, n, field))
                    if not cursor.rowcount:
                        cursor.execute('INSERT INTO ticket_custom (ticket, name, value) VALUES (%s, %s, %s)',
                                       (n, field, new_value))
        
               
        if handle_commit:
            db.commit()

Common problems

Removing '#' from blocking and blockedby fields

If you have used, for example '#1234' instead of '1234' on the blocking and blocked by field, you will have problems migrating the database. to solve that:

update ticket_custom set value=REPLACE(value, '#','') where name in ('blocking','blockedby');

update ticket_change set newvalue=REPLACE(newvalue, '#',''), oldvalue=REPLACE(oldvalue, '#', '') where field='blocking' or field='blockedby';

comment:5 in reply to: ↑ 3 Changed 6 years ago by anonymous

Replying to coderanger:

Leaving this ticket here for informational purposes. Not actually a bug.

I "solved" the question... maybe it'll be useful for someone...

Add Comment

Modify Ticket

Action
as closed The owner will remain coderanger.
The resolution will be deleted. Next status will be 'reopened'.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.