64 lines
		
	
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			64 lines
		
	
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 
								 | 
							
								# ------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								import time
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# ------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								class Migrator:
							 | 
						||
| 
								 | 
							
								    '''This class is responsible for performing migrations, when, on
							 | 
						||
| 
								 | 
							
								       installation, we've detected a new Appy version.'''
							 | 
						||
| 
								 | 
							
								    def __init__(self, installer):
							 | 
						||
| 
								 | 
							
								        self.installer = installer
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def migrateTo_0_7_1(self):
							 | 
						||
| 
								 | 
							
								        '''Appy 0.7.1 has its own management of Ref fields and does not use
							 | 
						||
| 
								 | 
							
								           Archetypes references and the reference catalog anymore. So we must
							 | 
						||
| 
								 | 
							
								           update data structures that store Ref info on instances.'''
							 | 
						||
| 
								 | 
							
								        ins = self.installer
							 | 
						||
| 
								 | 
							
								        ins.info('Migrating to Appy 0.7.1...')
							 | 
						||
| 
								 | 
							
								        allClassNames = [ins.tool.__class__.__name__] + ins.config.allClassNames
							 | 
						||
| 
								 | 
							
								        for className in allClassNames:
							 | 
						||
| 
								 | 
							
								            i = -1
							 | 
						||
| 
								 | 
							
								            updated = 0
							 | 
						||
| 
								 | 
							
								            ins.info('Analysing class "%s"...' % className)
							 | 
						||
| 
								 | 
							
								            refFields = None
							 | 
						||
| 
								 | 
							
								            for obj in ins.tool.executeQuery(className,\
							 | 
						||
| 
								 | 
							
								                                             noSecurity=True)['objects']:
							 | 
						||
| 
								 | 
							
								                i += 1
							 | 
						||
| 
								 | 
							
								                if i == 0:
							 | 
						||
| 
								 | 
							
								                    # Get the Ref fields for objects of this class
							 | 
						||
| 
								 | 
							
								                    refFields = [f for f in obj.getAllAppyTypes() \
							 | 
						||
| 
								 | 
							
								                                 if (f.type == 'Ref') and not f.isBack]
							 | 
						||
| 
								 | 
							
								                    if refFields:
							 | 
						||
| 
								 | 
							
								                        refNames = ', '.join([rf.name for rf in refFields])
							 | 
						||
| 
								 | 
							
								                        ins.info('  Ref fields found: %s' % refNames)
							 | 
						||
| 
								 | 
							
								                    else:
							 | 
						||
| 
								 | 
							
								                        ins.info('  No Ref field found.')
							 | 
						||
| 
								 | 
							
								                        break
							 | 
						||
| 
								 | 
							
								                isUpdated = False
							 | 
						||
| 
								 | 
							
								                for field in refFields:
							 | 
						||
| 
								 | 
							
								                    # Attr for storing UIDs of referred objects has moved
							 | 
						||
| 
								 | 
							
								                    # from _appy_[fieldName] to [fieldName].
							 | 
						||
| 
								 | 
							
								                    refs = getattr(obj, '_appy_%s' % field.name)
							 | 
						||
| 
								 | 
							
								                    if refs:
							 | 
						||
| 
								 | 
							
								                        isUpdated = True
							 | 
						||
| 
								 | 
							
								                        setattr(obj, field.name, refs)
							 | 
						||
| 
								 | 
							
								                        exec 'del obj._appy_%s' % field.name
							 | 
						||
| 
								 | 
							
								                        # Set the back references
							 | 
						||
| 
								 | 
							
								                        for refObject in field.getValue(obj):
							 | 
						||
| 
								 | 
							
								                            refObject.link(field.back.name, obj, back=True)
							 | 
						||
| 
								 | 
							
								                if isUpdated: updated += 1
							 | 
						||
| 
								 | 
							
								            if updated:
							 | 
						||
| 
								 | 
							
								                ins.info('  %d/%d object(s) updated.' % (updated, i+1))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def run(self):
							 | 
						||
| 
								 | 
							
								        i = self.installer
							 | 
						||
| 
								 | 
							
								        installedVersion = i.appyTool.appyVersion
							 | 
						||
| 
								 | 
							
								        startTime = time.time()
							 | 
						||
| 
								 | 
							
								        migrationRequired = False
							 | 
						||
| 
								 | 
							
								        if not installedVersion or (installedVersion <= '0.7.0'):
							 | 
						||
| 
								 | 
							
								            migrationRequired = True
							 | 
						||
| 
								 | 
							
								            self.migrateTo_0_7_1()
							 | 
						||
| 
								 | 
							
								        stopTime = time.time()
							 | 
						||
| 
								 | 
							
								        if migrationRequired:
							 | 
						||
| 
								 | 
							
								            i.info('Migration done in %d minute(s).'% ((stopTime-startTime)/60))
							 | 
						||
| 
								 | 
							
								# ------------------------------------------------------------------------------
							 |