Index: trunk/phase3/includes/api/ApiQueryAllLinks.php |
— | — | @@ -101,8 +101,9 @@ |
102 | 102 | |
103 | 103 | $res = $this->select(__METHOD__); |
104 | 104 | |
105 | | - $data = array (); |
| 105 | + $pageids = array (); |
106 | 106 | $count = 0; |
| 107 | + $result = $this->getResult(); |
107 | 108 | while ($row = $db->fetchObject($res)) { |
108 | 109 | if (++ $count > $limit) { |
109 | 110 | // We've reached the one extra which shows that there are additional pages to be had. Stop here... |
— | — | @@ -123,7 +124,13 @@ |
124 | 125 | $vals['ns'] = intval($title->getNamespace()); |
125 | 126 | $vals['title'] = $title->getPrefixedText(); |
126 | 127 | } |
127 | | - $data[] = $vals; |
| 128 | + $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals); |
| 129 | + if(!$fit) |
| 130 | + { |
| 131 | + $this->setContinueEnumParameter('continue', |
| 132 | + $this->keyToTitle($row->pl_title) . "|" . $row->pl_from); |
| 133 | + break; |
| 134 | + } |
128 | 135 | } else { |
129 | 136 | $pageids[] = $row->pl_from; |
130 | 137 | } |
— | — | @@ -131,9 +138,7 @@ |
132 | 139 | $db->freeResult($res); |
133 | 140 | |
134 | 141 | if (is_null($resultPageSet)) { |
135 | | - $result = $this->getResult(); |
136 | | - $result->setIndexedTagName($data, 'l'); |
137 | | - $result->addValue('query', $this->getModuleName(), $data); |
| 142 | + $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'l'); |
138 | 143 | } else { |
139 | 144 | $resultPageSet->populateFromPageIDs($pageids); |
140 | 145 | } |
— | — | @@ -192,4 +197,4 @@ |
193 | 198 | public function getVersion() { |
194 | 199 | return __CLASS__ . ': $Id$'; |
195 | 200 | } |
196 | | -} |
| 201 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQueryRecentChanges.php |
— | — | @@ -191,9 +191,7 @@ |
192 | 192 | $this->token = $params['token']; |
193 | 193 | $this->addOption('LIMIT', $params['limit'] +1); |
194 | 194 | |
195 | | - $data = array (); |
196 | 195 | $count = 0; |
197 | | - |
198 | 196 | /* Perform the actual query. */ |
199 | 197 | $db = $this->getDB(); |
200 | 198 | $res = $this->select(__METHOD__); |
— | — | @@ -210,16 +208,20 @@ |
211 | 209 | $vals = $this->extractRowInfo($row); |
212 | 210 | |
213 | 211 | /* Add that row's data to our final output. */ |
214 | | - if($vals) |
215 | | - $data[] = $vals; |
| 212 | + if(!$vals) |
| 213 | + continue; |
| 214 | + $fit = $this->getResult()->addValue(array('query', $this->getModuleName()), null, $vals); |
| 215 | + if(!$fit) |
| 216 | + { |
| 217 | + $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->rc_timestamp)); |
| 218 | + break; |
| 219 | + } |
216 | 220 | } |
217 | 221 | |
218 | 222 | $db->freeResult($res); |
219 | 223 | |
220 | 224 | /* Format the result */ |
221 | | - $result = $this->getResult(); |
222 | | - $result->setIndexedTagName($data, 'rc'); |
223 | | - $result->addValue('query', $this->getModuleName(), $data); |
| 225 | + $this->getResult()->setIndexedTagName_internal(array('query', $this->getModuleName()), 'rc'); |
224 | 226 | } |
225 | 227 | |
226 | 228 | /** |
— | — | @@ -453,4 +455,4 @@ |
454 | 456 | public function getVersion() { |
455 | 457 | return __CLASS__ . ': $Id$'; |
456 | 458 | } |
457 | | -} |
| 459 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQueryAllCategories.php |
— | — | @@ -110,14 +110,18 @@ |
111 | 111 | } |
112 | 112 | if( isset( $prop['hidden'] ) && $row->cat_hidden ) |
113 | 113 | $item['hidden'] = ''; |
114 | | - $categories[] = $item; |
| 114 | + $fit = $result->addValue(array('query', $this->getModuleName()), null, $item); |
| 115 | + if(!$fit) |
| 116 | + { |
| 117 | + $this->setContinueEnumParameter('from', $this->keyToTitle($row->cat_title)); |
| 118 | + break; |
| 119 | + } |
115 | 120 | } |
116 | 121 | } |
117 | 122 | $db->freeResult($res); |
118 | 123 | |
119 | 124 | if (is_null($resultPageSet)) { |
120 | | - $result->setIndexedTagName($categories, 'c'); |
121 | | - $result->addValue('query', $this->getModuleName(), $categories); |
| 125 | + $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'c'); |
122 | 126 | } else { |
123 | 127 | $resultPageSet->populateFromTitles($pages); |
124 | 128 | } |
— | — | @@ -173,4 +177,4 @@ |
174 | 178 | public function getVersion() { |
175 | 179 | return __CLASS__ . ': $Id$'; |
176 | 180 | } |
177 | | -} |
| 181 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQueryLinks.php |
— | — | @@ -119,9 +119,6 @@ |
120 | 120 | $res = $this->select(__METHOD__); |
121 | 121 | |
122 | 122 | if (is_null($resultPageSet)) { |
123 | | - |
124 | | - $data = array(); |
125 | | - $lastId = 0; // database has no ID 0 |
126 | 123 | $count = 0; |
127 | 124 | while ($row = $db->fetchObject($res)) { |
128 | 125 | if(++$count > $params['limit']) { |
— | — | @@ -132,23 +129,17 @@ |
133 | 130 | $this->keyToTitle($row->pl_title)); |
134 | 131 | break; |
135 | 132 | } |
136 | | - if ($lastId != $row->pl_from) { |
137 | | - if($lastId != 0) { |
138 | | - $this->addPageSubItems($lastId, $data); |
139 | | - $data = array(); |
140 | | - } |
141 | | - $lastId = $row->pl_from; |
142 | | - } |
143 | | - |
144 | 133 | $vals = array(); |
145 | 134 | ApiQueryBase :: addTitleInfo($vals, Title :: makeTitle($row->pl_namespace, $row->pl_title)); |
146 | | - $data[] = $vals; |
| 135 | + $fit = $this->addPageSubItem($row->pl_from, $vals); |
| 136 | + if(!$fit) |
| 137 | + { |
| 138 | + $this->setContinueEnumParameter('continue', |
| 139 | + "{$row->pl_from}|{$row->pl_namespace}|" . |
| 140 | + $this->keyToTitle($row->pl_title)); |
| 141 | + break; |
| 142 | + } |
147 | 143 | } |
148 | | - |
149 | | - if($lastId != 0) { |
150 | | - $this->addPageSubItems($lastId, $data); |
151 | | - } |
152 | | - |
153 | 144 | } else { |
154 | 145 | |
155 | 146 | $titles = array(); |
— | — | @@ -215,4 +206,4 @@ |
216 | 207 | public function getVersion() { |
217 | 208 | return __CLASS__ . ': $Id$'; |
218 | 209 | } |
219 | | -} |
| 210 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQueryRandom.php |
— | — | @@ -62,7 +62,7 @@ |
63 | 63 | $this->addFields($resultPageSet->getPageTableFields()); |
64 | 64 | } |
65 | 65 | |
66 | | - protected function runQuery(&$data, &$resultPageSet) { |
| 66 | + protected function runQuery(&$resultPageSet) { |
67 | 67 | $db = $this->getDB(); |
68 | 68 | $res = $this->select(__METHOD__); |
69 | 69 | $count = 0; |
— | — | @@ -73,7 +73,14 @@ |
74 | 74 | // Prevent duplicates |
75 | 75 | if(!in_array($row->page_id, $this->pageIDs)) |
76 | 76 | { |
77 | | - $data[] = $this->extractRowInfo($row); |
| 77 | + $fit = $this->getResult()->addValue( |
| 78 | + array('query', $this->getModuleName()), |
| 79 | + null, $this->extractRowInfo($row)); |
| 80 | + if(!$fit) |
| 81 | + # We can't really query-continue a random list. |
| 82 | + # Return an insanely high value so |
| 83 | + # $count < $limit is false |
| 84 | + return 1E9; |
78 | 85 | $this->pageIDs[] = $row->page_id; |
79 | 86 | } |
80 | 87 | } |
— | — | @@ -87,11 +94,10 @@ |
88 | 95 | public function run($resultPageSet = null) { |
89 | 96 | $params = $this->extractRequestParams(); |
90 | 97 | $result = $this->getResult(); |
91 | | - $data = array(); |
92 | 98 | $this->pageIDs = array(); |
93 | 99 | |
94 | 100 | $this->prepareQuery(wfRandom(), $params['limit'], $params['namespace'], $resultPageSet, $params['redirect']); |
95 | | - $count = $this->runQuery($data, $resultPageSet); |
| 101 | + $count = $this->runQuery($resultPageSet); |
96 | 102 | if($count < $params['limit']) |
97 | 103 | { |
98 | 104 | /* We got too few pages, we probably picked a high value |
— | — | @@ -99,12 +105,11 @@ |
100 | 106 | * also the comment in Title::getRandomTitle() |
101 | 107 | */ |
102 | 108 | $this->prepareQuery(0, $params['limit'] - $count, $params['namespace'], $resultPageSet, $params['redirect']); |
103 | | - $this->runQuery($data, $resultPageSet); |
| 109 | + $this->runQuery($resultPageSet); |
104 | 110 | } |
105 | 111 | |
106 | 112 | if(is_null($resultPageSet)) { |
107 | | - $result->setIndexedTagName($data, 'page'); |
108 | | - $result->addValue('query', $this->getModuleName(), $data); |
| 113 | + $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'page'); |
109 | 114 | } |
110 | 115 | } |
111 | 116 | |
— | — | @@ -157,4 +162,4 @@ |
158 | 163 | public function getVersion() { |
159 | 164 | return __CLASS__ . ': $Id: ApiQueryRandom.php overlordq$'; |
160 | 165 | } |
161 | | -} |
| 166 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQuerySiteinfo.php |
— | — | @@ -41,50 +41,60 @@ |
42 | 42 | |
43 | 43 | public function execute() { |
44 | 44 | $params = $this->extractRequestParams(); |
| 45 | + $done = array(); |
45 | 46 | foreach( $params['prop'] as $p ) |
46 | 47 | { |
47 | 48 | switch ( $p ) |
48 | 49 | { |
49 | 50 | case 'general': |
50 | | - $this->appendGeneralInfo( $p ); |
| 51 | + $fit = $this->appendGeneralInfo( $p ); |
51 | 52 | break; |
52 | 53 | case 'namespaces': |
53 | | - $this->appendNamespaces( $p ); |
| 54 | + $fit = $this->appendNamespaces( $p ); |
54 | 55 | break; |
55 | 56 | case 'namespacealiases': |
56 | | - $this->appendNamespaceAliases( $p ); |
| 57 | + $fit = $this->appendNamespaceAliases( $p ); |
57 | 58 | break; |
58 | 59 | case 'specialpagealiases': |
59 | | - $this->appendSpecialPageAliases( $p ); |
| 60 | + $fit = $this->appendSpecialPageAliases( $p ); |
60 | 61 | break; |
61 | 62 | case 'magicwords': |
62 | | - $this->appendMagicWords( $p ); |
| 63 | + $fit = $this->appendMagicWords( $p ); |
63 | 64 | break; |
64 | 65 | case 'interwikimap': |
65 | 66 | $filteriw = isset( $params['filteriw'] ) ? $params['filteriw'] : false; |
66 | | - $this->appendInterwikiMap( $p, $filteriw ); |
| 67 | + $fit = $this->appendInterwikiMap( $p, $filteriw ); |
67 | 68 | break; |
68 | 69 | case 'dbrepllag': |
69 | | - $this->appendDbReplLagInfo( $p, $params['showalldb'] ); |
| 70 | + $fit = $this->appendDbReplLagInfo( $p, $params['showalldb'] ); |
70 | 71 | break; |
71 | 72 | case 'statistics': |
72 | | - $this->appendStatistics( $p ); |
| 73 | + $fit = $this->appendStatistics( $p ); |
73 | 74 | break; |
74 | 75 | case 'usergroups': |
75 | | - $this->appendUserGroups( $p ); |
| 76 | + $fit = $this->appendUserGroups( $p ); |
76 | 77 | break; |
77 | 78 | case 'extensions': |
78 | | - $this->appendExtensions( $p ); |
| 79 | + $fit = $this->appendExtensions( $p ); |
79 | 80 | break; |
80 | 81 | case 'fileextensions': |
81 | | - $this->appendFileExtensions( $p ); |
| 82 | + $fit = $this->appendFileExtensions( $p ); |
82 | 83 | break; |
83 | 84 | case 'rightsinfo': |
84 | | - $this->appendRightsInfo( $p ); |
| 85 | + $fit = $this->appendRightsInfo( $p ); |
85 | 86 | break; |
86 | 87 | default : |
87 | 88 | ApiBase :: dieDebug( __METHOD__, "Unknown prop=$p" ); |
88 | 89 | } |
| 90 | + if(!$fit) |
| 91 | + { |
| 92 | + # Abuse siprop as a query-continue parameter |
| 93 | + # and set it to all unprocessed props |
| 94 | + $this->setContinueEnumParameter('prop', implode('|', |
| 95 | + array_diff($params['prop'], $done))); |
| 96 | + break; |
| 97 | + } |
| 98 | + $done[] = $p; |
89 | 99 | } |
90 | 100 | } |
91 | 101 | |
— | — | @@ -129,7 +139,7 @@ |
130 | 140 | $data['timezone'] = $tz; |
131 | 141 | $data['timeoffset'] = $offset; |
132 | 142 | |
133 | | - $this->getResult()->addValue( 'query', $property, $data ); |
| 143 | + return $this->getResult()->addValue( 'query', $property, $data ); |
134 | 144 | } |
135 | 145 | |
136 | 146 | protected function appendNamespaces( $property ) { |
— | — | @@ -151,7 +161,7 @@ |
152 | 162 | } |
153 | 163 | |
154 | 164 | $this->getResult()->setIndexedTagName( $data, 'ns' ); |
155 | | - $this->getResult()->addValue( 'query', $property, $data ); |
| 165 | + return $this->getResult()->addValue( 'query', $property, $data ); |
156 | 166 | } |
157 | 167 | |
158 | 168 | protected function appendNamespaceAliases( $property ) { |
— | — | @@ -168,7 +178,7 @@ |
169 | 179 | } |
170 | 180 | |
171 | 181 | $this->getResult()->setIndexedTagName( $data, 'ns' ); |
172 | | - $this->getResult()->addValue( 'query', $property, $data ); |
| 182 | + return $this->getResult()->addValue( 'query', $property, $data ); |
173 | 183 | } |
174 | 184 | |
175 | 185 | protected function appendSpecialPageAliases( $property ) { |
— | — | @@ -181,7 +191,7 @@ |
182 | 192 | $data[] = $arr; |
183 | 193 | } |
184 | 194 | $this->getResult()->setIndexedTagName( $data, 'specialpage' ); |
185 | | - $this->getResult()->addValue( 'query', $property, $data ); |
| 195 | + return $this->getResult()->addValue( 'query', $property, $data ); |
186 | 196 | } |
187 | 197 | |
188 | 198 | protected function appendMagicWords( $property ) { |
— | — | @@ -197,7 +207,7 @@ |
198 | 208 | $data[] = $arr; |
199 | 209 | } |
200 | 210 | $this->getResult()->setIndexedTagName($data, 'magicword'); |
201 | | - $this->getResult()->addValue('query', $property, $data); |
| 211 | + return $this->getResult()->addValue( 'query', $property, $data ); |
202 | 212 | } |
203 | 213 | |
204 | 214 | protected function appendInterwikiMap( $property, $filter ) { |
— | — | @@ -235,7 +245,7 @@ |
236 | 246 | $db->freeResult( $res ); |
237 | 247 | |
238 | 248 | $this->getResult()->setIndexedTagName( $data, 'iw' ); |
239 | | - $this->getResult()->addValue( 'query', $property, $data ); |
| 249 | + return $this->getResult()->addValue( 'query', $property, $data ); |
240 | 250 | } |
241 | 251 | |
242 | 252 | protected function appendDbReplLagInfo( $property, $includeAll ) { |
— | — | @@ -263,7 +273,7 @@ |
264 | 274 | |
265 | 275 | $result = $this->getResult(); |
266 | 276 | $result->setIndexedTagName( $data, 'db' ); |
267 | | - $result->addValue( 'query', $property, $data ); |
| 277 | + return $this->getResult()->addValue( 'query', $property, $data ); |
268 | 278 | } |
269 | 279 | |
270 | 280 | protected function appendStatistics( $property ) { |
— | — | @@ -277,7 +287,7 @@ |
278 | 288 | $data['activeusers'] = intval( SiteStats::activeUsers() ); |
279 | 289 | $data['admins'] = intval( SiteStats::numberingroup('sysop') ); |
280 | 290 | $data['jobs'] = intval( SiteStats::jobs() ); |
281 | | - $this->getResult()->addValue( 'query', $property, $data ); |
| 291 | + return $this->getResult()->addValue( 'query', $property, $data ); |
282 | 292 | } |
283 | 293 | |
284 | 294 | protected function appendUserGroups( $property ) { |
— | — | @@ -290,7 +300,7 @@ |
291 | 301 | } |
292 | 302 | |
293 | 303 | $this->getResult()->setIndexedTagName( $data, 'group' ); |
294 | | - $this->getResult()->addValue( 'query', $property, $data ); |
| 304 | + return $this->getResult()->addValue( 'query', $property, $data ); |
295 | 305 | } |
296 | 306 | |
297 | 307 | protected function appendFileExtensions( $property ) { |
— | — | @@ -301,7 +311,7 @@ |
302 | 312 | $data[] = array( 'ext' => $ext ); |
303 | 313 | } |
304 | 314 | $this->getResult()->setIndexedTagName( $data, 'fe' ); |
305 | | - $this->getResult()->addValue( 'query', $property, $data ); |
| 315 | + return $this->getResult()->addValue( 'query', $property, $data ); |
306 | 316 | } |
307 | 317 | |
308 | 318 | protected function appendExtensions( $property ) { |
— | — | @@ -334,7 +344,7 @@ |
335 | 345 | } |
336 | 346 | |
337 | 347 | $this->getResult()->setIndexedTagName( $data, 'ext' ); |
338 | | - $this->getResult()->addValue( 'query', $property, $data ); |
| 348 | + return $this->getResult()->addValue( 'query', $property, $data ); |
339 | 349 | } |
340 | 350 | |
341 | 351 | |
— | — | @@ -352,7 +362,7 @@ |
353 | 363 | 'text' => $text ? $text : '' |
354 | 364 | ); |
355 | 365 | |
356 | | - $this->getResult()->addValue( 'query', $property, $data ); |
| 366 | + return $this->getResult()->addValue( 'query', $property, $data ); |
357 | 367 | } |
358 | 368 | |
359 | 369 | |
— | — | @@ -423,4 +433,4 @@ |
424 | 434 | public function getVersion() { |
425 | 435 | return __CLASS__ . ': $Id$'; |
426 | 436 | } |
427 | | -} |
| 437 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQueryExtLinksUsage.php |
— | — | @@ -110,7 +110,7 @@ |
111 | 111 | |
112 | 112 | $res = $this->select(__METHOD__); |
113 | 113 | |
114 | | - $data = array (); |
| 114 | + $result = $this->getResult(); |
115 | 115 | $count = 0; |
116 | 116 | while ($row = $db->fetchObject($res)) { |
117 | 117 | if (++ $count > $limit) { |
— | — | @@ -130,7 +130,12 @@ |
131 | 131 | } |
132 | 132 | if ($fld_url) |
133 | 133 | $vals['url'] = $row->el_to; |
134 | | - $data[] = $vals; |
| 134 | + $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals); |
| 135 | + if(!$fit) |
| 136 | + { |
| 137 | + $this->setContinueEnumParameter('offset', $offset + $count - 1); |
| 138 | + break; |
| 139 | + } |
135 | 140 | } else { |
136 | 141 | $resultPageSet->processDbRow($row); |
137 | 142 | } |
— | — | @@ -138,9 +143,8 @@ |
139 | 144 | $db->freeResult($res); |
140 | 145 | |
141 | 146 | if (is_null($resultPageSet)) { |
142 | | - $result = $this->getResult(); |
143 | | - $result->setIndexedTagName($data, $this->getModulePrefix()); |
144 | | - $result->addValue('query', $this->getModuleName(), $data); |
| 147 | + $result->setIndexedTagName_internal(array('query', $this->getModuleName()), |
| 148 | + $this->getModulePrefix()); |
145 | 149 | } |
146 | 150 | } |
147 | 151 | |
— | — | @@ -208,4 +212,4 @@ |
209 | 213 | public function getVersion() { |
210 | 214 | return __CLASS__ . ': $Id$'; |
211 | 215 | } |
212 | | -} |
| 216 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQueryAllpages.php |
— | — | @@ -135,8 +135,8 @@ |
136 | 136 | $this->addOption('LIMIT', $limit+1); |
137 | 137 | $res = $this->select(__METHOD__); |
138 | 138 | |
139 | | - $data = array (); |
140 | 139 | $count = 0; |
| 140 | + $result = $this->getResult(); |
141 | 141 | while ($row = $db->fetchObject($res)) { |
142 | 142 | if (++ $count > $limit) { |
143 | 143 | // We've reached the one extra which shows that there are additional pages to be had. Stop here... |
— | — | @@ -147,10 +147,16 @@ |
148 | 148 | |
149 | 149 | if (is_null($resultPageSet)) { |
150 | 150 | $title = Title :: makeTitle($row->page_namespace, $row->page_title); |
151 | | - $data[] = array( |
| 151 | + $vals = array( |
152 | 152 | 'pageid' => intval($row->page_id), |
153 | 153 | 'ns' => intval($title->getNamespace()), |
154 | 154 | 'title' => $title->getPrefixedText()); |
| 155 | + $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals); |
| 156 | + if(!$fit) |
| 157 | + { |
| 158 | + $this->setContinueEnumParameter('from', $this->keyToTitle($row->page_title)); |
| 159 | + break; |
| 160 | + } |
155 | 161 | } else { |
156 | 162 | $resultPageSet->processDbRow($row); |
157 | 163 | } |
— | — | @@ -158,9 +164,7 @@ |
159 | 165 | $db->freeResult($res); |
160 | 166 | |
161 | 167 | if (is_null($resultPageSet)) { |
162 | | - $result = $this->getResult(); |
163 | | - $result->setIndexedTagName($data, 'p'); |
164 | | - $result->addValue('query', $this->getModuleName(), $data); |
| 168 | + $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'p'); |
165 | 169 | } |
166 | 170 | } |
167 | 171 | |
— | — | @@ -266,4 +270,4 @@ |
267 | 271 | public function getVersion() { |
268 | 272 | return __CLASS__ . ': $Id$'; |
269 | 273 | } |
270 | | -} |
| 274 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQueryBacklinks.php |
— | — | @@ -38,7 +38,9 @@ |
39 | 39 | */ |
40 | 40 | class ApiQueryBacklinks extends ApiQueryGeneratorBase { |
41 | 41 | |
42 | | - private $params, $rootTitle, $contRedirs, $contLevel, $contTitle, $contID, $redirID; |
| 42 | + private $params, $rootTitle, $contRedirs, $contLevel, $contTitle, $contID, $redirID, $redirect; |
| 43 | + private $bl_ns, $bl_from, $bl_table, $bl_code, $bl_title, $bl_sort, $bl_fields, $hasNS; |
| 44 | + private $pageMap, $resultArr; |
43 | 45 | |
44 | 46 | // output element name, database column field prefix, database table |
45 | 47 | private $backlinksSettings = array ( |
— | — | @@ -61,6 +63,7 @@ |
62 | 64 | |
63 | 65 | public function __construct($query, $moduleName) { |
64 | 66 | extract($this->backlinksSettings[$moduleName]); |
| 67 | + $this->resultArr = array(); |
65 | 68 | |
66 | 69 | parent :: __construct($query, $moduleName, $code); |
67 | 70 | $this->bl_ns = $prefix . '_namespace'; |
— | — | @@ -188,7 +191,7 @@ |
189 | 192 | $res = $this->select(__METHOD__.'::firstQuery'); |
190 | 193 | |
191 | 194 | $count = 0; |
192 | | - $this->data = array (); |
| 195 | + $this->pageMap = array(); // Maps ns and title to pageid |
193 | 196 | $this->continueStr = null; |
194 | 197 | $this->redirTitles = array(); |
195 | 198 | while ($row = $db->fetchObject($res)) { |
— | — | @@ -223,10 +226,10 @@ |
224 | 227 | // We've reached the one extra which shows that there are additional pages to be had. Stop here... |
225 | 228 | // We need to keep the parent page of this redir in |
226 | 229 | if($this->hasNS) |
227 | | - $contTitle = Title::makeTitle($row->{$this->bl_ns}, $row->{$this->bl_title}); |
| 230 | + $parentID = $this->pageMap[$row->{$this->bl_ns}][$row->{$this->bl_title}]; |
228 | 231 | else |
229 | | - $contTitle = Title::makeTitle(NS_FILE, $row->{$this->bl_title}); |
230 | | - $this->continueStr = $this->getContinueRedirStr($contTitle->getArticleID(), $row->page_id); |
| 232 | + $parentID = $this->pageMap[NS_IMAGE][$row->{$this->bl_title}]; |
| 233 | + $this->continueStr = $this->getContinueRedirStr($parentID, $row->page_id); |
231 | 234 | break; |
232 | 235 | } |
233 | 236 | |
— | — | @@ -237,30 +240,67 @@ |
238 | 241 | } |
239 | 242 | $db->freeResult($res); |
240 | 243 | } |
| 244 | + // Try to add the result data in one go and pray that it fits |
| 245 | + $fit = $this->getResult()->addValue('query', $this->getModuleName(), $this->resultArr); |
| 246 | + if(!$fit) |
| 247 | + { |
| 248 | + // It didn't fit. Add elements one by one until the |
| 249 | + // result is full. |
| 250 | + foreach($this->resultArr as $pageID => $arr) |
| 251 | + { |
| 252 | + // Add the basic entry without redirlinks first |
| 253 | + $fit = $this->getResult()->addValue( |
| 254 | + array('query', $this->getModuleName()), |
| 255 | + $pageID, array_diff_key($arr, array('redirlinks' => ''))); |
| 256 | + if(!$fit) |
| 257 | + { |
| 258 | + $this->continueStr = $this->getContinueStr($pageID); |
| 259 | + break; |
| 260 | + } |
| 261 | + |
| 262 | + $hasRedirs = false; |
| 263 | + foreach((array)@$arr['redirlinks'] as $key => $redir) |
| 264 | + { |
| 265 | + $fit = $this->getResult()->addValue( |
| 266 | + array('query', $this->getModuleName(), $pageID, 'redirlinks'), |
| 267 | + $key, $redir); |
| 268 | + if(!$fit) |
| 269 | + { |
| 270 | + $this->continueStr = $this->getContinueRedirStr($pageID, $redir['pageid']); |
| 271 | + break; |
| 272 | + } |
| 273 | + $hasRedirs = true; |
| 274 | + } |
| 275 | + if($hasRedirs) |
| 276 | + $this->getResult()->setIndexedTagName_internal( |
| 277 | + array('query', $this->getModuleName(), $pageID, 'redirlinks'), |
| 278 | + $this->bl_code); |
| 279 | + if(!$fit) |
| 280 | + break; |
| 281 | + } |
| 282 | + } |
241 | 283 | if(!is_null($this->continueStr)) |
242 | 284 | $this->setContinueEnumParameter('continue', $this->continueStr); |
243 | 285 | |
244 | 286 | if (is_null($resultPageSet)) { |
245 | | - $resultData = array(); |
246 | | - foreach($this->data as $ns => $a) |
247 | | - foreach($a as $title => $arr) |
248 | | - $resultData[] = $arr; |
249 | | - $result = $this->getResult(); |
250 | | - $result->setIndexedTagName($resultData, $this->bl_code); |
251 | | - $result->addValue('query', $this->getModuleName(), $resultData); |
| 287 | + $this->getResult()->setIndexedTagName_internal( |
| 288 | + array('query', $this->getModuleName()), |
| 289 | + $this->bl_code); |
252 | 290 | } |
253 | 291 | } |
254 | 292 | |
255 | 293 | private function extractRowInfo($row) { |
256 | | - if(!isset($this->data[$row->page_namespace][$row->page_title])) { |
257 | | - $this->data[$row->page_namespace][$row->page_title]['pageid'] = $row->page_id; |
258 | | - ApiQueryBase::addTitleInfo($this->data[$row->page_namespace][$row->page_title], Title::makeTitle($row->page_namespace, $row->page_title)); |
259 | | - if($row->page_is_redirect) |
260 | | - { |
261 | | - $this->data[$row->page_namespace][$row->page_title]['redirect'] = ''; |
262 | | - $this->redirTitles[] = Title::makeTitle($row->page_namespace, $row->page_title); |
263 | | - } |
| 294 | + $this->pageMap[$row->page_namespace][$row->page_title] = $row->page_id; |
| 295 | + $t = Title::makeTitle($row->page_namespace, $row->page_title); |
| 296 | + $a = array('pageid' => $row->page_id); |
| 297 | + ApiQueryBase::addTitleInfo($a, $t); |
| 298 | + if($row->page_is_redirect) |
| 299 | + { |
| 300 | + $a['redirect'] = ''; |
| 301 | + $this->redirTitles[] = $t; |
264 | 302 | } |
| 303 | + // Put all the results in an array first |
| 304 | + $this->resultArr[$a['pageid']] = $a; |
265 | 305 | } |
266 | 306 | |
267 | 307 | private function extractRedirRowInfo($row) |
— | — | @@ -270,8 +310,10 @@ |
271 | 311 | if($row->page_is_redirect) |
272 | 312 | $a['redirect'] = ''; |
273 | 313 | $ns = $this->hasNS ? $row->{$this->bl_ns} : NS_FILE; |
274 | | - $this->data[$ns][$row->{$this->bl_title}]['redirlinks'][] = $a; |
275 | | - $this->getResult()->setIndexedTagName($this->data[$ns][$row->{$this->bl_title}]['redirlinks'], $this->bl_code); |
| 314 | + $parentID = $this->pageMap[$ns][$row->{$this->bl_title}]; |
| 315 | + // Put all the results in an array first |
| 316 | + $this->resultArr[$parentID]['redirlinks'][] = $a; |
| 317 | + $this->getResult()->setIndexedTagName($this->resultArr[$parentID]['redirlinks'], $this->bl_code); |
276 | 318 | } |
277 | 319 | |
278 | 320 | protected function processContinue() { |
Index: trunk/phase3/includes/api/ApiQueryDeletedrevs.php |
— | — | @@ -173,9 +173,9 @@ |
174 | 174 | $this->addWhereRange('ar_timestamp', $params['dir'], $params['start'], $params['end']); |
175 | 175 | } |
176 | 176 | $res = $this->select(__METHOD__); |
177 | | - $pages = array(); |
| 177 | + $pageMap = array(); // Maps ns&title to (fake) pageid |
178 | 178 | $count = 0; |
179 | | - // First populate the $pages array |
| 179 | + $newPageID = 0; |
180 | 180 | while($row = $db->fetchObject($res)) |
181 | 181 | { |
182 | 182 | if(++$count > $limit) |
— | — | @@ -205,32 +205,38 @@ |
206 | 206 | if($fld_content) |
207 | 207 | ApiResult::setContent($rev, Revision::getRevisionText($row)); |
208 | 208 | |
209 | | - $t = Title::makeTitle($row->ar_namespace, $row->ar_title); |
210 | | - if(!isset($pages[$t->getPrefixedText()])) |
| 209 | + if(!isset($pageMap[$row->ar_namespace][$row->ar_title])) |
211 | 210 | { |
212 | | - $pages[$t->getPrefixedText()] = array( |
| 211 | + $pageID = $newPageID++; |
| 212 | + $pageMap[$row->ar_namespace][$row->ar_title] = $pageID; |
| 213 | + $t = Title::makeTitle($row->ar_namespace, $row->ar_title); |
| 214 | + $a = array( |
213 | 215 | 'title' => $t->getPrefixedText(), |
214 | 216 | 'ns' => intval($row->ar_namespace), |
215 | 217 | 'revisions' => array($rev) |
216 | 218 | ); |
| 219 | + $result->setIndexedTagName($a['revisions'], 'rev'); |
217 | 220 | if($fld_token) |
218 | | - $pages[$t->getPrefixedText()]['token'] = $token; |
| 221 | + $a['token'] = $token; |
| 222 | + $fit = $result->addValue(array('query', $this->getModuleName()), $pageID, $a); |
219 | 223 | } |
220 | 224 | else |
221 | | - $pages[$t->getPrefixedText()]['revisions'][] = $rev; |
| 225 | + { |
| 226 | + $pageID = $pageMap[$row->ar_namespace][$row->ar_title]; |
| 227 | + $fit = $result->addValue( |
| 228 | + array('query', $this->getModuleName(), $pageID, 'revisions'), |
| 229 | + null, $rev); |
| 230 | + } |
| 231 | + if(!$fit) |
| 232 | + { |
| 233 | + $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->ar_timestamp)); |
| 234 | + break; |
| 235 | + } |
222 | 236 | } |
223 | 237 | $db->freeResult($res); |
| 238 | + $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'page'); |
| 239 | + } |
224 | 240 | |
225 | | - // We don't want entire pagenames as keys, so let's make this array indexed |
226 | | - foreach($pages as $page) |
227 | | - { |
228 | | - $result->setIndexedTagName($page['revisions'], 'rev'); |
229 | | - $data[] = $page; |
230 | | - } |
231 | | - $result->setIndexedTagName($data, 'page'); |
232 | | - $result->addValue('query', $this->getModuleName(), $data); |
233 | | - } |
234 | | - |
235 | 241 | public function getAllowedParams() { |
236 | 242 | return array ( |
237 | 243 | 'start' => array( |
— | — | @@ -325,4 +331,4 @@ |
326 | 332 | public function getVersion() { |
327 | 333 | return __CLASS__ . ': $Id$'; |
328 | 334 | } |
329 | | -} |
| 335 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQueryBase.php |
— | — | @@ -272,15 +272,37 @@ |
273 | 273 | /** |
274 | 274 | * Add a sub-element under the page element with the given page ID |
275 | 275 | * @param int $pageId Page ID |
276 | | - * @param array $data Data array à la ApiResult |
| 276 | + * @param array $data Data array � la ApiResult |
| 277 | + * @return bool Whether the element fit in the result |
277 | 278 | */ |
278 | 279 | protected function addPageSubItems($pageId, $data) { |
279 | 280 | $result = $this->getResult(); |
280 | 281 | $result->setIndexedTagName($data, $this->getModulePrefix()); |
281 | | - $result->addValue(array ('query', 'pages', intval($pageId)), |
| 282 | + return $result->addValue(array('query', 'pages', intval($pageId)), |
282 | 283 | $this->getModuleName(), |
283 | 284 | $data); |
284 | 285 | } |
| 286 | + |
| 287 | + /** |
| 288 | + * Same as addPageSubItems(), but one element of $data |
| 289 | + * at a time |
| 290 | + * @param int $pageId Page ID |
| 291 | + * @param array $data Data array � la ApiResult |
| 292 | + * @param string $elemname XML element name. If null, getModuleName() is used |
| 293 | + * @return bool Whether the element fit in the result |
| 294 | + */ |
| 295 | + protected function addPageSubItem($pageId, $item, $elemname = null) { |
| 296 | + if(is_null($elemname)) |
| 297 | + $elemname = $this->getModulePrefix(); |
| 298 | + $result = $this->getResult(); |
| 299 | + $fit = $result->addValue(array('query', 'pages', $pageId, |
| 300 | + $this->getModuleName()), null, $item); |
| 301 | + if(!$fit) |
| 302 | + return false; |
| 303 | + $result->setIndexedTagName_internal(array('query', 'pages', $pageId, |
| 304 | + $this->getModuleName()), $elemname); |
| 305 | + return true; |
| 306 | + } |
285 | 307 | |
286 | 308 | /** |
287 | 309 | * Set a query-continue value |
— | — | @@ -288,10 +310,11 @@ |
289 | 311 | * @param $paramValue Parameter value |
290 | 312 | */ |
291 | 313 | protected function setContinueEnumParameter($paramName, $paramValue) { |
292 | | - |
293 | 314 | $paramName = $this->encodeParamName($paramName); |
294 | 315 | $msg = array( $paramName => $paramValue ); |
| 316 | + $this->getResult()->disableSizeCheck(); |
295 | 317 | $this->getResult()->addValue('query-continue', $this->getModuleName(), $msg); |
| 318 | + $this->getResult()->enableSizeCheck(); |
296 | 319 | } |
297 | 320 | |
298 | 321 | /** |
Index: trunk/phase3/includes/api/ApiQueryBlocks.php |
— | — | @@ -169,10 +169,14 @@ |
170 | 170 | if($row->ipb_allow_usertalk) |
171 | 171 | $block['allowusertalk'] = ''; |
172 | 172 | } |
173 | | - $data[] = $block; |
| 173 | + $fit = $result->addValue(array('query', $this->getModuleName()), null, $block); |
| 174 | + if(!$fit) |
| 175 | + { |
| 176 | + $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->ipb_timestamp)); |
| 177 | + break; |
| 178 | + } |
174 | 179 | } |
175 | | - $result->setIndexedTagName($data, 'block'); |
176 | | - $result->addValue('query', $this->getModuleName(), $data); |
| 180 | + $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'block'); |
177 | 181 | } |
178 | 182 | |
179 | 183 | protected function prepareUsername($user) |
— | — | @@ -261,4 +265,4 @@ |
262 | 266 | public function getVersion() { |
263 | 267 | return __CLASS__ . ': $Id$'; |
264 | 268 | } |
265 | | -} |
| 269 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQueryCategoryMembers.php |
— | — | @@ -112,8 +112,6 @@ |
113 | 113 | break; |
114 | 114 | } |
115 | 115 | |
116 | | - $lastSortKey = $row->cl_sortkey; // detect duplicate sortkeys |
117 | | - |
118 | 116 | if (is_null($resultPageSet)) { |
119 | 117 | $vals = array(); |
120 | 118 | if ($fld_ids) |
— | — | @@ -127,16 +125,26 @@ |
128 | 126 | $vals['sortkey'] = $row->cl_sortkey; |
129 | 127 | if ($fld_timestamp) |
130 | 128 | $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->cl_timestamp); |
131 | | - $data[] = $vals; |
| 129 | + $fit = $this->getResult()->addValue(array('query', $this->getModuleName()), |
| 130 | + null, $vals); |
| 131 | + if(!$fit) |
| 132 | + { |
| 133 | + if ($params['sort'] == 'timestamp') |
| 134 | + $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->cl_timestamp)); |
| 135 | + else |
| 136 | + $this->setContinueEnumParameter('continue', $this->getContinueStr($row, $lastSortKey)); |
| 137 | + break; |
| 138 | + } |
132 | 139 | } else { |
133 | 140 | $resultPageSet->processDbRow($row); |
134 | 141 | } |
| 142 | + $lastSortKey = $row->cl_sortkey; // detect duplicate sortkeys |
135 | 143 | } |
136 | 144 | $db->freeResult($res); |
137 | 145 | |
138 | 146 | if (is_null($resultPageSet)) { |
139 | | - $this->getResult()->setIndexedTagName($data, 'cm'); |
140 | | - $this->getResult()->addValue('query', $this->getModuleName(), $data); |
| 147 | + $this->getResult()->setIndexedTagName_internal( |
| 148 | + array('query', $this->getModuleName()), 'cm'); |
141 | 149 | } |
142 | 150 | } |
143 | 151 | |
— | — | @@ -257,4 +265,4 @@ |
258 | 266 | public function getVersion() { |
259 | 267 | return __CLASS__ . ': $Id$'; |
260 | 268 | } |
261 | | -} |
| 269 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiResult.php |
— | — | @@ -47,7 +47,7 @@ |
48 | 48 | */ |
49 | 49 | class ApiResult extends ApiBase { |
50 | 50 | |
51 | | - private $mData, $mIsRawMode; |
| 51 | + private $mData, $mIsRawMode, $mSize, $mCheckingSize; |
52 | 52 | |
53 | 53 | /** |
54 | 54 | * Constructor |
— | — | @@ -55,6 +55,7 @@ |
56 | 56 | public function __construct($main) { |
57 | 57 | parent :: __construct($main, 'result'); |
58 | 58 | $this->mIsRawMode = false; |
| 59 | + $this->mCheckingSize = true; |
59 | 60 | $this->reset(); |
60 | 61 | } |
61 | 62 | |
— | — | @@ -63,6 +64,7 @@ |
64 | 65 | */ |
65 | 66 | public function reset() { |
66 | 67 | $this->mData = array (); |
| 68 | + $this->mSize = 0; |
67 | 69 | } |
68 | 70 | |
69 | 71 | /** |
— | — | @@ -81,13 +83,54 @@ |
82 | 84 | } |
83 | 85 | |
84 | 86 | /** |
85 | | - * Get result's internal data array |
| 87 | + * Get the result's internal data array (read-only) |
86 | 88 | */ |
87 | | - public function & getData() { |
| 89 | + public function getData() { |
88 | 90 | return $this->mData; |
89 | 91 | } |
| 92 | + |
| 93 | + /** |
| 94 | + * Get the 'real' size of a result item. This means the strlen() of the item, |
| 95 | + * or the sum of the strlen()s of the elements if the item is an array. |
| 96 | + * @param mixed $value |
| 97 | + * @return int |
| 98 | + */ |
| 99 | + public static function size($value) { |
| 100 | + $s = 0; |
| 101 | + if(is_array($value)) |
| 102 | + foreach($value as $v) |
| 103 | + $s += self::size($v); |
| 104 | + else if(!is_object($value)) |
| 105 | + // Objects can't always be cast to string |
| 106 | + $s = strlen($value); |
| 107 | + return $s; |
| 108 | + } |
90 | 109 | |
91 | 110 | /** |
| 111 | + * Get the size of the result, i.e. the amount of bytes in it |
| 112 | + * @return int |
| 113 | + */ |
| 114 | + public function getSize() { |
| 115 | + return $this->mSize; |
| 116 | + } |
| 117 | + |
| 118 | + /** |
| 119 | + * Disable size checking in addValue(). Don't use this unless you |
| 120 | + * REALLY know what you're doing. Values added while size checking |
| 121 | + * was disabled will not be counted (ever) |
| 122 | + */ |
| 123 | + public function disableSizeCheck() { |
| 124 | + $this->mCheckingSize = false; |
| 125 | + } |
| 126 | + |
| 127 | + /** |
| 128 | + * Re-enable size checking in addValue() |
| 129 | + */ |
| 130 | + public function enableSizeCheck() { |
| 131 | + $this->mCheckingSize = true; |
| 132 | + } |
| 133 | + |
| 134 | + /** |
92 | 135 | * Add an output value to the array by name. |
93 | 136 | * Verifies that value with the same name has not been added before. |
94 | 137 | */ |
— | — | @@ -157,15 +200,38 @@ |
158 | 201 | } |
159 | 202 | |
160 | 203 | /** |
| 204 | + * Calls setIndexedTagName() on an array already in the result. |
| 205 | + * Don't specify a path to a value that's not in the result, or |
| 206 | + * you'll get nasty errors. |
| 207 | + * @param array $path Path to the array, like addValue()'s path |
| 208 | + * @param string $tag |
| 209 | + */ |
| 210 | + public function setIndexedTagName_internal( $path, $tag ) { |
| 211 | + $data = & $this->mData; |
| 212 | + foreach((array)$path as $p) |
| 213 | + $data = & $data[$p]; |
| 214 | + if(is_null($data)) |
| 215 | + return; |
| 216 | + $this->setIndexedTagName($data, $tag); |
| 217 | + } |
| 218 | + |
| 219 | + /** |
161 | 220 | * Add value to the output data at the given path. |
162 | 221 | * Path is an indexed array, each element specifing the branch at which to add the new value |
163 | 222 | * Setting $path to array('a','b','c') is equivalent to data['a']['b']['c'] = $value |
164 | 223 | * If $name is empty, the $value is added as a next list element data[] = $value |
| 224 | + * @return bool True if $value fits in the result, false if not |
165 | 225 | */ |
166 | 226 | public function addValue($path, $name, $value) { |
| 227 | + global $wgAPIMaxResultSize; |
| 228 | + $data = & $this->mData; |
| 229 | + if( $this->mCheckingSize ) { |
| 230 | + $newsize = $this->mSize + self::size($value); |
| 231 | + if($newsize > $wgAPIMaxResultSize) |
| 232 | + return false; |
| 233 | + $this->mSize = $newsize; |
| 234 | + } |
167 | 235 | |
168 | | - $data = & $this->getData(); |
169 | | - |
170 | 236 | if (!is_null($path)) { |
171 | 237 | if (is_array($path)) { |
172 | 238 | foreach ($path as $p) { |
— | — | @@ -184,9 +250,27 @@ |
185 | 251 | $data[] = $value; // Add list element |
186 | 252 | else |
187 | 253 | ApiResult :: setElement($data, $name, $value); // Add named element |
| 254 | + return true; |
188 | 255 | } |
189 | 256 | |
190 | 257 | /** |
| 258 | + * Unset a value previously added to the result set. |
| 259 | + * Fails silently if the value isn't found. |
| 260 | + * For parameters, see addValue() |
| 261 | + */ |
| 262 | + public function unsetValue($path, $name) { |
| 263 | + $data = & $this->mData; |
| 264 | + if(!is_null($path)) |
| 265 | + foreach((array)$path as $p) { |
| 266 | + if(!isset($data[$p])) |
| 267 | + return; |
| 268 | + $data = & $data[$p]; |
| 269 | + } |
| 270 | + $this->mSize -= self::size($data[$name]); |
| 271 | + unset($data[$name]); |
| 272 | + } |
| 273 | + |
| 274 | + /** |
191 | 275 | * Ensure all values in this result are valid UTF-8. |
192 | 276 | */ |
193 | 277 | public function cleanUpUTF8() |
Index: trunk/phase3/includes/api/ApiQueryCategoryInfo.php |
— | — | @@ -29,7 +29,7 @@ |
30 | 30 | } |
31 | 31 | |
32 | 32 | /** |
33 | | - * This query adds <categories> subelement to all pages with the list of images embedded into those pages. |
| 33 | + * This query adds the <categories> subelement to all pages with the list of categories the page is in |
34 | 34 | * |
35 | 35 | * @ingroup API |
36 | 36 | */ |
— | — | @@ -39,7 +39,8 @@ |
40 | 40 | parent :: __construct($query, $moduleName, 'ci'); |
41 | 41 | } |
42 | 42 | |
43 | | - public function execute() { |
| 43 | + public function execute() { |
| 44 | + $params = $this->extractRequestParams(); |
44 | 45 | $alltitles = $this->getPageSet()->getAllTitlesByNamespace(); |
45 | 46 | if ( empty( $alltitles[NS_CATEGORY] ) ) { |
46 | 47 | return; |
— | — | @@ -65,13 +66,20 @@ |
66 | 67 | 'pp_propname' => 'hiddencat')), |
67 | 68 | )); |
68 | 69 | $this->addFields(array('cat_title', 'cat_pages', 'cat_subcats', 'cat_files', 'pp_propname AS cat_hidden')); |
69 | | - $this->addWhere(array('cat_title' => $cattitles)); |
| 70 | + $this->addWhere(array('cat_title' => $cattitles)); |
| 71 | + if(!is_null($params['continue'])) |
| 72 | + { |
| 73 | + // We need to set a LIMIT in order to be able to set |
| 74 | + // an OFFSET |
| 75 | + $this->addOption('LIMIT', count($titles)); |
| 76 | + $this->addOption('OFFSET', $params['continue']); |
| 77 | + } |
70 | 78 | |
71 | 79 | $db = $this->getDB(); |
72 | 80 | $res = $this->select(__METHOD__); |
73 | 81 | |
74 | | - $data = array(); |
75 | 82 | $catids = array_flip($cattitles); |
| 83 | + $count = (int)@$params['continue']; |
76 | 84 | while($row = $db->fetchObject($res)) |
77 | 85 | { |
78 | 86 | $vals = array(); |
— | — | @@ -81,11 +89,29 @@ |
82 | 90 | $vals['subcats'] = $row->cat_subcats; |
83 | 91 | if($row->cat_hidden) |
84 | 92 | $vals['hidden'] = ''; |
85 | | - $this->addPageSubItems($catids[$row->cat_title], $vals); |
| 93 | + $fit = $this->addPageSubItems($catids[$row->cat_title], $vals); |
| 94 | + if(!$fit) |
| 95 | + { |
| 96 | + $this->setContinueEnumParameter('continue', $count); |
| 97 | + break; |
| 98 | + } |
| 99 | + $count++; |
86 | 100 | } |
87 | 101 | $db->freeResult($res); |
88 | 102 | } |
89 | 103 | |
| 104 | + public function getAllowedParams() { |
| 105 | + return array ( |
| 106 | + 'continue' => null, |
| 107 | + ); |
| 108 | + } |
| 109 | + |
| 110 | + public function getParamDescription() { |
| 111 | + return array ( |
| 112 | + 'continue' => 'When more results are available, use this to continue', |
| 113 | + ); |
| 114 | + } |
| 115 | + |
90 | 116 | public function getDescription() { |
91 | 117 | return 'Returns information about the given categories'; |
92 | 118 | } |
— | — | @@ -97,4 +123,4 @@ |
98 | 124 | public function getVersion() { |
99 | 125 | return __CLASS__ . ': $Id$'; |
100 | 126 | } |
101 | | -} |
| 127 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiFormatBase.php |
— | — | @@ -261,9 +261,13 @@ |
262 | 262 | public static function setResult($result, $feed, $feedItems) { |
263 | 263 | // Store output in the Result data. |
264 | 264 | // This way we can check during execution if any error has occured |
265 | | - $data = & $result->getData(); |
266 | | - $data['_feed'] = $feed; |
267 | | - $data['_feeditems'] = $feedItems; |
| 265 | + // Disable size checking for this because we can't continue |
| 266 | + // cleanly; size checking would cause more problems than it'd |
| 267 | + // solve |
| 268 | + $result->disableSizeCheck(); |
| 269 | + $result->addValue(null, '_feed', $feed); |
| 270 | + $result->addValue(null, '_feeditems', $feedItems); |
| 271 | + $result->enableSizeCheck(); |
268 | 272 | } |
269 | 273 | |
270 | 274 | /** |
— | — | @@ -282,8 +286,8 @@ |
283 | 287 | |
284 | 288 | /** |
285 | 289 | * This class expects the result data to be in a custom format set by self::setResult() |
286 | | - * $result['_feed'] - an instance of one of the $wgFeedClasses classes |
287 | | - * $result['_feeditems'] - an array of FeedItem instances |
| 290 | + * $result['_feed'] - an instance of one of the $wgFeedClasses classes |
| 291 | + * $result['_feeditems'] - an array of FeedItem instances |
288 | 292 | */ |
289 | 293 | public function execute() { |
290 | 294 | $data = $this->getResultData(); |
— | — | @@ -304,4 +308,4 @@ |
305 | 309 | public function getVersion() { |
306 | 310 | return __CLASS__ . ': $Id$'; |
307 | 311 | } |
308 | | -} |
| 312 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQueryAllimages.php |
— | — | @@ -97,7 +97,7 @@ |
98 | 98 | |
99 | 99 | $res = $this->select(__METHOD__); |
100 | 100 | |
101 | | - $data = array (); |
| 101 | + $titles = array(); |
102 | 102 | $count = 0; |
103 | 103 | $result = $this->getResult(); |
104 | 104 | while ($row = $db->fetchObject($res)) { |
— | — | @@ -110,20 +110,23 @@ |
111 | 111 | |
112 | 112 | if (is_null($resultPageSet)) { |
113 | 113 | $file = $repo->newFileFromRow( $row ); |
114 | | - $data[] = array_merge(array('name' => $row->img_name), |
| 114 | + $info = array_merge(array('name' => $row->img_name), |
115 | 115 | ApiQueryImageInfo::getInfo($file, $prop, $result)); |
| 116 | + $fit = $result->addValue(array('query', $this->getModuleName()), null, $info); |
| 117 | + if( !$fit ) { |
| 118 | + $this->setContinueEnumParameter('from', $this->keyToTitle($row->img_name)); |
| 119 | + break; |
| 120 | + } |
116 | 121 | } else { |
117 | | - $data[] = Title::makeTitle(NS_FILE, $row->img_name); |
| 122 | + $titles[] = Title::makeTitle(NS_IMAGE, $row->img_name); |
118 | 123 | } |
119 | 124 | } |
120 | 125 | $db->freeResult($res); |
121 | 126 | |
122 | 127 | if (is_null($resultPageSet)) { |
123 | | - $result = $this->getResult(); |
124 | | - $result->setIndexedTagName($data, 'img'); |
125 | | - $result->addValue('query', $this->getModuleName(), $data); |
| 128 | + $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'img'); |
126 | 129 | } else { |
127 | | - $resultPageSet->populateFromTitles( $data ); |
| 130 | + $resultPageSet->populateFromTitles($titles); |
128 | 131 | } |
129 | 132 | } |
130 | 133 | |
Index: trunk/phase3/includes/api/ApiQueryAllmessages.php |
— | — | @@ -75,6 +75,9 @@ |
76 | 76 | //Get all requested messages |
77 | 77 | $messages = array(); |
78 | 78 | foreach( $messages_target as $message ) { |
| 79 | + if(!is_null($params['from'])) |
| 80 | + if($message < $params['from']) |
| 81 | + continue; |
79 | 82 | $messages[$message] = wfMsg( $message ); |
80 | 83 | } |
81 | 84 | |
— | — | @@ -89,10 +92,14 @@ |
90 | 93 | } else { |
91 | 94 | $result->setContent( $message, $value ); |
92 | 95 | } |
93 | | - $messages_out[] = $message; |
| 96 | + $fit = $result->addValue(array('query', $this->getModuleName()), null, $message); |
| 97 | + if(!$fit) |
| 98 | + { |
| 99 | + $this->setContinueEnumParameter('from', $name); |
| 100 | + break; |
| 101 | + } |
94 | 102 | } |
95 | | - $result->setIndexedTagName( $messages_out, 'message' ); |
96 | | - $result->addValue( 'query', $this->getModuleName(), $messages_out ); |
| 103 | + $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'message'); |
97 | 104 | } |
98 | 105 | |
99 | 106 | public function getAllowedParams() { |
— | — | @@ -102,6 +109,7 @@ |
103 | 110 | ), |
104 | 111 | 'filter' => array(), |
105 | 112 | 'lang' => null, |
| 113 | + 'from' => null, |
106 | 114 | ); |
107 | 115 | } |
108 | 116 | |
— | — | @@ -110,6 +118,7 @@ |
111 | 119 | 'messages' => 'Which messages to output. "*" means all messages', |
112 | 120 | 'filter' => 'Return only messages that contain this string', |
113 | 121 | 'lang' => 'Return messages in this language', |
| 122 | + 'from' => 'Return messages starting at this message', |
114 | 123 | ); |
115 | 124 | } |
116 | 125 | |
— | — | @@ -127,4 +136,4 @@ |
128 | 137 | public function getVersion() { |
129 | 138 | return __CLASS__ . ': $Id$'; |
130 | 139 | } |
131 | | -} |
| 140 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQuerySearch.php |
— | — | @@ -87,7 +87,7 @@ |
88 | 88 | $this->dieUsage("{$what} search is disabled", |
89 | 89 | "search-{$what}-disabled"); |
90 | 90 | |
91 | | - $data = array (); |
| 91 | + $titles = array (); |
92 | 92 | $count = 0; |
93 | 93 | while( $result = $matches->next() ) { |
94 | 94 | if (++ $count > $limit) { |
— | — | @@ -102,20 +102,24 @@ |
103 | 103 | |
104 | 104 | $title = $result->getTitle(); |
105 | 105 | if (is_null($resultPageSet)) { |
106 | | - $data[] = array( |
| 106 | + $vals = array( |
107 | 107 | 'ns' => intval($title->getNamespace()), |
108 | 108 | 'title' => $title->getPrefixedText()); |
| 109 | + $fit = $this->getResult()->addValue(array('query', $this->getModuleName()), null, $vals); |
| 110 | + if(!$fit) |
| 111 | + { |
| 112 | + $this->setContinueEnumParameter('offset', $params['offset'] + $count - 1); |
| 113 | + break; |
| 114 | + } |
109 | 115 | } else { |
110 | | - $data[] = $title; |
| 116 | + $titles[] = $title; |
111 | 117 | } |
112 | 118 | } |
113 | 119 | |
114 | 120 | if (is_null($resultPageSet)) { |
115 | | - $result = $this->getResult(); |
116 | | - $result->setIndexedTagName($data, 'p'); |
117 | | - $result->addValue('query', $this->getModuleName(), $data); |
| 121 | + $this->getResult()->setIndexedTagName_internal(array('query', $this->getModuleName()), 'p'); |
118 | 122 | } else { |
119 | | - $resultPageSet->populateFromTitles($data); |
| 123 | + $resultPageSet->populateFromTitles($titles); |
120 | 124 | } |
121 | 125 | } |
122 | 126 | |
— | — | @@ -172,4 +176,4 @@ |
173 | 177 | public function getVersion() { |
174 | 178 | return __CLASS__ . ': $Id$'; |
175 | 179 | } |
176 | | -} |
| 180 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQueryLogEvents.php |
— | — | @@ -125,7 +125,6 @@ |
126 | 126 | $this->addWhere('log_deleted & ' . LogPage::DELETED_USER . ' = 0'); |
127 | 127 | } |
128 | 128 | |
129 | | - $data = array (); |
130 | 129 | $count = 0; |
131 | 130 | $res = $this->select(__METHOD__); |
132 | 131 | while ($row = $db->fetchObject($res)) { |
— | — | @@ -136,13 +135,18 @@ |
137 | 136 | } |
138 | 137 | |
139 | 138 | $vals = $this->extractRowInfo($row); |
140 | | - if($vals) |
141 | | - $data[] = $vals; |
| 139 | + if(!$vals) |
| 140 | + continue; |
| 141 | + $fit = $this->getResult()->addValue(array('query', $this->getModuleName()), null, $vals); |
| 142 | + if(!$fit) |
| 143 | + { |
| 144 | + $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->log_timestamp)); |
| 145 | + break; |
| 146 | + } |
142 | 147 | } |
143 | 148 | $db->freeResult($res); |
144 | 149 | |
145 | | - $this->getResult()->setIndexedTagName($data, 'item'); |
146 | | - $this->getResult()->addValue('query', $this->getModuleName(), $data); |
| 150 | + $this->getResult()->setIndexedTagName_internal(array('query', $this->getModuleName()), 'item'); |
147 | 151 | } |
148 | 152 | |
149 | 153 | public static function addLogParams($result, &$vals, $params, $type, $ts) { |
Index: trunk/phase3/includes/api/ApiQueryWatchlistRaw.php |
— | — | @@ -89,7 +89,6 @@ |
90 | 90 | $res = $this->select(__METHOD__); |
91 | 91 | |
92 | 92 | $db = $this->getDB(); |
93 | | - $data = array(); |
94 | 93 | $titles = array(); |
95 | 94 | $count = 0; |
96 | 95 | while($row = $db->fetchObject($res)) |
— | — | @@ -108,16 +107,19 @@ |
109 | 108 | ApiQueryBase::addTitleInfo($vals, $t); |
110 | 109 | if(isset($prop['changed']) && !is_null($row->wl_notificationtimestamp)) |
111 | 110 | $vals['changed'] = wfTimestamp(TS_ISO_8601, $row->wl_notificationtimestamp); |
112 | | - $data[] = $vals; |
| 111 | + $fit = $this->getResult()->addValue($this->getModuleName(), null, $vals); |
| 112 | + if(!$fit) |
| 113 | + { |
| 114 | + $this->setContinueEnumParameter('continue', $row->wl_namespace . '|' . |
| 115 | + $this->keyToTitle($row->wl_title)); |
| 116 | + break; |
| 117 | + } |
113 | 118 | } |
114 | 119 | else |
115 | 120 | $titles[] = $t; |
116 | 121 | } |
117 | 122 | if(is_null($resultPageSet)) |
118 | | - { |
119 | | - $this->getResult()->setIndexedTagName($data, 'wr'); |
120 | | - $this->getResult()->addValue(null, $this->getModuleName(), $data); |
121 | | - } |
| 123 | + $this->getResult()->setIndexedTagName_internal($this->getModuleName(), 'wr'); |
122 | 124 | else |
123 | 125 | $resultPageSet->populateFromTitles($titles); |
124 | 126 | } |
— | — | @@ -176,4 +178,4 @@ |
177 | 179 | public function getVersion() { |
178 | 180 | return __CLASS__ . ': $Id$'; |
179 | 181 | } |
180 | | -} |
| 182 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQuery.php |
— | — | @@ -255,6 +255,10 @@ |
256 | 256 | $pageSet = $this->getPageSet(); |
257 | 257 | $result = $this->getResult(); |
258 | 258 | |
| 259 | + # We don't check for a full result set here because we can't be adding |
| 260 | + # more than 380K. The maximum revision size is in the megabyte range, |
| 261 | + # and the maximum result size must be even higher than that. |
| 262 | + |
259 | 263 | // Title normalizations |
260 | 264 | $normValues = array (); |
261 | 265 | foreach ($pageSet->getNormalizedTitles() as $rawTitleStr => $titleStr) { |
— | — | @@ -368,6 +372,10 @@ |
369 | 373 | $exporter->closeStream(); |
370 | 374 | $exportxml = ob_get_contents(); |
371 | 375 | ob_end_clean(); |
| 376 | + // Don't check the size of exported stuff |
| 377 | + // It's not continuable, so it would cause more |
| 378 | + // problems than it'd solve |
| 379 | + $result->disableSizeCheck(); |
372 | 380 | if ($this->params['exportnowrap']) { |
373 | 381 | $result->reset(); |
374 | 382 | // Raw formatter will handle this |
— | — | @@ -378,6 +386,7 @@ |
379 | 387 | ApiResult::setContent($r, $exportxml); |
380 | 388 | $result->addValue('query', 'export', $r); |
381 | 389 | } |
| 390 | + $result->enableSizeCheck(); |
382 | 391 | } |
383 | 392 | } |
384 | 393 | } |
— | — | @@ -552,4 +561,4 @@ |
553 | 562 | $vers[] = $psModule->getVersion(); |
554 | 563 | return $vers; |
555 | 564 | } |
556 | | -} |
| 565 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQueryLangLinks.php |
— | — | @@ -71,8 +71,6 @@ |
72 | 72 | $this->addOption('LIMIT', $params['limit'] + 1); |
73 | 73 | $res = $this->select(__METHOD__); |
74 | 74 | |
75 | | - $data = array(); |
76 | | - $lastId = 0; // database has no ID 0 |
77 | 75 | $count = 0; |
78 | 76 | $db = $this->getDB(); |
79 | 77 | while ($row = $db->fetchObject($res)) { |
— | — | @@ -82,23 +80,15 @@ |
83 | 81 | $this->setContinueEnumParameter('continue', "{$row->ll_from}|{$row->ll_lang}"); |
84 | 82 | break; |
85 | 83 | } |
86 | | - if ($lastId != $row->ll_from) { |
87 | | - if($lastId != 0) { |
88 | | - $this->addPageSubItems($lastId, $data); |
89 | | - $data = array(); |
90 | | - } |
91 | | - $lastId = $row->ll_from; |
92 | | - } |
93 | | - |
94 | 84 | $entry = array('lang' => $row->ll_lang); |
95 | 85 | ApiResult :: setContent($entry, $row->ll_title); |
96 | | - $data[] = $entry; |
| 86 | + $fit = $this->addPageSubItem($row->ll_from, $entry); |
| 87 | + if(!$fit) |
| 88 | + { |
| 89 | + $this->setContinueEnumParameter('continue', "{$row->ll_from}|{$row->ll_lang}"); |
| 90 | + break; |
| 91 | + } |
97 | 92 | } |
98 | | - |
99 | | - if($lastId != 0) { |
100 | | - $this->addPageSubItems($lastId, $data); |
101 | | - } |
102 | | - |
103 | 93 | $db->freeResult($res); |
104 | 94 | } |
105 | 95 | |
— | — | @@ -136,4 +126,4 @@ |
137 | 127 | public function getVersion() { |
138 | 128 | return __CLASS__ . ': $Id$'; |
139 | 129 | } |
140 | | -} |
| 130 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiMain.php |
— | — | @@ -361,9 +361,11 @@ |
362 | 362 | } |
363 | 363 | |
364 | 364 | $this->getResult()->reset(); |
| 365 | + $this->getResult()->disableSizeCheck(); |
365 | 366 | // Re-add the id |
366 | | - if($this->mRequest->getCheck('requestid')) |
367 | | - $this->getResult()->addValue(null, 'requestid', $this->mRequest->getVal('requestid')); |
| 367 | + $requestid = $this->getParameter('requestid'); |
| 368 | + if(!is_null($requestid)) |
| 369 | + $this->getResult()->addValue(null, 'requestid', $requestid); |
368 | 370 | $this->getResult()->addValue(null, 'error', $errMessage); |
369 | 371 | |
370 | 372 | return $errMessage['code']; |
— | — | @@ -374,8 +376,9 @@ |
375 | 377 | */ |
376 | 378 | protected function executeAction() { |
377 | 379 | // First add the id to the top element |
378 | | - if($this->mRequest->getCheck('requestid')) |
379 | | - $this->getResult()->addValue(null, 'requestid', $this->mRequest->getVal('requestid')); |
| 380 | + $requestid = $this->getParameter('requestid'); |
| 381 | + if(!is_null($requestid)) |
| 382 | + $this->getResult()->addValue(null, 'requestid', $requestid); |
380 | 383 | |
381 | 384 | $params = $this->extractRequestParams(); |
382 | 385 | |
— | — | @@ -719,4 +722,4 @@ |
720 | 723 | public function __toString() { |
721 | 724 | return "{$this->getCodeString()}: {$this->getMessage()}"; |
722 | 725 | } |
723 | | -} |
| 726 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQueryImageInfo.php |
— | — | @@ -56,49 +56,97 @@ |
57 | 57 | } |
58 | 58 | |
59 | 59 | $pageIds = $this->getPageSet()->getAllTitlesByNamespace(); |
| 60 | + $cnt = 0; |
60 | 61 | if (!empty($pageIds[NS_FILE])) { |
61 | | - |
62 | 62 | $result = $this->getResult(); |
63 | 63 | $images = RepoGroup::singleton()->findFiles( array_keys( $pageIds[NS_FILE] ) ); |
64 | 64 | foreach ( $images as $img ) { |
65 | | - $data = array(); |
66 | | - |
| 65 | + $cnt++; |
| 66 | + if(!is_null($params['continue'])) |
| 67 | + if($cnt < $params['continue']) |
| 68 | + continue; |
| 69 | + $pageId = $pageIds[NS_IMAGE][ $img->getOriginalTitle()->getDBkey() ]; |
| 70 | + |
| 71 | + $fit = $result->addValue( |
| 72 | + array('query', 'pages', intval($pageId)), |
| 73 | + 'imagerepository', $img->getRepoName() |
| 74 | + ); |
| 75 | + if(!$fit) |
| 76 | + { |
| 77 | + if(count($pageIds[NS_IMAGE]) == 1) |
| 78 | + # The user is screwed. imageinfo can't be solely |
| 79 | + # responsible for exceeding the limit in this case, |
| 80 | + # so set a query-continue that just returns the same |
| 81 | + # thing again. When the violating queries have been |
| 82 | + # out-continued, the result will get through |
| 83 | + $this->setContinueEnumParameter('start', |
| 84 | + wfTimestamp(TS_ISO_8601, $img->getTimestamp())); |
| 85 | + else |
| 86 | + $this->setContinueEnumParameter('continue', $cnt); |
| 87 | + break; |
| 88 | + } |
| 89 | + |
67 | 90 | // Get information about the current version first |
68 | 91 | // Check that the current version is within the start-end boundaries |
| 92 | + $gotOne = false; |
69 | 93 | if((is_null($params['start']) || $img->getTimestamp() <= $params['start']) && |
70 | 94 | (is_null($params['end']) || $img->getTimestamp() >= $params['end'])) { |
71 | | - $data[] = self::getInfo( $img, $prop, $result, $scale ); |
| 95 | + $gotOne = true; |
| 96 | + $fit = $this->addPageSubItem($pageId, |
| 97 | + self::getInfo( $img, $prop, $result, $scale)); |
| 98 | + if(!$fit) |
| 99 | + { |
| 100 | + if(count($pageIds[NS_IMAGE]) == 1) |
| 101 | + # See the 'the user is screwed' comment above |
| 102 | + $this->setContinueEnumParameter('start', |
| 103 | + wfTimestamp(TS_ISO_8601, $img->getTimestamp())); |
| 104 | + else |
| 105 | + $this->setContinueEnumParameter('continue', $cnt); |
| 106 | + break; |
| 107 | + } |
72 | 108 | } |
73 | 109 | |
74 | 110 | // Now get the old revisions |
75 | 111 | // Get one more to facilitate query-continue functionality |
76 | | - $count = count($data); |
| 112 | + $count = ($gotOne ? 1 : 0); |
77 | 113 | $oldies = $img->getHistory($params['limit'] - $count + 1, $params['start'], $params['end']); |
78 | 114 | foreach($oldies as $oldie) { |
79 | 115 | if(++$count > $params['limit']) { |
80 | 116 | // We've reached the extra one which shows that there are additional pages to be had. Stop here... |
81 | 117 | // Only set a query-continue if there was only one title |
82 | 118 | if(count($pageIds[NS_FILE]) == 1) |
83 | | - $this->setContinueEnumParameter('start', $oldie->getTimestamp()); |
| 119 | + $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $oldie->getTimestamp())); |
84 | 120 | break; |
85 | 121 | } |
86 | | - $data[] = self::getInfo( $oldie, $prop, $result ); |
| 122 | + $fit = $this->addPageSubItem($pageId, |
| 123 | + self::getInfo($oldie, $prop, $result)); |
| 124 | + if(!$fit) |
| 125 | + { |
| 126 | + if(count($pageIds[NS_IMAGE]) == 1) |
| 127 | + $this->setContinueEnumParameter('start', |
| 128 | + wfTimestamp(TS_ISO_8601, $oldie->getTimestamp())); |
| 129 | + else |
| 130 | + $this->setContinueEnumParameter('continue', $cnt); |
| 131 | + break; |
| 132 | + } |
87 | 133 | } |
88 | | - |
89 | | - $pageId = $pageIds[NS_FILE][ $img->getOriginalTitle()->getDBkey() ]; |
90 | | - $result->addValue( |
91 | | - array( 'query', 'pages', intval( $pageId ) ), |
92 | | - 'imagerepository', $img->getRepoName() |
93 | | - ); |
94 | | - $this->addPageSubItems($pageId, $data); |
| 134 | + if(!$fit) |
| 135 | + break; |
95 | 136 | } |
96 | 137 | |
97 | 138 | $missing = array_diff( array_keys( $pageIds[NS_FILE] ), array_keys( $images ) ); |
98 | | - foreach ( $missing as $title ) |
99 | | - $result->addValue( |
100 | | - array( 'query', 'pages', intval( $pageIds[NS_FILE][$title] ) ), |
| 139 | + foreach ($missing as $title) { |
| 140 | + $cnt++; |
| 141 | + if(!is_null($params['continue'])) |
| 142 | + if($count < $params['continue']) |
| 143 | + continue; |
| 144 | + $fit = $result->addValue( |
| 145 | + array('query', 'pages', intval($pageIds[NS_FILE][$title])), |
101 | 146 | 'imagerepository', '' |
102 | 147 | ); |
| 148 | + if(!$fit) |
| 149 | + $this->setContinueEnumParameter('continue', $cnt); |
| 150 | + } |
103 | 151 | } |
104 | 152 | } |
105 | 153 | |
— | — | @@ -208,7 +256,8 @@ |
209 | 257 | 'urlheight' => array( |
210 | 258 | ApiBase :: PARAM_TYPE => 'integer', |
211 | 259 | ApiBase :: PARAM_DFLT => -1 |
212 | | - ) |
| 260 | + ), |
| 261 | + 'continue' => null, |
213 | 262 | ); |
214 | 263 | } |
215 | 264 | |
— | — | @@ -221,6 +270,7 @@ |
222 | 271 | 'urlwidth' => array('If iiprop=url is set, a URL to an image scaled to this width will be returned.', |
223 | 272 | 'Only the current version of the image can be scaled.'), |
224 | 273 | 'urlheight' => 'Similar to iiurlwidth. Cannot be used without iiurlwidth', |
| 274 | + 'continue' => 'When more results are available, use this to continue', |
225 | 275 | ); |
226 | 276 | } |
227 | 277 | |
Index: trunk/phase3/includes/api/ApiQueryWatchlist.php |
— | — | @@ -168,7 +168,7 @@ |
169 | 169 | |
170 | 170 | $this->addOption('LIMIT', $params['limit'] +1); |
171 | 171 | |
172 | | - $data = array (); |
| 172 | + $ids = array (); |
173 | 173 | $count = 0; |
174 | 174 | $res = $this->select(__METHOD__); |
175 | 175 | |
— | — | @@ -182,13 +182,18 @@ |
183 | 183 | |
184 | 184 | if (is_null($resultPageSet)) { |
185 | 185 | $vals = $this->extractRowInfo($row); |
186 | | - if ($vals) |
187 | | - $data[] = $vals; |
| 186 | + $fit = $this->getResult()->addValue(array('query', $this->getModuleName()), null, $vals); |
| 187 | + if(!$fit) |
| 188 | + { |
| 189 | + $this->setContinueEnumParameter('start', |
| 190 | + wfTimestamp(TS_ISO_8601, $row->rc_timestamp)); |
| 191 | + break; |
| 192 | + } |
188 | 193 | } else { |
189 | 194 | if ($params['allrev']) { |
190 | | - $data[] = intval($row->rc_this_oldid); |
| 195 | + $ids[] = intval($row->rc_this_oldid); |
191 | 196 | } else { |
192 | | - $data[] = intval($row->rc_cur_id); |
| 197 | + $ids[] = intval($row->rc_cur_id); |
193 | 198 | } |
194 | 199 | } |
195 | 200 | } |
— | — | @@ -196,13 +201,12 @@ |
197 | 202 | $db->freeResult($res); |
198 | 203 | |
199 | 204 | if (is_null($resultPageSet)) { |
200 | | - $this->getResult()->setIndexedTagName($data, 'item'); |
201 | | - $this->getResult()->addValue('query', $this->getModuleName(), $data); |
| 205 | + $this->getResult()->setIndexedTagName_internal(array('query', $this->getModuleName()), 'item'); |
202 | 206 | } |
203 | 207 | elseif ($params['allrev']) { |
204 | | - $resultPageSet->populateFromRevisionIDs($data); |
| 208 | + $resultPageSet->populateFromRevisionIDs($ids); |
205 | 209 | } else { |
206 | | - $resultPageSet->populateFromPageIDs($data); |
| 210 | + $resultPageSet->populateFromPageIDs($ids); |
207 | 211 | } |
208 | 212 | } |
209 | 213 | |
— | — | @@ -340,4 +344,4 @@ |
341 | 345 | public function getVersion() { |
342 | 346 | return __CLASS__ . ': $Id$'; |
343 | 347 | } |
344 | | -} |
| 348 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQueryRevisions.php |
— | — | @@ -231,6 +231,8 @@ |
232 | 232 | ApiBase :: dieDebug(__METHOD__, 'param validation?'); |
233 | 233 | |
234 | 234 | $this->addOption('LIMIT', $limit +1); |
| 235 | + if(!is_null($continue)) |
| 236 | + $this->addOption('OFFSET', $continue); |
235 | 237 | |
236 | 238 | $data = array (); |
237 | 239 | $count = 0; |
— | — | @@ -246,29 +248,19 @@ |
247 | 249 | $this->setContinueEnumParameter('startid', intval($row->rev_id)); |
248 | 250 | break; |
249 | 251 | } |
250 | | - |
251 | 252 | $revision = new Revision( $row ); |
252 | | - $this->getResult()->addValue( |
253 | | - array ( |
254 | | - 'query', |
255 | | - 'pages', |
256 | | - $revision->getPage(), |
257 | | - 'revisions'), |
258 | | - null, |
259 | | - $this->extractRowInfo( $revision )); |
260 | | - } |
261 | | - $db->freeResult($res); |
262 | | - |
263 | | - // Ensure that all revisions are shown as '<rev>' elements |
264 | | - $result = $this->getResult(); |
265 | | - if ($result->getIsRawMode()) { |
266 | | - $data =& $result->getData(); |
267 | | - foreach ($data['query']['pages'] as & $page) { |
268 | | - if (is_array($page) && array_key_exists('revisions', $page)) { |
269 | | - $result->setIndexedTagName($page['revisions'], 'rev'); |
270 | | - } |
| 253 | + // |
| 254 | + $fit = $this->addPageSubItem($revision->getPage(), $this->extractRowInfo($revision), 'rev'); |
| 255 | + if(!$fit) |
| 256 | + { |
| 257 | + if($enumRevMode) |
| 258 | + $this->setContinueEnumParameter('startid', intval($row->rev_id)); |
| 259 | + else |
| 260 | + $this->setContinueEnumParameter('continue', $continue + $count - 1); |
| 261 | + break; |
271 | 262 | } |
272 | 263 | } |
| 264 | + $db->freeResult($res); |
273 | 265 | } |
274 | 266 | |
275 | 267 | private function extractRowInfo( $revision ) { |
— | — | @@ -412,6 +404,7 @@ |
413 | 405 | ApiBase :: PARAM_TYPE => array_keys($this->getTokenFunctions()), |
414 | 406 | ApiBase :: PARAM_ISMULTI => true |
415 | 407 | ), |
| 408 | + 'continue' => null, |
416 | 409 | ); |
417 | 410 | } |
418 | 411 | |
— | — | @@ -430,6 +423,7 @@ |
431 | 424 | 'generatexml' => 'generate XML parse tree for revision content', |
432 | 425 | 'section' => 'only retrieve the content of this section', |
433 | 426 | 'token' => 'Which tokens to obtain for each revision', |
| 427 | + 'continue' => 'When more results are available, use this to continue', |
434 | 428 | ); |
435 | 429 | } |
436 | 430 | |
Index: trunk/phase3/includes/api/ApiQueryExternalLinks.php |
— | — | @@ -61,8 +61,6 @@ |
62 | 62 | $db = $this->getDB(); |
63 | 63 | $res = $this->select(__METHOD__); |
64 | 64 | |
65 | | - $data = array(); |
66 | | - $lastId = 0; // database has no ID 0 |
67 | 65 | $count = 0; |
68 | 66 | while ($row = $db->fetchObject($res)) { |
69 | 67 | if (++$count > $params['limit']) { |
— | — | @@ -71,23 +69,15 @@ |
72 | 70 | $this->setContinueEnumParameter('offset', @$params['offset'] + $params['limit']); |
73 | 71 | break; |
74 | 72 | } |
75 | | - if ($lastId != $row->el_from) { |
76 | | - if($lastId != 0) { |
77 | | - $this->addPageSubItems($lastId, $data); |
78 | | - $data = array(); |
79 | | - } |
80 | | - $lastId = $row->el_from; |
81 | | - } |
82 | | - |
83 | 73 | $entry = array(); |
84 | 74 | ApiResult :: setContent($entry, $row->el_to); |
85 | | - $data[] = $entry; |
| 75 | + $fit = $this->addPageSubItem($row->el_from, $entry); |
| 76 | + if(!$fit) |
| 77 | + { |
| 78 | + $this->setContinueEnumParameter('offset', @$params['offset'] + $count - 1); |
| 79 | + break; |
| 80 | + } |
86 | 81 | } |
87 | | - |
88 | | - if($lastId != 0) { |
89 | | - $this->addPageSubItems($lastId, $data); |
90 | | - } |
91 | | - |
92 | 82 | $db->freeResult($res); |
93 | 83 | } |
94 | 84 | |
— | — | @@ -125,4 +115,4 @@ |
126 | 116 | public function getVersion() { |
127 | 117 | return __CLASS__ . ': $Id$'; |
128 | 118 | } |
129 | | -} |
| 119 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiBase.php |
— | — | @@ -147,7 +147,7 @@ |
148 | 148 | /** |
149 | 149 | * Get the result data array |
150 | 150 | */ |
151 | | - public function & getResultData() { |
| 151 | + public function getResultData() { |
152 | 152 | return $this->getResult()->getData(); |
153 | 153 | } |
154 | 154 | |
— | — | @@ -156,20 +156,23 @@ |
157 | 157 | * notice any changes in API. |
158 | 158 | */ |
159 | 159 | public function setWarning($warning) { |
160 | | - # If there is a warning already, append it to the existing one |
161 | | - $data =& $this->getResult()->getData(); |
| 160 | + $data = $this->getResult()->getData(); |
162 | 161 | if(isset($data['warnings'][$this->getModuleName()])) |
163 | 162 | { |
164 | 163 | # Don't add duplicate warnings |
165 | 164 | $warn_regex = preg_quote($warning, '/'); |
166 | 165 | if(preg_match("/{$warn_regex}(\\n|$)/", $data['warnings'][$this->getModuleName()]['*'])) |
167 | 166 | return; |
168 | | - $warning = "{$data['warnings'][$this->getModuleName()]['*']}\n$warning"; |
169 | | - unset($data['warnings'][$this->getModuleName()]); |
| 167 | + $oldwarning = $data['warnings'][$this->getModuleName()]['*']; |
| 168 | + # If there is a warning already, append it to the existing one |
| 169 | + $warning = "$oldwarning\n$warning"; |
| 170 | + $this->getResult()->unsetValue('warnings', $this->getModuleName()); |
170 | 171 | } |
171 | 172 | $msg = array(); |
172 | 173 | ApiResult :: setContent($msg, $warning); |
| 174 | + $this->getResult()->disableSizeCheck(); |
173 | 175 | $this->getResult()->addValue('warnings', $this->getModuleName(), $msg); |
| 176 | + $this->getResult()->enableSizeCheck(); |
174 | 177 | } |
175 | 178 | |
176 | 179 | /** |
— | — | @@ -905,4 +908,4 @@ |
906 | 909 | public static function getBaseVersion() { |
907 | 910 | return __CLASS__ . ': $Id$'; |
908 | 911 | } |
909 | | -} |
| 912 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQueryCategories.php |
— | — | @@ -137,8 +137,6 @@ |
138 | 138 | |
139 | 139 | if (is_null($resultPageSet)) { |
140 | 140 | |
141 | | - $data = array(); |
142 | | - $lastId = 0; // database has no ID 0 |
143 | 141 | $count = 0; |
144 | 142 | while ($row = $db->fetchObject($res)) { |
145 | 143 | if (++$count > $params['limit']) { |
— | — | @@ -148,16 +146,8 @@ |
149 | 147 | '|' . $this->keyToTitle($row->cl_to)); |
150 | 148 | break; |
151 | 149 | } |
152 | | - if ($lastId != $row->cl_from) { |
153 | | - if($lastId != 0) { |
154 | | - $this->addPageSubItems($lastId, $data); |
155 | | - $data = array(); |
156 | | - } |
157 | | - $lastId = $row->cl_from; |
158 | | - } |
159 | 150 | |
160 | 151 | $title = Title :: makeTitle(NS_CATEGORY, $row->cl_to); |
161 | | - |
162 | 152 | $vals = array(); |
163 | 153 | ApiQueryBase :: addTitleInfo($vals, $title); |
164 | 154 | if ($fld_sortkey) |
— | — | @@ -165,13 +155,14 @@ |
166 | 156 | if ($fld_timestamp) |
167 | 157 | $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->cl_timestamp); |
168 | 158 | |
169 | | - $data[] = $vals; |
| 159 | + $fit = $this->addPageSubItem($row->cl_from, $vals); |
| 160 | + if(!$fit) |
| 161 | + { |
| 162 | + $this->setContinueEnumParameter('continue', $row->cl_from . |
| 163 | + '|' . $this->keyToTitle($row->cl_to)); |
| 164 | + break; |
| 165 | + } |
170 | 166 | } |
171 | | - |
172 | | - if($lastId != 0) { |
173 | | - $this->addPageSubItems($lastId, $data); |
174 | | - } |
175 | | - |
176 | 167 | } else { |
177 | 168 | |
178 | 169 | $titles = array(); |
— | — | @@ -248,4 +239,4 @@ |
249 | 240 | public function getVersion() { |
250 | 241 | return __CLASS__ . ': $Id$'; |
251 | 242 | } |
252 | | -} |
| 243 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQueryAllUsers.php |
— | — | @@ -127,7 +127,16 @@ |
128 | 128 | if (!$row || $lastUser !== $row->user_name) { |
129 | 129 | // Save the last pass's user data |
130 | 130 | if (is_array($lastUserData)) |
131 | | - $data[] = $lastUserData; |
| 131 | + { |
| 132 | + $fit = $result->addValue(array('query', $this->getModuleName()), |
| 133 | + null, $lastUserData); |
| 134 | + if(!$fit) |
| 135 | + { |
| 136 | + $this->setContinueEnumParameter('from', |
| 137 | + $this->keyToTitle($lastUserData['name'])); |
| 138 | + break; |
| 139 | + } |
| 140 | + } |
132 | 141 | |
133 | 142 | // No more rows left |
134 | 143 | if (!$row) |
— | — | @@ -169,8 +178,7 @@ |
170 | 179 | |
171 | 180 | $db->freeResult($res); |
172 | 181 | |
173 | | - $result->setIndexedTagName($data, 'u'); |
174 | | - $result->addValue('query', $this->getModuleName(), $data); |
| 182 | + $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'u'); |
175 | 183 | } |
176 | 184 | |
177 | 185 | public function getAllowedParams() { |
— | — | @@ -226,4 +234,4 @@ |
227 | 235 | public function getVersion() { |
228 | 236 | return __CLASS__ . ': $Id$'; |
229 | 237 | } |
230 | | -} |
| 238 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQueryInfo.php |
— | — | @@ -434,7 +434,12 @@ |
435 | 435 | } |
436 | 436 | } |
437 | 437 | |
| 438 | + $count = 0; |
438 | 439 | foreach ( $titles as $pageid => $title ) { |
| 440 | + $count++; |
| 441 | + if(!is_null($params['continue'])) |
| 442 | + if($count < $params['continue']) |
| 443 | + continue; |
439 | 444 | $pageInfo = array ( |
440 | 445 | 'touched' => wfTimestamp(TS_ISO_8601, $pageTouched[$pageid]), |
441 | 446 | 'lastrevid' => intval($pageLatest[$pageid]), |
— | — | @@ -480,18 +485,27 @@ |
481 | 486 | if($title->userCanRead()) |
482 | 487 | $pageInfo['readable'] = ''; |
483 | 488 | |
484 | | - $result->addValue(array ( |
| 489 | + $fit = $result->addValue(array ( |
485 | 490 | 'query', |
486 | 491 | 'pages' |
487 | 492 | ), $pageid, $pageInfo); |
| 493 | + if(!$fit) |
| 494 | + { |
| 495 | + $this->setContinueEnumParameter('continue', $count); |
| 496 | + break; |
| 497 | + } |
488 | 498 | } |
489 | 499 | |
490 | 500 | // Get properties for missing titles if requested |
491 | 501 | if(!is_null($params['token']) || $fld_protection || $fld_talkid || $fld_subjectid || |
492 | 502 | $fld_url || $fld_readable) |
493 | 503 | { |
494 | | - $res = &$result->getData(); |
495 | 504 | foreach($missing as $pageid => $title) { |
| 505 | + $count++; |
| 506 | + if(!is_null($params['continue'])) |
| 507 | + if($count < $params['continue']) |
| 508 | + continue; |
| 509 | + $fit = true; |
496 | 510 | if(!is_null($params['token'])) |
497 | 511 | { |
498 | 512 | $tokenFunctions = $this->getTokenFunctions(); |
— | — | @@ -502,30 +516,45 @@ |
503 | 517 | if($val === false) |
504 | 518 | $this->setWarning("Action '$t' is not allowed for the current user"); |
505 | 519 | else |
506 | | - $res['query']['pages'][$pageid][$t . 'token'] = $val; |
| 520 | + $fit = $result->addValue( |
| 521 | + array('query', 'pages', $pageid), |
| 522 | + $t . 'token', $val); |
507 | 523 | } |
508 | 524 | } |
509 | | - if($fld_protection) |
| 525 | + if($fld_protection && $fit) |
510 | 526 | { |
511 | 527 | // Apparently the XML formatting code doesn't like array(null) |
512 | 528 | // This is painful to fix, so we'll just work around it |
513 | 529 | if(isset($prottitles[$title->getNamespace()][$title->getDBkey()])) |
514 | | - $res['query']['pages'][$pageid]['protection'] = $prottitles[$title->getNamespace()][$title->getDBkey()]; |
| 530 | + $val = $prottitles[$title->getNamespace()][$title->getDBkey()]; |
515 | 531 | else |
516 | | - $res['query']['pages'][$pageid]['protection'] = array(); |
517 | | - $result->setIndexedTagName($res['query']['pages'][$pageid]['protection'], 'pr'); |
| 532 | + $val = array(); |
| 533 | + $result->setIndexedTagName($val, 'pr'); |
| 534 | + $fit = $result->addValue( |
| 535 | + array('query', 'pages', $pageid), |
| 536 | + 'protection', $val); |
518 | 537 | } |
519 | | - if($fld_talkid && isset($talkids[$title->getNamespace()][$title->getDBKey()])) |
520 | | - $res['query']['pages'][$pageid]['talkid'] = $talkids[$title->getNamespace()][$title->getDBKey()]; |
521 | | - if($fld_subjectid && isset($subjectids[$title->getNamespace()][$title->getDBKey()])) |
522 | | - $res['query']['pages'][$pageid]['subjectid'] = $subjectids[$title->getNamespace()][$title->getDBKey()]; |
523 | | - if($fld_url) { |
524 | | - $res['query']['pages'][$pageid]['fullurl'] = $title->getFullURL(); |
525 | | - $res['query']['pages'][$pageid]['editurl'] = $title->getFullURL('action=edit'); |
| 538 | + if($fld_talkid && isset($talkids[$title->getNamespace()][$title->getDbKey()]) && $fit) |
| 539 | + $fit = $result->addValue(array('query', 'pages', $pageid), 'talkid', |
| 540 | + $talkids[$title->getNamespace()][$title->getDbKey()]); |
| 541 | + if($fld_subjectid && isset($subjectids[$title->getNamespace()][$title->getDbKey()]) && $fit) |
| 542 | + $fit = $result->addValue(array('query', 'pages', $pageid), 'subjectid', |
| 543 | + $subjectids[$title->getNamespace()][$title->getDbKey()]); |
| 544 | + if($fld_url && $fit) { |
| 545 | + $fit = $result->addValue(array('query', 'pages', $pageid), 'fullurl', |
| 546 | + $title->getFullURL()); |
| 547 | + if($fit) |
| 548 | + $fit = $result->addValue(array('query', 'pages', $pageid), 'editurl', |
| 549 | + $title->getFullURL('action=edit')); |
526 | 550 | } |
527 | | - if($fld_readable) |
| 551 | + if($fld_readable && $fit) |
528 | 552 | if($title->userCanRead()) |
529 | | - $res['query']['pages'][$pageid]['readable'] = ''; |
| 553 | + $fit = $result->addValue(array('query', 'pages', $pageid), 'readable', ''); |
| 554 | + if(!$fit) |
| 555 | + { |
| 556 | + $this->setContinueEnumParameter('continue', $count); |
| 557 | + break; |
| 558 | + } |
530 | 559 | } |
531 | 560 | } |
532 | 561 | } |
— | — | @@ -546,7 +575,8 @@ |
547 | 576 | ApiBase :: PARAM_DFLT => NULL, |
548 | 577 | ApiBase :: PARAM_ISMULTI => true, |
549 | 578 | ApiBase :: PARAM_TYPE => array_keys($this->getTokenFunctions()) |
550 | | - ) |
| 579 | + ), |
| 580 | + 'continue' => null, |
551 | 581 | ); |
552 | 582 | } |
553 | 583 | |
— | — | @@ -559,6 +589,7 @@ |
560 | 590 | ' subjectid - The page ID of the parent page for each talk page' |
561 | 591 | ), |
562 | 592 | 'token' => 'Request a token to perform a data-modifying action on a page', |
| 593 | + 'continue' => 'When more results are available, use this to continue', |
563 | 594 | ); |
564 | 595 | } |
565 | 596 | |
Index: trunk/phase3/includes/api/ApiQueryDuplicateFiles.php |
— | — | @@ -86,9 +86,7 @@ |
87 | 87 | $res = $this->select(__METHOD__); |
88 | 88 | $db = $this->getDB(); |
89 | 89 | $count = 0; |
90 | | - $data = array(); |
91 | 90 | $titles = array(); |
92 | | - $lastName = ''; |
93 | 91 | while($row = $db->fetchObject($res)) |
94 | 92 | { |
95 | 93 | if(++$count > $params['limit']) |
— | — | @@ -104,27 +102,23 @@ |
105 | 103 | $titles[] = Title::makeTitle(NS_FILE, $row->dup_name); |
106 | 104 | else |
107 | 105 | { |
108 | | - if($row->orig_name != $lastName) |
109 | | - { |
110 | | - if($lastName != '') |
111 | | - { |
112 | | - $this->addPageSubItems($images[$lastName], $data); |
113 | | - $data = array(); |
114 | | - } |
115 | | - $lastName = $row->orig_name; |
116 | | - } |
117 | | - |
118 | | - $data[] = array( |
| 106 | + $r = array( |
119 | 107 | 'name' => $row->dup_name, |
120 | 108 | 'user' => $row->dup_user_text, |
121 | 109 | 'timestamp' => wfTimestamp(TS_ISO_8601, $row->dup_timestamp) |
122 | 110 | ); |
| 111 | + $fit = $this->addPageSubItem($images[$row->orig_name], $r); |
| 112 | + if(!$fit) |
| 113 | + { |
| 114 | + $this->setContinueEnumParameter('continue', |
| 115 | + $this->keyToTitle($row->orig_name) . '|' . |
| 116 | + $this->keyToTitle($row->dup_name)); |
| 117 | + break; |
| 118 | + } |
123 | 119 | } |
124 | 120 | } |
125 | 121 | if(!is_null($resultPageSet)) |
126 | 122 | $resultPageSet->populateFromTitles($titles); |
127 | | - else if($lastName != '') |
128 | | - $this->addPageSubItems($images[$lastName], $data); |
129 | 123 | $db->freeResult($res); |
130 | 124 | } |
131 | 125 | |
Index: trunk/phase3/includes/api/ApiQueryUsers.php |
— | — | @@ -51,71 +51,72 @@ |
52 | 52 | $this->prop = array(); |
53 | 53 | } |
54 | 54 | |
55 | | - if(is_array($params['users'])) { |
56 | | - $r = $this->getOtherUsersInfo($params['users']); |
57 | | - $result->setIndexedTagName($r, 'user'); |
58 | | - } |
59 | | - $result->addValue("query", $this->getModuleName(), $r); |
60 | | - } |
61 | | - |
62 | | - protected function getOtherUsersInfo($users) { |
63 | | - $goodNames = $retval = array(); |
| 55 | + $users = (array)$params['users']; |
| 56 | + $goodNames = $done = array(); |
| 57 | + $result = $this->getResult(); |
64 | 58 | // Canonicalize user names |
65 | 59 | foreach($users as $u) { |
66 | 60 | $n = User::getCanonicalName($u); |
67 | 61 | if($n === false || $n === '') |
68 | | - $retval[] = array('name' => $u, 'invalid' => ''); |
| 62 | + { |
| 63 | + $vals = array('name' => $u, 'invalid' => ''); |
| 64 | + $fit = $result->addValue(array('query', $this->getModuleName()), |
| 65 | + null, $vals); |
| 66 | + if(!$fit) |
| 67 | + { |
| 68 | + $this->setContinueEnumParameter('users', |
| 69 | + implode('|', array_diff($users, $done))); |
| 70 | + $goodNames = array(); |
| 71 | + break; |
| 72 | + } |
| 73 | + $done[] = $u; |
| 74 | + } |
69 | 75 | else |
70 | 76 | $goodNames[] = $n; |
71 | 77 | } |
72 | | - if(!count($goodNames)) |
73 | | - return $retval; |
| 78 | + if(count($goodNames)) |
| 79 | + { |
| 80 | + $db = $this->getDb(); |
| 81 | + $this->addTables('user', 'u1'); |
| 82 | + $this->addFields('u1.user_name'); |
| 83 | + $this->addWhereFld('u1.user_name', $goodNames); |
| 84 | + $this->addFieldsIf('u1.user_editcount', isset($this->prop['editcount'])); |
| 85 | + $this->addFieldsIf('u1.user_registration', isset($this->prop['registration'])); |
74 | 86 | |
75 | | - $db = $this->getDB(); |
76 | | - $this->addTables('user', 'u1'); |
77 | | - $this->addFields('u1.*'); |
78 | | - $this->addWhereFld('u1.user_name', $goodNames); |
| 87 | + if(isset($this->prop['groups'])) { |
| 88 | + $this->addTables('user_groups'); |
| 89 | + $this->addJoinConds(array('user_groups' => array('LEFT JOIN', 'ug_user=u1.user_id'))); |
| 90 | + $this->addFields('ug_group'); |
| 91 | + } |
| 92 | + if(isset($this->prop['blockinfo'])) { |
| 93 | + $this->addTables('ipblocks'); |
| 94 | + $this->addTables('user', 'u2'); |
| 95 | + $u2 = $this->getAliasedName('user', 'u2'); |
| 96 | + $this->addJoinConds(array( |
| 97 | + 'ipblocks' => array('LEFT JOIN', 'ipb_user=u1.user_id'), |
| 98 | + $u2 => array('LEFT JOIN', 'ipb_by=u2.user_id'))); |
| 99 | + $this->addFields(array('ipb_reason', 'u2.user_name blocker_name')); |
| 100 | + } |
79 | 101 | |
80 | | - if(isset($this->prop['groups'])) { |
81 | | - $this->addTables('user_groups'); |
82 | | - $this->addJoinConds(array('user_groups' => array('LEFT JOIN', 'ug_user=u1.user_id'))); |
83 | | - $this->addFields('ug_group'); |
| 102 | + $data = array(); |
| 103 | + $res = $this->select(__METHOD__); |
| 104 | + while(($r = $db->fetchObject($res))) { |
| 105 | + $data[$r->user_name]['name'] = $r->user_name; |
| 106 | + if(isset($this->prop['editcount'])) |
| 107 | + $data[$r->user_name]['editcount'] = $r->user_editcount; |
| 108 | + if(isset($this->prop['registration'])) |
| 109 | + $data[$r->user_name]['registration'] = wfTimestampOrNull(TS_ISO_8601, $r->user_registration); |
| 110 | + if(isset($this->prop['groups'])) |
| 111 | + // This row contains only one group, others will be added from other rows |
| 112 | + if(!is_null($r->ug_group)) |
| 113 | + $data[$r->user_name]['groups'][] = $r->ug_group; |
| 114 | + if(isset($this->prop['blockinfo'])) |
| 115 | + if(!is_null($r->blocker_name)) { |
| 116 | + $data[$r->user_name]['blockedby'] = $r->blocker_name; |
| 117 | + $data[$r->user_name]['blockreason'] = $r->ipb_reason; |
| 118 | + } |
| 119 | + } |
84 | 120 | } |
85 | | - if(isset($this->prop['blockinfo'])) { |
86 | | - $this->addTables('ipblocks'); |
87 | | - $this->addTables('user', 'u2'); |
88 | | - $u2 = $this->getAliasedName('user', 'u2'); |
89 | | - $this->addJoinConds(array( |
90 | | - 'ipblocks' => array('LEFT JOIN', 'ipb_user=u1.user_id'), |
91 | | - $u2 => array('LEFT JOIN', 'ipb_by=u2.user_id'))); |
92 | | - $this->addFields(array('ipb_reason', 'u2.user_name blocker_name')); |
93 | | - } |
94 | | - |
95 | | - $data = array(); |
96 | | - $res = $this->select(__METHOD__); |
97 | | - while(($r = $db->fetchObject($res))) { |
98 | | - $user = User::newFromRow($r); |
99 | | - $name = $user->getName(); |
100 | | - $data[$name]['name'] = $name; |
101 | | - if(isset($this->prop['editcount'])) |
102 | | - // No proper member function in User class for this |
103 | | - $data[$name]['editcount'] = $r->user_editcount; |
104 | | - if(isset($this->prop['registration'])) |
105 | | - // Nor for this one |
106 | | - $data[$name]['registration'] = wfTimestampOrNull(TS_ISO_8601, $r->user_registration); |
107 | | - if(isset($this->prop['groups'])) |
108 | | - // This row contains only one group, others will be added from other rows |
109 | | - if(!is_null($r->ug_group)) |
110 | | - $data[$name]['groups'][] = $r->ug_group; |
111 | | - if(isset($this->prop['blockinfo'])) |
112 | | - if(!is_null($r->blocker_name)) { |
113 | | - $data[$name]['blockedby'] = $r->blocker_name; |
114 | | - $data[$name]['blockreason'] = $r->ipb_reason; |
115 | | - } |
116 | | - if(isset($this->prop['emailable']) && $user->canReceiveEmail()) |
117 | | - $data[$name]['emailable'] = ''; |
118 | | - } |
119 | | - |
120 | 121 | // Second pass: add result data to $retval |
121 | 122 | foreach($goodNames as $u) { |
122 | 123 | if(!isset($data[$u])) |
— | — | @@ -125,8 +126,9 @@ |
126 | 127 | $this->getResult()->setIndexedTagName($data[$u]['groups'], 'g'); |
127 | 128 | $retval[] = $data[$u]; |
128 | 129 | } |
| 130 | + $done[] = $u; |
129 | 131 | } |
130 | | - return $retval; |
| 132 | + return $this->getResult()->setIndexedTagName_internal(array('query', $this->getModuleName()), 'user'); |
131 | 133 | } |
132 | 134 | |
133 | 135 | public function getAllowedParams() { |
Index: trunk/phase3/includes/api/ApiQueryUserContributions.php |
— | — | @@ -83,7 +83,6 @@ |
84 | 84 | $res = $this->select( __METHOD__ ); |
85 | 85 | |
86 | 86 | //Initialise some variables |
87 | | - $data = array (); |
88 | 87 | $count = 0; |
89 | 88 | $limit = $this->params['limit']; |
90 | 89 | |
— | — | @@ -99,16 +98,21 @@ |
100 | 99 | } |
101 | 100 | |
102 | 101 | $vals = $this->extractRowInfo($row); |
103 | | - if ($vals) |
104 | | - $data[] = $vals; |
| 102 | + $fit = $this->getResult()->addValue(array('query', $this->getModuleName()), null, $vals); |
| 103 | + if(!$fit) |
| 104 | + { |
| 105 | + if($this->multiUserMode) |
| 106 | + $this->setContinueEnumParameter('continue', $this->continueStr($row)); |
| 107 | + else |
| 108 | + $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->rev_timestamp)); |
| 109 | + break; |
| 110 | + } |
105 | 111 | } |
106 | 112 | |
107 | 113 | //Free the database record so the connection can get on with other stuff |
108 | 114 | $db->freeResult($res); |
109 | 115 | |
110 | | - //And send the whole shebang out as output. |
111 | | - $this->getResult()->setIndexedTagName($data, 'item'); |
112 | | - $this->getResult()->addValue('query', $this->getModuleName(), $data); |
| 116 | + $this->getResult()->setIndexedTagName_internal(array('query', $this->getModuleName()), 'item'); |
113 | 117 | } |
114 | 118 | |
115 | 119 | /** |
— | — | @@ -358,4 +362,4 @@ |
359 | 363 | public function getVersion() { |
360 | 364 | return __CLASS__ . ': $Id$'; |
361 | 365 | } |
362 | | -} |
| 366 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/api/ApiQueryImages.php |
— | — | @@ -82,9 +82,6 @@ |
83 | 83 | $res = $this->select(__METHOD__); |
84 | 84 | |
85 | 85 | if (is_null($resultPageSet)) { |
86 | | - |
87 | | - $data = array(); |
88 | | - $lastId = 0; // database has no ID 0 |
89 | 86 | $count = 0; |
90 | 87 | while ($row = $db->fetchObject($res)) { |
91 | 88 | if (++$count > $params['limit']) { |
— | — | @@ -94,23 +91,16 @@ |
95 | 92 | '|' . $this->keyToTitle($row->il_to)); |
96 | 93 | break; |
97 | 94 | } |
98 | | - if ($lastId != $row->il_from) { |
99 | | - if($lastId != 0) { |
100 | | - $this->addPageSubItems($lastId, $data); |
101 | | - $data = array(); |
102 | | - } |
103 | | - $lastId = $row->il_from; |
104 | | - } |
105 | | - |
106 | 95 | $vals = array(); |
107 | 96 | ApiQueryBase :: addTitleInfo($vals, Title :: makeTitle(NS_FILE, $row->il_to)); |
108 | | - $data[] = $vals; |
| 97 | + $fit = $this->addPageSubItem($row->il_from, $vals); |
| 98 | + if(!$fit) |
| 99 | + { |
| 100 | + $this->setContinueEnumParameter('continue', $row->il_from . |
| 101 | + '|' . $this->keyToTitle($row->il_to)); |
| 102 | + break; |
| 103 | + } |
109 | 104 | } |
110 | | - |
111 | | - if($lastId != 0) { |
112 | | - $this->addPageSubItems($lastId, $data); |
113 | | - } |
114 | | - |
115 | 105 | } else { |
116 | 106 | |
117 | 107 | $titles = array(); |
— | — | @@ -167,4 +157,4 @@ |
168 | 158 | public function getVersion() { |
169 | 159 | return __CLASS__ . ': $Id$'; |
170 | 160 | } |
171 | | -} |
| 161 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/DefaultSettings.php |
— | — | @@ -3519,6 +3519,12 @@ |
3520 | 3520 | $wgAPIMaxDBRows = 5000; |
3521 | 3521 | |
3522 | 3522 | /** |
| 3523 | + * The maximum size (in bytes) of an API result. |
| 3524 | + * Don't set this lower than $wgMaxArticleSize*1024 |
| 3525 | + */ |
| 3526 | +$wgAPIMaxResultSize = 8388608; |
| 3527 | + |
| 3528 | +/** |
3523 | 3529 | * Parser test suite files to be run by parserTests.php when no specific |
3524 | 3530 | * filename is passed to it. |
3525 | 3531 | * |