1- from trac .core import *
1+ from trac .core import Component , implements
22from trac .db .schema import Table , Column , Index
33from trac .env import IEnvironmentSetupParticipant
44from trac .db .api import DatabaseManager
55
66# Database version identifier for upgrades.
7- db_version = 2
7+ db_version = 3
88
99# Database schema
1010schema = {
2121 Index (['path' ]),
2222 Index (['author' ]),
2323 ],
24+ 'code_comments_subscriptions' : Table ('code_comments_subscriptions' ,
25+ key = ('user' , 'type' , 'path' ,
26+ 'repos' , 'rev' ))[
27+ Column ('user' ),
28+ Column ('usertype' ),
29+ Column ('type' ),
30+ Column ('path' ),
31+ Column ('repos' ),
32+ Column ('rev' ),
33+ Index (['user' ]),
34+ Index (['path' ]),
35+ ],
2436}
2537
38+
2639def to_sql (env , table ):
2740 """ Convenience function to get the to_sql for the active connector."""
2841 dc = DatabaseManager (env )._get_connector ()[0 ]
2942 return dc .to_sql (table )
3043
44+
3145def create_tables (env , db ):
3246 cursor = db .cursor ()
3347 for table_name in schema :
3448 for stmt in to_sql (env , schema [table_name ]):
3549 cursor .execute (stmt )
36- cursor .execute ("INSERT into system values ('code_comments_schema_version', %s)" ,
37- str (db_version ))
50+ cursor .execute (
51+ "insert into system values ('code_comments_schema_version', %s)" ,
52+ str (db_version ))
53+
3854
3955# Upgrades
56+
4057def upgrade_from_1_to_2 (env , db ):
4158 # Add the new column "type"
4259 @env .with_transaction ()
43- def add_type_column ( db ):
60+ def add_type_column (db ):
4461 cursor = db .cursor ()
45- cursor .execute ( 'ALTER TABLE code_comments ADD COLUMN type TEXT' )
62+ cursor .execute ('ALTER TABLE code_comments ADD COLUMN type TEXT' )
4663
4764 # Convert all the current comments to the new schema
4865 @env .with_transaction ()
49- def convert_comments ( db ):
66+ def convert_comments (db ):
5067 comments = {}
5168 cursor = db .cursor ()
52- cursor .execute ( 'SELECT id, path FROM code_comments' )
69+ cursor .execute ('SELECT id, path FROM code_comments' )
5370 comments = cursor .fetchall ()
5471 # options:
5572 # 1: comment on file (path != "" && path != "attachment")
5673 # 2: comment on changeset (path == "")
5774 # 3: comment on attachment (path == "attachment")
5875 for comment in comments :
5976 path = comment [1 ]
60- is_comment_to_attachment = path .startswith ( 'attachment' )
77+ is_comment_to_attachment = path .startswith ('attachment' )
6178 is_comment_to_file = not is_comment_to_attachment and '' != path
6279 is_comment_to_changeset = '' == path
6380 cursor = db .cursor ()
6481 update = 'UPDATE code_comments SET type={0} WHERE id={1}'
6582 sql = ''
6683
6784 if is_comment_to_changeset :
68- sql = update .format ( "'changeset'" , str ( comment [0 ] ) )
85+ sql = update .format ("'changeset'" , str (comment [0 ]) )
6986 elif is_comment_to_attachment :
70- sql = update .format ( "'attachment'" , str (comment [0 ] ) )
87+ sql = update .format ("'attachment'" , str (comment [0 ]) )
7188 elif is_comment_to_file :
72- sql = update .format ( "'browser'" , str (comment [0 ] ) )
89+ sql = update .format ("'browser'" , str (comment [0 ]))
90+
91+ cursor .execute (sql )
92+
93+
94+ def upgrade_from_2_to_3 (env , db ):
95+ # Add the new table
96+ @env .with_transaction ()
97+ def add_subscriptions_table (db ):
98+ cursor = db .cursor ()
99+ for stmt in to_sql (env , schema ['code_comments_subscriptions' ]):
100+ cursor .execute (stmt )
101+
102+ @env .with_transaction ()
103+ def add_attachment_subscriptions (db ):
104+ """
105+ Create a subscription for all existing attachments.
106+ """
107+ cursor = db .cursor ()
108+ cursor .execute ("SELECT type, id, filename, author FROM attachment" )
109+ attachments = cursor .fetchall ()
110+ for attachment in attachments :
111+ path = "/{0}/{1}/{2}" .format (* attachment )
112+ sql = ("INSERT INTO code_comments_subscriptions VALUES "
113+ "('{3}', 'author', 'attachment', '{path}', '', '')"
114+ ).format (* attachment , path = path )
115+ cursor .execute (sql )
116+
117+ @env .with_transaction ()
118+ def add_revision_subscriptions (db ):
119+ """
120+ Create a subscription for all existing revisions.
121+ """
122+ cursor = db .cursor ()
123+ cursor .execute ("SELECT repos, rev, author FROM revision" )
124+ revisions = cursor .fetchall ()
125+ for revision in revisions :
126+ sql = ("INSERT INTO code_comments_subscriptions VALUES "
127+ "('{2}', 'author', 'revision', '', '{0}', '{1}')"
128+ ).format (* revision )
129+ cursor .execute (sql )
73130
74- cursor .execute ( sql )
75131
76132upgrade_map = {
77- 2 : upgrade_from_1_to_2
78- }
133+ 2 : upgrade_from_1_to_2 ,
134+ 3 : upgrade_from_2_to_3 ,
135+ }
136+
79137
80138class CodeCommentsSetup (Component ):
81139 """Component that deals with database setup and upgrades."""
@@ -87,13 +145,17 @@ def environment_created(self):
87145 pass
88146
89147 def environment_needs_upgrade (self , db ):
90- """Called when Trac checks whether the environment needs to be upgraded.
91- Returns `True` if upgrade is needed, `False` otherwise."""
148+ """
149+ Called when Trac checks whether the environment needs to be upgraded.
150+ Returns `True` if upgrade is needed, `False` otherwise.
151+ """
92152 return self ._get_version (db ) != db_version
93153
94154 def upgrade_environment (self , db ):
95- """Actually perform an environment upgrade, but don't commit as
96- that is done by the common upgrade procedure when all plugins are done."""
155+ """
156+ Actually perform an environment upgrade, but don't commit as
157+ that is done by the common upgrade procedure when all plugins are done.
158+ """
97159 current_ver = self ._get_version (db )
98160 if current_ver == 0 :
99161 create_tables (self .env , db )
@@ -102,8 +164,9 @@ def upgrade_environment(self, db):
102164 upgrade_map [current_ver + 1 ](self .env , db )
103165 current_ver += 1
104166 cursor = db .cursor ()
105- cursor .execute ("UPDATE system SET value=%s WHERE name='code_comments_schema_version'" ,
106- str (db_version ))
167+ cursor .execute (
168+ "UPDATE system SET value=%s WHERE name='code_comments_schema_version'" ,
169+ str (db_version ))
107170
108171 def _get_version (self , db ):
109172 cursor = db .cursor ()
0 commit comments