Index: trunk/phase3/includes/api/ApiQuery.php |
— | — | @@ -96,45 +96,25 @@ |
97 | 97 | * #5 Execute all requested modules
|
98 | 98 | */
|
99 | 99 | public function execute() {
|
100 | | - $meta = $prop = $list = $generator = $titles = $pageids = $revids = null;
|
| 100 | + $meta = $prop = $list = $generator = $titles = $pageids = null;
|
101 | 101 | $redirects = null;
|
102 | 102 | extract($this->extractRequestParams());
|
103 | 103 |
|
104 | 104 | //
|
105 | 105 | // Create and initialize PageSet
|
106 | 106 | //
|
107 | | - // Only one of the titles/pageids/revids is allowed at the same time
|
108 | 107 | $dataSource = null;
|
109 | | - if (isset ($titles))
|
110 | | - $dataSource = 'titles';
|
111 | | - if (isset ($pageids)) {
|
112 | | - if (isset ($dataSource))
|
113 | | - $this->dieUsage("Cannot use 'pageids' at the same time as '$dataSource'", 'multisource');
|
114 | | - $dataSource = 'pageids';
|
115 | | - }
|
116 | | - if (isset ($revids)) {
|
117 | | - if (isset ($dataSource))
|
118 | | - $this->dieUsage("Cannot use 'revids' at the same time as '$dataSource'", 'multisource');
|
119 | | - $dataSource = 'revids';
|
120 | | - }
|
| 108 | + if (isset ($titles) && isset($pageids))
|
| 109 | + $this->dieUsage("At present you may not use titles= and pageids= at the same time", 'multisource');
|
121 | 110 |
|
122 | 111 | $this->mData = new ApiPageSet($this, $redirects);
|
123 | 112 |
|
124 | | - switch ($dataSource) {
|
125 | | - case 'titles' :
|
126 | | - $this->mData->populateTitles($titles);
|
127 | | - break;
|
128 | | - case 'pageids' :
|
129 | | - $this->mData->populatePageIDs($pageids);
|
130 | | - break;
|
131 | | - case 'titles' :
|
132 | | - $this->mData->populateRevIDs($revids);
|
133 | | - break;
|
134 | | - default :
|
135 | | - // Do nothing - some queries do not need any of the data sources.
|
136 | | - break;
|
137 | | - }
|
| 113 | + if (isset($titles))
|
| 114 | + $this->mData->populateTitles($titles);
|
138 | 115 |
|
| 116 | + if (isset($pageids))
|
| 117 | + $this->mData->populatePageIDs($pageids);
|
| 118 | +
|
139 | 119 | //
|
140 | 120 | // If generator is provided, get a new dataset to work on
|
141 | 121 | //
|
— | — | @@ -159,7 +139,8 @@ |
160 | 140 | foreach ($this->mData->getNormalizedTitles() as $rawTitleStr => $titleStr) {
|
161 | 141 | $this->getResult()->addMessage('query', 'normalized', array (
|
162 | 142 | 'from' => $rawTitleStr,
|
163 | | - 'to' => $titleStr
|
| 143 | + 'to' => $titleStr,
|
| 144 | + '*' => ''
|
164 | 145 | ), 'n');
|
165 | 146 | }
|
166 | 147 |
|
— | — | @@ -168,7 +149,8 @@ |
169 | 150 | foreach ($this->mData->getRedirectTitles() as $titleStrFrom => $titleStrTo) {
|
170 | 151 | $this->getResult()->addMessage('query', 'redirects', array (
|
171 | 152 | 'from' => $titleStrFrom,
|
172 | | - 'to' => $titleStrTo
|
| 153 | + 'to' => $titleStrTo,
|
| 154 | + '*' => ''
|
173 | 155 | ), 'r');
|
174 | 156 | }
|
175 | 157 | }
|
— | — | @@ -224,10 +206,6 @@ |
225 | 207 | // GN_ENUM_TYPE => 'integer',
|
226 | 208 | // GN_ENUM_ISMULTI => true
|
227 | 209 | // ),
|
228 | | - // 'revids' => array (
|
229 | | - // GN_ENUM_TYPE => 'integer',
|
230 | | - // GN_ENUM_ISMULTI => true
|
231 | | - // ),
|
232 | 210 | 'redirects' => false
|
233 | 211 | );
|
234 | 212 | }
|
— | — | @@ -280,7 +258,6 @@ |
281 | 259 | 'generator' => 'Use the output of a list as the input for other prop/list/meta items',
|
282 | 260 | 'titles' => 'A list of titles to work on',
|
283 | 261 | 'pageids' => 'A list of page IDs to work on',
|
284 | | - 'revids' => 'A list of revision IDs to work on',
|
285 | 262 | 'redirects' => 'Automatically resolve redirects'
|
286 | 263 | );
|
287 | 264 | }
|
Index: trunk/phase3/includes/api/ApiQueryRevisions.php |
— | — | @@ -36,7 +36,7 @@ |
37 | 37 | } |
38 | 38 | |
39 | 39 | public function execute() { |
40 | | - $rvlimit = $rvstartid = $rvendid = $rvstart = $rvend = $rvdir = $rvprop = null; |
| 40 | + $rvrevids = $rvlimit = $rvstartid = $rvendid = $rvstart = $rvend = $rvdir = $rvprop = null; |
41 | 41 | extract($this->extractRequestParams()); |
42 | 42 | |
43 | 43 | // |
— | — | @@ -46,17 +46,31 @@ |
47 | 47 | // true when ordered by timestamp from older to newer, false otherwise |
48 | 48 | $dirNewer = ($rvdir === 'newer'); |
49 | 49 | |
50 | | - // If any of those parameters are used, we work with single page only |
51 | | - $singePageMode = ($rvlimit !== 0 || $rvstartid !== 0 || $rvendid !== 0 || $dirNewer || isset ($rvstart) || isset ($rvend)); |
| 50 | + // If any of those parameters are used, we can only work with a single page |
| 51 | + // Enumerating revisions on multiple pages make it extremelly |
| 52 | + // difficult to manage continuations and require additional sql indexes |
| 53 | + $enumRevMode = ($rvlimit !== 0 || $rvstartid !== 0 || $rvendid !== 0 || $dirNewer || isset ($rvstart) || isset ($rvend)); |
52 | 54 | |
53 | 55 | if ($rvstartid !== 0 || $rvendid !== 0) |
54 | 56 | $this->dieUsage('rvstartid/rvendid not implemented', 'notimplemented'); |
55 | 57 | |
56 | 58 | $data = $this->getData(); |
57 | 59 | $pageCount = $data->getPageCount(); |
58 | | - if ($singePageMode && $pageCount > 1) |
59 | | - $this->dieUsage('You have supplied multiple pages, but the specified revisions parameters may only be used with one page.', 'rv_multpages'); |
60 | 60 | |
| 61 | + if (!empty ($rvrevids)) { |
| 62 | + if ($pageCount > 0) |
| 63 | + $this->dieUsage('The rvrevids= parameter may not be used with titles, pageids, and generator options.', 'rv_rvrevids'); |
| 64 | + |
| 65 | + if ($enumRevMode) |
| 66 | + $this->dieUsage('The rvrevids= parameter may not be used with the list options (rvlimit, rvstartid, rvendid, dirNewer, rvstart, rvend).', 'rv_rvrevids'); |
| 67 | + } else { |
| 68 | + if ($pageCount < 1) |
| 69 | + $this->dieUsage('No pages were given. Please use titles, pageids or a generator to provide page(s) to work on.', 'rv_no_pages'); |
| 70 | + |
| 71 | + if ($enumRevMode && $pageCount > 1) |
| 72 | + $this->dieUsage('titles, pageids or a generator was used to supply multiple pages, but the rvlimit, rvstartid, rvendid, dirNewer, rvstart, and rvend parameters may only be used on a single page.', 'rv_multpages'); |
| 73 | + } |
| 74 | + |
61 | 75 | $tables = array ( |
62 | 76 | 'revision' |
63 | 77 | ); |
— | — | @@ -97,6 +111,7 @@ |
98 | 112 | $fields[] = 'old_id'; |
99 | 113 | $fields[] = 'old_text'; |
100 | 114 | $fields[] = 'old_flags'; |
| 115 | + $showContent = true; |
101 | 116 | break; |
102 | 117 | default : |
103 | 118 | $this->dieDebug("unknown rvprop $prop"); |
— | — | @@ -104,25 +119,43 @@ |
105 | 120 | } |
106 | 121 | } |
107 | 122 | |
108 | | - if (isset ($rvstart)) |
109 | | - $conds[] = 'rev_timestamp >= ' . $this->prepareTimestamp($rvstart); |
110 | | - if (isset ($rvend)) |
111 | | - $conds[] = 'rev_timestamp <= ' . $this->prepareTimestamp($rvend); |
| 123 | + $userMax = ($showContent ? 50 : 500); |
| 124 | + $botMax = ($showContent ? 200 : 10000); |
112 | 125 | |
113 | | - if ($singePageMode) { |
| 126 | + if ($enumRevMode) { |
| 127 | + |
| 128 | + if (isset ($rvstart)) |
| 129 | + $conds[] = 'rev_timestamp >= ' . $this->prepareTimestamp($rvstart); |
| 130 | + if (isset ($rvend)) |
| 131 | + $conds[] = 'rev_timestamp <= ' . $this->prepareTimestamp($rvend); |
| 132 | + |
| 133 | + // must manually initialize unset rvlimit |
114 | 134 | if (!isset ($rvlimit)) |
115 | 135 | $rvlimit = 10; |
116 | 136 | |
117 | | - $options['LIMIT'] = $rvlimit + 1; |
118 | 137 | $options['ORDER BY'] = 'rev_timestamp' . ($dirNewer ? '' : ' DESC'); |
119 | | - |
120 | | - // get the first (and only) pageid => title pair |
121 | | - foreach($data->getGoodTitles() as $pageId => $titleObj) { |
122 | | - $conds['rev_page'] = $pageId; |
123 | | - break; |
124 | | - } |
| 138 | + |
| 139 | + $this->validateLimit('rvlimit', $rvlimit, 1, $userMax, $botMax); |
| 140 | + |
| 141 | + // There is only one ID |
| 142 | + $conds['rev_page'] = array_keys($data->getGoodTitles()); |
| 143 | + |
| 144 | + } else { |
| 145 | + // When working in multi-page non-enumeration mode, |
| 146 | + // limit to the latest revision only |
| 147 | + $tables[] = 'page'; |
| 148 | + $conds[] = 'page_id=rev_page'; |
| 149 | + $conds[] = 'page_latest=rev_id'; |
| 150 | + $this->validateLimit('page_count', $pageCount, 1, $userMax, $botMax); |
| 151 | + |
| 152 | + // Get all page IDs |
| 153 | + $conds['page_id'] = array_keys($data->getGoodTitles()); |
| 154 | + |
| 155 | + $rvlimit = $pageCount; // assumption testing -- we should never get more then $pageCount rows. |
125 | 156 | } |
126 | 157 | |
| 158 | + $options['LIMIT'] = $rvlimit +1; |
| 159 | + |
127 | 160 | $db = $this->getDB(); |
128 | 161 | $this->profileDBIn(); |
129 | 162 | $res = $db->select($tables, $fields, $conds, __CLASS__ . '::' . __FUNCTION__, $options); |
— | — | @@ -134,31 +167,32 @@ |
135 | 168 | |
136 | 169 | if (++ $count > $rvlimit) { |
137 | 170 | // We've reached the one extra which shows that there are additional pages to be had. Stop here... |
| 171 | + if (!$enumRevMode) |
| 172 | + $this->dieDebug('Got more rows then expected'); // bug report |
| 173 | + |
138 | 174 | $startStr = 'rvstartid=' . $row->rev_id; |
139 | | - $msg = array ('continue' => $startStr ); |
| 175 | + $msg = array ( |
| 176 | + 'continue' => $startStr |
| 177 | + ); |
140 | 178 | $this->getResult()->addMessage('query-status', 'revisions', $msg); |
141 | 179 | break; |
142 | 180 | } |
143 | 181 | |
144 | | - |
145 | | - $revid = intval($row->rev_id); |
146 | | - $pageid = intval($row->rev_page); |
147 | | - |
148 | 182 | $vals = array ( |
149 | | - 'revid' => $revid, |
| 183 | + 'revid' => intval($row->rev_id), |
150 | 184 | 'oldid' => intval($row->rev_text_id |
151 | 185 | )); |
152 | 186 | |
153 | | - if( $row->rev_minor_edit ) { |
| 187 | + if ($row->rev_minor_edit) { |
154 | 188 | $vals['minor'] = ''; |
155 | 189 | } |
156 | | - |
| 190 | + |
157 | 191 | if ($showTimestamp) |
158 | 192 | $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->rev_timestamp); |
159 | | - |
| 193 | + |
160 | 194 | if ($showUser) { |
161 | 195 | $vals['user'] = $row->rev_user_text; |
162 | | - if( !$row->rev_user ) |
| 196 | + if (!$row->rev_user) |
163 | 197 | $vals['anon'] = ''; |
164 | 198 | } |
165 | 199 | |
— | — | @@ -167,13 +201,13 @@ |
168 | 202 | |
169 | 203 | if ($showContent) { |
170 | 204 | $vals['xml:space'] = 'preserve'; |
171 | | - $vals['*'] = Revision::getRevisionText( $row ); |
| 205 | + $vals['*'] = Revision :: getRevisionText($row); |
172 | 206 | } else { |
173 | | - $vals['*'] = ''; // Force all elements to be attributes |
| 207 | + $vals['*'] = ''; // Force all elements to be attributes |
174 | 208 | } |
175 | 209 | |
176 | | - $data[$pageid]['revisions']['_element'] = 'rv'; |
177 | | - $data[$pageid]['revisions'][$revid] = $vals; |
| 210 | + $data[$row->rev_page]['revisions']['_element'] = 'rv'; |
| 211 | + $data[$row->rev_page]['revisions'][$row->rev_id] = $vals; |
178 | 212 | } |
179 | 213 | $db->freeResult($res); |
180 | 214 | |
— | — | @@ -182,6 +216,10 @@ |
183 | 217 | |
184 | 218 | protected function getAllowedParams() { |
185 | 219 | return array ( |
| 220 | + 'rvrevids' => array ( |
| 221 | + GN_ENUM_ISMULTI => true, |
| 222 | + GN_ENUM_TYPE => 'integer' |
| 223 | + ), |
186 | 224 | 'rvlimit' => array ( |
187 | 225 | GN_ENUM_DFLT => 0, |
188 | 226 | GN_ENUM_TYPE => 'limit', |
Index: trunk/phase3/includes/api/ApiPageSet.php |
— | — | @@ -83,7 +83,7 @@ |
84 | 84 | * Returns the number of unique pages (not revisions) in the set. |
85 | 85 | */ |
86 | 86 | public function getPageCount() { |
87 | | - return count($this->getGoodTitles()); |
| 87 | + return count($this->getGoodTitles()); |
88 | 88 | } |
89 | 89 | |
90 | 90 | /** |
— | — | @@ -176,7 +176,7 @@ |
177 | 177 | 'pl_from' => array_keys($redirectIds |
178 | 178 | )), __CLASS__ . '::' . __FUNCTION__); |
179 | 179 | $this->profileDBOut(); |
180 | | - |
| 180 | + |
181 | 181 | while ($row = $db->fetchObject($res)) { |
182 | 182 | |
183 | 183 | // Bug 7304 workaround |
— | — | @@ -199,9 +199,9 @@ |
200 | 200 | } |
201 | 201 | $db->freeResult($res); |
202 | 202 | } |
203 | | - $this->profileOut(); |
| 203 | + $this->profileOut(); |
204 | 204 | } |
205 | | - |
| 205 | + |
206 | 206 | /** |
207 | 207 | * Given an array of title strings, convert them into Title objects. |
208 | 208 | * This method validates access rights for the title, |
— | — | @@ -237,6 +237,10 @@ |
238 | 238 | return $linkBatch; |
239 | 239 | } |
240 | 240 | |
| 241 | + public function populatePageIDs($pageids) { |
| 242 | + $this->dieUsage(__FUNCTION__ . " is not implemented", 'notimplemented'); |
| 243 | + } |
| 244 | + |
241 | 245 | public function execute() { |
242 | 246 | $this->dieDebug("execute() is not supported on this object"); |
243 | 247 | } |