@@ -104,48 +104,55 @@ def commitfest(request, cfid):
104104 cf = get_object_or_404 (CommitFest , pk = cfid )
105105
106106 # Build a dynamic filter based on the filtering options entered
107- q = Q ()
107+ whereclauses = []
108+ whereparams = {}
108109 if request .GET .has_key ('status' ) and request .GET ['status' ] != "-1" :
109110 try :
110- q = q & Q (patchoncommitfest__status = int (request .GET ['status' ]))
111+ whereclauses .append ("poc.status=%(status)s" )
112+ whereparams ['status' ] = int (request .GET ['status' ])
111113 except ValueError :
112114 # int() failed -- so just ignore this filter
113115 pass
114116
115117 if request .GET .has_key ('author' ) and request .GET ['author' ] != "-1" :
116118 if request .GET ['author' ] == '-2' :
117- q = q & Q ( authors = None )
119+ whereclauses . append ( "NOT EXISTS (SELECT 1 FROM commitfest_patch_authors cpa WHERE cpa.patch_id=p.id)" )
118120 elif request .GET ['author' ] == '-3' :
119121 # Checking for "yourself" requires the user to be logged in!
120122 if not request .user .is_authenticated ():
121123 return HttpResponseRedirect ('%s?next=%s' % (settings .LOGIN_URL , request .path ))
122- q = q & Q (authors = request .user )
124+ whereclauses .append ("EXISTS (SELECT 1 FROM commitfest_patch_authors cpa WHERE cpa.patch_id=p.id AND cpa.user_id=%(self)s)" )
125+ whereparams ['self' ] = request .user .id
123126 else :
124127 try :
125- q = q & Q (authors__id = int (request .GET ['author' ]))
128+ whereclauses .append ("EXISTS (SELECT 1 FROM commitfest_patch_authors cpa WHERE cpa.patch_id=p.id AND cpa.user_id=%(author)s)" )
129+ whereparams ['author' ] = int (request .GET ['author' ])
126130 except ValueError :
127131 # int() failed -- so just ignore this filter
128132 pass
129133
130134 if request .GET .has_key ('reviewer' ) and request .GET ['reviewer' ] != "-1" :
131135 if request .GET ['reviewer' ] == '-2' :
132- q = q & Q ( reviewers = None )
136+ whereclauses . append ( "NOT EXISTS (SELECT 1 FROM commitfest_patch_reviewers cpr WHERE cpr.patch_id=p.id)" )
133137 elif request .GET ['reviewer' ] == '-3' :
134138 # Checking for "yourself" requires the user to be logged in!
135139 if not request .user .is_authenticated ():
136140 return HttpResponseRedirect ('%s?next=%s' % (settings .LOGIN_URL , request .path ))
137- q = q & Q (reviewers = request .user )
141+ whereclauses .append ("EXISTS (SELECT 1 FROM commitfest_patch_reviewers cpr WHERE cpr.patch_id=p.id AND cpr.user_id=%(self)s)" )
142+ whereparams ['self' ] = request .user .id
138143 else :
139144 try :
140- q = q & Q (reviewers__id = int (request .GET ['reviewer' ]))
145+ whereclauses .append ("EXISTS (SELECT 1 FROM commitfest_patch_reviewers cpr WHERE cpr.patch_id=p.id AND cpr.user_id=%(reviewer)s)" )
146+ whereparams ['reviewer' ] = int (request .GET ['reviewer' ])
141147 except ValueError :
142148 # int() failed -- so just ignore this filter
143149 pass
144150
145151 if request .GET .has_key ('text' ) and request .GET ['text' ] != '' :
146- q = q & Q (name__icontains = request .GET ['text' ])
152+ whereclauses .append ("p.name ILIKE '%%' || %(txt)s || '%%'" )
153+ whereparams ['txt' ] = request .GET ['text' ]
147154
148- has_filter = len (q . children ) > 0
155+ has_filter = len (whereclauses ) > 0
149156
150157 # Figure out custom ordering
151158 ordering = ['-is_open' , 'topic__topic' , 'created' ,]
@@ -156,27 +163,46 @@ def commitfest(request, cfid):
156163 sortkey = 0
157164
158165 if sortkey == 1 :
159- ordering = [ '-is_open' , ' modified' , ' created',]
166+ orderby_str = ' modified, created'
160167 elif sortkey == 2 :
161- ordering = [ '-is_open' , ' lastmail' , ' created',]
168+ orderby_str = ' lastmail, created'
162169 elif sortkey == 3 :
163- ordering = [ '-is_open' , '- num_cfs' , ' modified' , ' created']
170+ orderby_str = ' num_cfs DESC, modified, created'
164171 else :
172+ orderby_str = 'p.id'
165173 sortkey = 0
166174 else :
175+ orderby_str = 'p.id'
167176 sortkey = 0
168177
169178 if not has_filter and sortkey == 0 and request .GET :
170179 # Redirect to get rid of the ugly url
171180 return HttpResponseRedirect ('/%s/' % cf .id )
172181
173- patches = list (cf .patch_set .filter (q ).select_related ().extra (select = {
174- 'status' :'commitfest_patchoncommitfest.status' ,
175- 'author_names' :"SELECT string_agg(first_name || ' ' || last_name || ' (' || username || ')', ', ') FROM auth_user INNER JOIN commitfest_patch_authors cpa ON cpa.user_id=auth_user.id WHERE cpa.patch_id=commitfest_patch.id" ,
176- 'reviewer_names' :"SELECT string_agg(first_name || ' ' || last_name || ' (' || username || ')', ', ') FROM auth_user INNER JOIN commitfest_patch_reviewers cpr ON cpr.user_id=auth_user.id WHERE cpr.patch_id=commitfest_patch.id" ,
177- 'is_open' :'commitfest_patchoncommitfest.status IN (%s)' % ',' .join ([str (x ) for x in PatchOnCommitFest .OPEN_STATUSES ]),
178- 'num_cfs' : 'SELECT count(1) FROM commitfest_patchoncommitfest pcf WHERE pcf.patch_id=commitfest_patch.id' ,
179- }).order_by (* ordering ))
182+ if whereclauses :
183+ where_str = 'AND ({0})' .format (' AND ' .join (whereclauses ))
184+ else :
185+ where_str = ''
186+ params = {
187+ 'cid' : cf .id ,
188+ 'openstatuses' : PatchOnCommitFest .OPEN_STATUSES ,
189+ }
190+ params .update (whereparams )
191+
192+ # Let's not overload the poor django ORM
193+ curs = connection .cursor ()
194+ curs .execute ("""SELECT p.id, p.name, poc.status, p.created, p.modified, p.lastmail, committer.username AS committer,
195+ (poc.status=ANY(%(openstatuses)s)) AS is_open,
196+ (SELECT string_agg(first_name || ' ' || last_name || ' (' || username || ')', ', ') FROM auth_user INNER JOIN commitfest_patch_authors cpa ON cpa.user_id=auth_user.id WHERE cpa.patch_id=p.id) AS author_names,
197+ (SELECT string_agg(first_name || ' ' || last_name || ' (' || username || ')', ', ') FROM auth_user INNER JOIN commitfest_patch_reviewers cpr ON cpr.user_id=auth_user.id WHERE cpr.patch_id=p.id) AS reviewer_names,
198+ (SELECT count(1) FROM commitfest_patchoncommitfest pcf WHERE pcf.patch_id=p.id) AS num_cfs
199+ FROM commitfest_patch p
200+ INNER JOIN commitfest_patchoncommitfest poc ON poc.patch_id=p.id
201+ LEFT JOIN auth_user committer ON committer.id=p.committer_id
202+ WHERE poc.commitfest_id=%(cid)s {0}
203+ GROUP BY p.id, poc.id, committer.id
204+ ORDER BY is_open DESC, {1}""" .format (where_str , orderby_str ), params )
205+ patches = [dict (zip ([col [0 ] for col in curs .description ], row )) for row in curs .fetchall ()]
180206
181207 # Generate patch status summary.
182208 curs = connection .cursor ()
@@ -199,7 +225,7 @@ def commitfest(request, cfid):
199225 'title' : cf .title ,
200226 'grouping' : sortkey == 0 ,
201227 'sortkey' : sortkey ,
202- 'openpatchids' : [p . id for p in patches if p . is_open ],
228+ 'openpatchids' : [p [ 'id' ] for p in patches if p [ ' is_open' ] ],
203229 'header_activity' : 'Activity log' ,
204230 'header_activity_link' : 'activity/' ,
205231 })
0 commit comments