22from trac .db .schema import Table , Column , Index
33from trac .env import IEnvironmentSetupParticipant
44from trac .db .api import DatabaseManager
5+ from trac .versioncontrol import RepositoryManager
56
67# Database version identifier for upgrades.
78db_version = 3
2223 Index (['author' ]),
2324 ],
2425 'code_comments_subscriptions' : Table ('code_comments_subscriptions' ,
25- key = ('user' , 'type' , 'path' ,
26+ key = ('id' , ' user' , 'type' , 'path' ,
2627 'repos' , 'rev' ))[
28+ Column ('id' , auto_increment = True ),
2729 Column ('user' ),
28- Column ('usertype ' ),
30+ Column ('role ' ),
2931 Column ('type' ),
3032 Column ('path' ),
3133 Column ('repos' ),
3234 Column ('rev' ),
35+ Column ('notify' ),
3336 Index (['user' ]),
3437 Index (['path' ]),
3538 ],
@@ -108,11 +111,16 @@ def add_attachment_subscriptions(db):
108111 cursor .execute ("SELECT type, id, filename, author FROM attachment" )
109112 attachments = cursor .fetchall ()
110113 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 )
114+ sub = {
115+ 'user' : attachment [3 ],
116+ 'role' : 'author' ,
117+ 'type' : 'attachment' ,
118+ 'path' : "/{0}/{1}/{2}" .format (* attachment ),
119+ 'repos' : '' ,
120+ 'rev' : '' ,
121+ 'notify' : 'always' ,
122+ }
123+ add_subscription (env , ** sub )
116124
117125 @env .with_transaction ()
118126 def add_revision_subscriptions (db ):
@@ -123,10 +131,77 @@ def add_revision_subscriptions(db):
123131 cursor .execute ("SELECT repos, rev, author FROM revision" )
124132 revisions = cursor .fetchall ()
125133 for revision in revisions :
126- sql = ("INSERT INTO code_comments_subscriptions VALUES "
127- "('{2}', 'author', 'revision', '', '{0}', '{1}')"
128- ).format (* revision )
134+ sub = {
135+ 'user' : revision [2 ],
136+ 'role' : 'author' ,
137+ 'type' : 'revision' ,
138+ 'path' : '' ,
139+ 'repos' : revision [0 ],
140+ 'rev' : revision [1 ],
141+ 'notify' : 'always' ,
142+ }
143+ add_subscription (env , ** sub )
144+
145+ @env .with_transaction ()
146+ def add_comment_subscriptions (db ):
147+ """
148+ Create a subscription for all existing comments.
149+ """
150+ cursor = db .cursor ()
151+ cursor .execute ("SELECT DISTINCT author, type, path, revision FROM "
152+ "code_comments" )
153+ comments = cursor .fetchall ()
154+ for comment in comments :
155+ sub = {
156+ 'user' : comment [0 ],
157+ 'role' : 'commenter' ,
158+ 'type' : comment [1 ],
159+ 'notify' : 'always' ,
160+ }
161+
162+ # Munge attachments
163+ if sub ['type' ] == 'attachment' :
164+ sub ['path' ] = comment [2 ].split (':' )[1 ]
165+ sub ['repos' ] = ''
166+ sub ['rev' ] = ''
167+
168+ # Munge changesets and browser
169+ if sub ['type' ] == 'changeset' or sub ['type' ] == 'browser' :
170+ sub ['type' ] = 'revision'
171+ sub ['path' ] = comment [2 ]
172+ repo = RepositoryManager (env ).get_repository (None )
173+ try :
174+ sub ['repos' ] = repo .id
175+ sub ['rev' ] = repo .db_rev (int (comment [3 ]))
176+ finally :
177+ repo .close ()
178+
179+ add_subscription (env , ** sub )
180+
181+
182+ def add_subscription (env , ** kwargs ):
183+ """
184+ Helper method for create a code comment subscription.
185+ """
186+ @env .with_transaction ()
187+ def do_add_subscription (db ):
188+ cursor = db .cursor ()
189+ # We need to avoid creating duplicate subscriptions here due to
190+ # the transaction (duplicates will raise an IntegrityError)
191+ query = ("SELECT COUNT(*) FROM code_comments_subscriptions WHERE "
192+ "user = '{user}' AND type = '{type}' AND path = '{path}' "
193+ "AND repos = '{repos}' AND rev = '{rev}' AND "
194+ "notify = '{notify}'" ).format (** kwargs )
195+ cursor .execute (query )
196+ already_subscribed = cursor .fetchone ()[0 ]
197+ if not already_subscribed :
198+ sql = ("INSERT INTO code_comments_subscriptions ('user', "
199+ "'role', 'type', 'path', 'repos', 'rev', 'notify') "
200+ "VALUES ('{user}', '{role}', '{type}', '{path}', "
201+ "'{repos}', '{rev}', '{notify}')" ).format (** kwargs )
129202 cursor .execute (sql )
203+ env .log .info (
204+ "Subscribing {user} to {type} as {role}." .format (** kwargs ))
130205
131206
132207upgrade_map = {
0 commit comments