source: tagsplugin/tags/0.12/tractags/db.py

Last change on this file was 16943, checked in by Ryan J Ollos, 6 years ago

TracTags 0.10dev: Make compatible with Trac 1.3.3dev

Fixes #13316.

File size: 5.2 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#
4# Copyright (C) 2012 Steffen Hoffmann <hoff.st@web.de>
5#
6# This software is licensed as described in the file COPYING, which
7# you should have received as part of this distribution.
8
9from trac.core import Component, TracError, implements
10from trac.db.api import DatabaseManager
11from trac.env import IEnvironmentSetupParticipant
12
13from tractags import db_default
14from tractags.api import _
15from tractags.ticket import TicketTagProvider
16
17
18class TagSetup(Component):
19    """[main] Plugin setup and upgrade handler."""
20
21    implements(IEnvironmentSetupParticipant)
22
23    # IEnvironmentSetupParticipant methods
24
25    def environment_created(self):
26        pass
27
28    def environment_needs_upgrade(self, db=None):
29        schema_ver = self.get_schema_version()
30        if schema_ver == db_default.schema_version:
31            return False
32        elif schema_ver > db_default.schema_version:
33            raise TracError(_("A newer plugin version has been installed "
34                              "before, but downgrading is unsupported."))
35        self.log.info("TracTags database schema version is %d, should be %d",
36                      schema_ver, db_default.schema_version)
37        return True
38
39    def upgrade_environment(self, db=None):
40        """Each schema version should have its own upgrade module, named
41        upgrades/dbN.py, where 'N' is the version number (int).
42        """
43        db_mgr = DatabaseManager(self.env)
44        schema_ver = self.get_schema_version()
45
46        with self.env.db_transaction as db:
47            # Is this a new installation?
48            if not schema_ver:
49                # Perform a single-step install: Create plugin schema and
50                # insert default data into the database.
51                connector = db_mgr.get_connector()[0]
52                for table in db_default.schema:
53                    for stmt in connector.to_sql(table):
54                        db(stmt)
55                for table, cols, vals in db_default.get_data(db):
56                    db.executemany("INSERT INTO %s (%s) VALUES (%s)"
57                                   % (table, ','.join(cols),
58                                      ','.join(['%s'] * len(cols))), vals)
59            else:
60                # Perform incremental upgrades.
61                for i in range(schema_ver + 1, db_default.schema_version + 1):
62                    name = 'db%i' % i
63                    try:
64                        upgrades = __import__('tractags.upgrades', globals(),
65                                              locals(), [name])
66                        script = getattr(upgrades, name)
67                    except AttributeError:
68                        raise TracError(_("No upgrade module for version "
69                                          "%(num)i (%(version)s.py)", num=i,
70                                          version=name))
71                    cursor = db.cursor()
72                    script.do_upgrade(self.env, i, cursor)
73            db("""UPDATE system SET value=%s
74                  WHERE name='tags_version'
75                  """, (db_default.schema_version,))
76            self.log.info("Upgraded TracTags db schema from version %d to %d",
77                          schema_ver, db_default.schema_version)
78
79            TicketTagProvider(self.env)._fetch_tkt_tags()
80            self.log.info("Synchronized ticket attributes to tags table")
81
82    def get_db_version(self):
83        for version, in self.env.db_query("""
84                SELECT value FROM system
85                WHERE name='tags_version'
86                """):
87            return int(version)
88
89    def get_schema_version(self):
90        """Return the current schema version for this plugin."""
91        version = self.get_db_version()
92        if not version or version < 2:
93            # Care for pre-tags-0.7 installations.
94            tables = self._get_tables()
95            if 'tags' in tables:
96                self.env.log.debug("TracTags needs to register schema version")
97                return 2
98            if 'wiki_namespace' in tables:
99                self.env.log.debug("TracTags needs to migrate old data")
100                return 1
101            # This is a new installation.
102            return 0
103        # The expected outcome for any up-to-date installation.
104        return version or 0
105
106    # Internal methods
107
108    def _get_tables(self):
109        """Code from TracMigratePlugin by Jun Omae (see tracmigrate.admin)."""
110        dburi = self.config.get('trac', 'database')
111        if dburi.startswith('sqlite:'):
112            sql = """
113                SELECT name FROM sqlite_master
114                WHERE type='table' AND NOT name='sqlite_sequence'
115                """
116        elif dburi.startswith('postgres:'):
117            sql = """
118                SELECT tablename FROM pg_tables
119                WHERE schemaname = ANY (current_schemas(false))
120                """
121        elif dburi.startswith('mysql:'):
122            sql = "SHOW TABLES"
123        else:
124            raise TracError('Unsupported database type "%s"'
125                            % dburi.split(':')[0])
126        with self.env.db_transaction as db:
127            cursor = db.cursor()
128            cursor.execute(sql)
129            return sorted(name for name, in cursor.fetchall())
Note: See TracBrowser for help on using the repository browser.