Index: trunk/extensions/LiquidThreads/classes/LqtThreads.php |
— | — | @@ -135,90 +135,31 @@ |
136 | 136 | } |
137 | 137 | } |
138 | 138 | } |
| 139 | + |
| 140 | + static function loadFromResult( $res, $db ) { |
| 141 | + $rows = array(); |
| 142 | + |
| 143 | + while( $row = $db->fetchObject( $res ) ) { |
| 144 | + $rows[] = $row; |
| 145 | + } |
| 146 | + |
| 147 | + return Thread::bulkLoad( $rows ); |
| 148 | + } |
139 | 149 | |
140 | | - static function where( $where, $options = array(), $extra_tables = array(), |
141 | | - $joins = "" ) { |
| 150 | + static function where( $where, $options = array() ) { |
142 | 151 | global $wgDBprefix; |
143 | 152 | $dbr = wfGetDB( DB_SLAVE ); |
144 | | - if ( is_array( $where ) ) $where = $dbr->makeList( $where, LIST_AND ); |
145 | | - if ( is_array( $options ) ) $options = implode( ',', $options ); |
146 | | - |
147 | | - if ( is_array( $extra_tables ) && count( $extra_tables ) != 0 ) { |
148 | | - if ( !empty( $wgDBprefix ) ) { |
149 | | - foreach ( $extra_tables as $tablekey => $extra_table ) |
150 | | - $extra_tables[$tablekey] = $wgDBprefix . $extra_table; |
151 | | - } |
152 | | - $tables = implode( ',', $extra_tables ) . ', '; |
153 | | - } else if ( is_string( $extra_tables ) ) { |
154 | | - $tables = $extra_tables . ', '; |
155 | | - } else { |
156 | | - $tables = ""; |
157 | | - } |
158 | | - |
159 | | - $selection_sql = <<< SQL |
160 | | - SELECT DISTINCT thread.* FROM ($tables {$wgDBprefix}thread thread) |
161 | | - $joins |
162 | | - WHERE $where |
163 | | - $options |
164 | | -SQL; |
165 | | - $selection_res = $dbr->query( $selection_sql ); |
166 | | - |
167 | | - $ancestor_conds = array(); |
168 | | - $selection_conds = array(); |
169 | | - while ( $line = $dbr->fetchObject( $selection_res ) ) { |
170 | | - $ancestor_conds[] = $line->thread_ancestor; |
171 | | - $selection_conds[] = $line->thread_id; |
172 | | - } |
173 | | - if ( count( $selection_conds ) == 0 ) { |
174 | | - // No threads were found, so we can skip the second query. |
175 | | - return array(); |
176 | | - } // List comprehensions, how I miss thee. |
177 | | - $ancestor_clause = join( ', ', $ancestor_conds ); |
178 | | - $selection_clause = join( ', ', $selection_conds ); |
179 | 153 | |
180 | | - // TODO uses a subquery, unsupported on Wikimedia |
| 154 | + $res = $dbr->select( 'thread', '*', $where, __METHOD__, $options ); |
| 155 | + |
| 156 | + $threads = Threads::loadFromResult( $res, $dbr ); |
181 | 157 | |
182 | | - $children_sql = <<< SQL |
183 | | - SELECT DISTINCT thread.*, page.*, |
184 | | - thread.thread_id IN($selection_clause) as selected |
185 | | - FROM ({$wgDBprefix}thread thread, {$wgDBprefix}page page) |
186 | | - WHERE thread.thread_ancestor IN($ancestor_clause) |
187 | | - AND page.page_id = thread.thread_root |
188 | | - $options |
189 | | -SQL; |
190 | | - $res = $dbr->query( $children_sql ); |
191 | | - |
192 | | - $threads = array(); |
193 | | - $top_level_threads = array(); |
194 | | - $thread_children = array(); |
195 | | - |
196 | | - while ( $line = $dbr->fetchObject( $res ) ) { |
197 | | - $new_thread = new Thread( $line, null ); |
198 | | - $threads[] = $new_thread; |
199 | | - if ( $line->selected ) |
200 | | - // thread is one of those that was directly queried for. |
201 | | - $top_level_threads[] = $new_thread; |
202 | | - if ( $line->thread_parent !== null ) { |
203 | | - if ( !array_key_exists( $line->thread_parent, $thread_children ) ) |
204 | | - $thread_children[$line->thread_parent] = array(); |
205 | | - // Can have duplicate if thread is both top_level and child of another top_level thread. |
206 | | - if ( !self::arrayContainsThreadWithId( $thread_children[$line->thread_parent], $new_thread->id() ) ) |
207 | | - $thread_children[$line->thread_parent][] = $new_thread; |
208 | | - } |
209 | | - } |
210 | | - |
211 | 158 | foreach ( $threads as $thread ) { |
212 | | - if ( array_key_exists( $thread->id(), $thread_children ) ) { |
213 | | - $thread->initWithReplies( $thread_children[$thread->id()] ); |
214 | | - } else { |
215 | | - $thread->initWithReplies( array() ); |
216 | | - } |
217 | | - |
218 | 159 | self::$cache_by_root[$thread->root()->getID()] = $thread; |
219 | 160 | self::$cache_by_id[$thread->id()] = $thread; |
220 | 161 | } |
221 | 162 | |
222 | | - return $top_level_threads; |
| 163 | + return $threads; |
223 | 164 | } |
224 | 165 | |
225 | 166 | private static function databaseError( $msg ) { |
Index: trunk/extensions/LiquidThreads/classes/LqtNewMessages.php |
— | — | @@ -95,6 +95,7 @@ |
96 | 96 | array( |
97 | 97 | 'ums_user' => $row->wl_user, |
98 | 98 | 'ums_thread' => $t->id(), |
| 99 | + 'ums_read_timestamp' => null, |
99 | 100 | ); |
100 | 101 | } |
101 | 102 | |
— | — | @@ -194,22 +195,42 @@ |
195 | 196 | } |
196 | 197 | |
197 | 198 | static function newUserMessages( $user ) { |
198 | | - global $wgDBprefix; |
| 199 | + $talkPage = new Article( $user->getUserPage()->getTalkPage() ); |
199 | 200 | |
200 | | - $talkPage = new Article( $user->getUserPage()->getTalkPage() ); |
201 | | - return Threads::where( array( 'ums_read_timestamp is null', |
| 201 | + $dbr = wfGetDB( DB_SLAVE ); |
| 202 | + |
| 203 | + $joinConds = array( 'ums_user' => null ); |
| 204 | + $joinConds[] = $dbr->makeList( array( 'ums_user' => $user->getId(), |
| 205 | + 'ums_thread=thread_id' ), LIST_AND ); |
| 206 | + $joinClause = $dbr->makeList( $joinConds, LIST_OR ); |
| 207 | + |
| 208 | + $res = $dbr->select( array( 'thread', 'user_message_state' ), '*', |
| 209 | + array( 'ums_read_timestamp' => null, |
202 | 210 | Threads::articleClause( $talkPage ) ), |
203 | | - array(), array(), |
204 | | - "left outer join {$wgDBprefix}user_message_state on " . |
205 | | - "ums_user is null or ". |
206 | | - "(ums_user = {$user->getID()} and ums_thread = thread.thread_id)" ); |
| 211 | + __METHOD__, array(), |
| 212 | + array( |
| 213 | + 'user_message_state' => |
| 214 | + array( 'LEFT OUTER JOIN', $joinClause ) |
| 215 | + ) ); |
| 216 | + |
| 217 | + return Threads::loadFromResult( $res, $dbr ); |
207 | 218 | } |
208 | 219 | |
209 | 220 | static function watchedThreadsForUser( $user ) { |
210 | | - return Threads::where( array( 'ums_read_timestamp is null', |
211 | | - 'ums_user' => $user->getID(), |
212 | | - 'ums_thread = thread.thread_id', |
213 | | - 'NOT (' . Threads::articleClause( new Article( $user->getTalkPage() ) ) . ')' ), |
214 | | - array(), array( 'user_message_state' ) ); |
| 221 | + $talkPage = new Article( $user->getUserPage()->getTalkPage() ); |
| 222 | + |
| 223 | + $dbr = wfGetDB( DB_SLAVE ); |
| 224 | + |
| 225 | + $res = $dbr->select( array( 'thread', 'user_message_state' ), '*', |
| 226 | + array( 'ums_read_timestamp' => null, |
| 227 | + 'ums_user' => $user->getId(), |
| 228 | + 'not (' . Threads::articleClause( $talkPage ) . ')', |
| 229 | + ), |
| 230 | + __METHOD__, array(), |
| 231 | + array( 'user_message_state' => |
| 232 | + array( 'INNER JOIN', 'ums_thread=thread_id' ), |
| 233 | + ) ); |
| 234 | + |
| 235 | + return Threads::loadFromResult( $res, $dbr ); |
215 | 236 | } |
216 | 237 | } |