Edgewall Software

Ticket #8172: db-upgrade-helpers.patch

File db-upgrade-helpers.patch, 6.7 KB (added by psuter, 9 months ago)

DB upgrade helper functions

  • trac/env.py

    # HG changeset patch
    # Parent c10c5c1105a9e4aea7ecc469c2ea25523943af03
    Plugin DB upgrade helper functions.
    
    diff -r c10c5c1105a9 trac/env.py
    a b  
    560560        :since 0.13: deprecation warning: the `db` parameter is no 
    561561                     longer used and will be removed in version 0.14 
    562562        """ 
    563         rows = self.db_query(""" 
    564                 SELECT value FROM system WHERE name='%sdatabase_version' 
    565                 """ % ('initial_' if initial else '')) 
    566         return rows and int(rows[0][0]) 
     563        return get_environment_version_for_module(self,  
     564            'initial_database_version' if initial else 'database_version') 
    567565 
    568566    def setup_config(self): 
    569567        """Load the configuration file.""" 
     
    706704 
    707705    def environment_created(self): 
    708706        """Insert default data into the database.""" 
    709         with self.env.db_transaction as db: 
    710             for table, cols, vals in db_default.get_data(db): 
    711                 db.executemany("INSERT INTO %s (%s) VALUES (%s)" 
    712                    % (table, ','.join(cols), ','.join(['%s' for c in cols])), 
    713                    vals) 
     707        init_environment_data_for_module(self.env, db_default.get_data) 
    714708        self._update_sample_config() 
    715709 
    716710    def environment_needs_upgrade(self, db): 
    717         dbver = self.env.get_version(db) 
    718         if dbver == db_default.db_version: 
    719             return False 
    720         elif dbver > db_default.db_version: 
    721             raise TracError(_('Database newer than Trac version')) 
    722         self.log.info("Trac database schema version is %d, should be %d", 
    723                       dbver, db_default.db_version) 
    724         return True 
     711        return environment_needs_upgrade_for_module(self.env, 'Trac', 
     712                                                    'database_version', 
     713                                                    db_default.db_version) 
    725714 
    726715    def upgrade_environment(self, db): 
    727716        """Each db version should have its own upgrade module, named 
    728717        upgrades/dbN.py, where 'N' is the version number (int). 
    729718        """ 
    730         cursor = db.cursor() 
    731         dbver = self.env.get_version() 
    732         for i in range(dbver + 1, db_default.db_version + 1): 
    733             name  = 'db%i' % i 
    734             try: 
    735                 upgrades = __import__('upgrades', globals(), locals(), [name]) 
    736                 script = getattr(upgrades, name) 
    737             except AttributeError: 
    738                 raise TracError(_("No upgrade module for version %(num)i " 
    739                                   "(%(version)s.py)", num=i, version=name)) 
    740             script.do_upgrade(self.env, i, cursor) 
    741             cursor.execute(""" 
    742                 UPDATE system SET value=%s WHERE name='database_version' 
    743                 """, (i,)) 
    744             self.log.info("Upgraded database version from %d to %d", i - 1, i) 
    745             db.commit() 
     719        upgrade_environment_for_module(self.env, 'Trac', 'database_version', 
     720                                       db_default.db_version, 
     721                                       'upgrades') 
    746722        self._update_sample_config() 
    747723 
    748724    # Internal methods 
     
    817793 
    818794    return env 
    819795 
     796def init_environment_version_for_module(env, name, version): 
     797    """Set the current module version in the database. 
     798     
     799    :since: 0.13 
     800    """ 
     801    with env.db_transaction as db: 
     802        cursor = db.cursor() 
     803        cursor.execute(""" 
     804            INSERT INTO system (name, value) 
     805            VALUES (%s, %s) 
     806            """, (name, version)) 
     807 
     808def init_environment_schema_for_module(env, schema): 
     809    """Setup db schema for this module in the database. 
     810     
     811    :since: 0.13 
     812    """ 
     813    db_connector, _ = DatabaseManager(env).get_connector() 
     814    with env.db_transaction as db: 
     815        cursor = db.cursor() 
     816        for table in schema: 
     817            for stmt in db_connector.to_sql(table): 
     818                cursor.execute(stmt) 
     819 
     820def init_environment_data_for_module(env, get_initial_data): 
     821    """Insert initial data into the database. 
     822     
     823    :since: 0.13 
     824    """ 
     825    with env.db_transaction as db: 
     826        for table, cols, vals in get_initial_data(db): 
     827                db.executemany("INSERT INTO %s (%s) VALUES (%s)" 
     828                   % (table, ','.join(cols), ','.join(['%s' for c in cols])), 
     829                   vals) 
     830 
     831def get_environment_version_for_module(env, name): 
     832    """Get the current module version from the database. 
     833 
     834    Returns `False` if the environment has not been setup for this module, 
     835    which is "older" than any db version number. 
     836 
     837    :since: 0.13 
     838    """ 
     839    rows = env.db_query(""" 
     840            SELECT value FROM system WHERE name='%s' 
     841            """ % name) 
     842    return rows and int(rows[0][0]) 
     843 
     844def environment_needs_upgrade_for_module(env, name, field, version): 
     845    """Check whether the environment needs to be upgraded for this module. 
     846 
     847    Commonly called from `IEnvironmentSetupParticipant` modules and plugins 
     848    to implement the method `environment_needs_upgrade`. 
     849     
     850    :since: 0.13 
     851    """ 
     852    dbver = get_environment_version_for_module(env, field) 
     853    if dbver == version: 
     854        return False 
     855    elif dbver > version: 
     856        raise TracError(_("Database newer than %(name)s version.", name=name)) 
     857    env.log.info("%s database schema version is %d, should be %d", 
     858                  name, dbver, version) 
     859    return True 
     860 
     861def upgrade_environment_for_module(env, name, field, version,  
     862                                   upgrades_pkg_name): 
     863    """Invoke `do_upgrade(env, version, cursor)` in module  
     864    `"%s/db%i.py" % (upgrades_pkg_name, version)` for each  
     865    required version upgrade. 
     866     
     867    :since: 0.13 
     868    """ 
     869    dbver = get_environment_version_for_module(env, field) 
     870    with env.db_transaction as db: 
     871        cursor = db.cursor() 
     872        for i in range(dbver + 1, version + 1): 
     873            module  = 'db%i' % i 
     874            try: 
     875                upgrades = __import__(upgrades_pkg_name, globals(), locals(), 
     876                                      [module]) 
     877                script = getattr(upgrades, module) 
     878            except AttributeError: 
     879                msg =  
     880                raise TracError(_("No upgrade module for version %(num)i " 
     881                                  "(%(module)s.py)", num=i, module=module) 
     882            script.do_upgrade(env, i, cursor) 
     883            cursor.execute(""" 
     884                UPDATE system SET value=%s WHERE name='%s' 
     885                """, (i, name)) 
     886            env.log.info("Upgraded database version from %d to %d" 
     887                          " for module %s", i - 1, i, name) 
     888            db.commit() 
     889 
    820890 
    821891class EnvironmentAdmin(Component): 
    822892    """trac-admin command provider for environment administration."""