source: tracformsplugin/trunk/tracforms/tracdb.py

Last change on this file was 16386, checked in by Ryan J Ollos, 7 years ago

TracForms 0.5dev: Make compatible with Trac 1.2

Fixes #13127.

File size: 5.7 KB
Line 
1# -*- coding: utf-8 -*-
2
3from trac.core import Component, implements
4from trac.db import Column, DatabaseManager, Index, Table
5from trac.env import IEnvironmentSetupParticipant
6
7# Database version identifier. Used for automatic upgrades.
8db_version = 14
9
10##
11# Database schema
12
13schema = [
14    # root table
15    Table('forms', key='id')[
16        Column('id', auto_increment=True),
17        Column('realm'),
18        Column('resource_id'),
19        Column('subcontext'),
20        Column('state'),
21        Column('author'),
22        Column('time', type='int'),
23        Column('keep_history', type='int'),
24        Column('track_fields', type='int'),
25        Index(['realm', 'resource_id', 'subcontext'], unique=True),
26        Index(['author']),
27        Index(['time'])],
28
29    # field changes tracking
30    Table('forms_fields')[
31        Column('id', type='int'),
32        Column('field'),
33        Column('author'),
34        Column('time', type='int'),
35        Index(['id', 'field'], unique=True)],
36
37    # change history
38    Table('forms_history')[
39        Column('id', type='int'),
40        Column('author'),
41        Column('time', type='int'),
42        Column('old_state'),
43        Index(['id']),
44        Index(['author']),
45        Index(['time'])],
46]
47
48
49def _db_to_version(name):
50    return int(name.lstrip('db'))
51
52
53class DBComponent(Component):
54    """Provides TracForms db schema management methods."""
55
56    implements(IEnvironmentSetupParticipant)
57
58    apply_schema = False
59    plugin_name = 'forms'
60
61    # IEnvironmentSetupParticipant methods
62
63    def environment_created(self):
64        pass
65
66    def environment_needs_upgrade(self, db=None):
67        if not type(self).__dict__.get('apply_schema', False):
68            self.log.debug("Not checking schema for \"%s\", since "
69                           "apply_schema is not defined or is False.",
70                           type(self).__name__)
71            return False
72        installed = self.get_installed_version()
73        for version, fn in self.get_schema_functions():
74            if version > installed:
75                self.log.debug('"%s" requires a schema upgrade.',
76                               type(self).__name__)
77                return True
78        else:
79            self.log.debug('"%s" does not need a schema upgrade.',
80                           type(self).__name__)
81            return False
82
83    def upgrade_environment(self, db=None):
84        if not type(self).__dict__.get('apply_schema', False):
85            self.log.debug("Not updating schema for \"%s\" since "
86                           "apply_schema is not defined or is False.",
87                           type(self).__name__)
88            return
89        installed = self.get_installed_version()
90        if installed is None:
91            self.log.info("Installing TracForm plugin schema %s", db_version)
92            db_connector = DatabaseManager(self.env).get_connector()[0]
93            with self.env.db_transaction as db:
94                for table in schema:
95                    for stmt in db_connector.to_sql(table):
96                        db(stmt)
97                self.set_installed_version(db_version)
98            self.log.info("Installation of %s successful.", db_version)
99            return
100        self.log.debug(
101            'Upgrading schema for "%s".' % type(self).__name__)
102        for version, fn in self.get_schema_functions():
103            if version > installed:
104                self.log.info("Upgrading TracForm plugin schema to %s",
105                              version)
106                self.log.info('- %s: %s' % (fn.__name__, fn.__doc__))
107                self.set_installed_version(version)
108                installed = version
109                self.log.info("Upgrade to %s successful.", version)
110
111    # TracForms db schema management methods
112
113    def get_installed_version(self):
114        version = self.get_system_value(self.plugin_name + '_version')
115        if version is None:
116            # check for old naming schema
117            oldversion = self.get_system_value('TracFormDBComponent:version')
118            version = _db_oldversion_dict.get(oldversion)
119        if version is None:
120            return version
121        return int(version)
122
123    def get_schema_functions(self, prefix='db'):
124        fns = []
125        for name in self.__dict__:
126            if name.startswith(prefix):
127                fns.append((_db_to_version(name), getattr(self, name)))
128        for cls in type(self).__mro__:
129            for name in cls.__dict__:
130                if name.startswith(prefix):
131                    fns.append((_db_to_version(name), getattr(self, name)))
132        fns.sort()
133        return tuple(fns)
134
135    def set_installed_version(self, version):
136        self.set_system_value(self.plugin_name + '_version', version)
137
138    # Trac db 'system' table management methods for TracForms entry
139
140    def get_system_value(self, key):
141        for value, in self.env.db_query("""
142                SELECT value FROM system WHERE name=%s
143                """, (key,)):
144            return value
145
146    def set_system_value(self, key, value):
147        """Atomic UPSERT db transaction to save TracForms version."""
148        with self.env.db_transaction as db:
149            for value, in db("""
150                    SELECT value FROM system WHERE name=%s
151                    """, (key,)):
152                db("""
153                    UPDATE system SET value=%s WHERE name=%s
154                    """, (value, key))
155                break
156            else:
157                db("""
158                    INSERT INTO system(name, value) VALUES(%s, %s)
159                    """, (key, value))
160
161
162_db_oldversion_dict = {
163    'dbschema_2008_06_15_0000': 0, 'dbschema_2008_06_15_0001': 1,
164    'dbschema_2008_06_14_0002': 2, 'dbschema_2008_06_15_0003': 3,
165    'dbschema_2008_06_15_0004': 4, 'dbschema_2008_06_15_0010': 10,
166    'dbschema_2008_06_15_0011': 11, 'dbschema_2008_06_15_0012': 12,
167}
Note: See TracBrowser for help on using the repository browser.