Index: trunk/phase3/maintenance/tests/ApiTest.php |
— | — | @@ -57,8 +57,9 @@ |
58 | 58 | } |
59 | 59 | |
60 | 60 | function testApi() { |
61 | | - global $wgServerName, $wgServer; |
| 61 | + global $wgServerName, $wgServer, $wgDBprefix; |
62 | 62 | |
| 63 | + if($wgDBprefix === "parsertest_") $this->markTestSkipped("This test can't (yet?) be run with the parser tests"); |
63 | 64 | if(!isset($wgServerName) || !isset($wgServer)) { |
64 | 65 | $this->markTestIncomplete('This test needs $wgServerName and $wgServer to '. |
65 | 66 | 'be set in LocalSettings.php'); |
— | — | @@ -73,8 +74,9 @@ |
74 | 75 | } |
75 | 76 | |
76 | 77 | function testApiLoginNoName() { |
77 | | - global $wgServerName, $wgServer; |
| 78 | + global $wgServerName, $wgServer, $wgDBprefix; |
78 | 79 | |
| 80 | + if($wgDBprefix === "parsertest_") $this->markTestSkipped("This test can't (yet?) be run with the parser tests"); |
79 | 81 | if(!isset($wgServerName) || !isset($wgServer)) { |
80 | 82 | $this->markTestIncomplete('This test needs $wgServerName and $wgServer to '. |
81 | 83 | 'be set in LocalSettings.php'); |
— | — | @@ -92,8 +94,9 @@ |
93 | 95 | } |
94 | 96 | |
95 | 97 | function testApiLoginBadPass() { |
96 | | - global $wgServerName, $wgServer; |
| 98 | + global $wgServerName, $wgServer, $wgDBprefix; |
97 | 99 | |
| 100 | + if($wgDBprefix === "parsertest_") $this->markTestSkipped("This test can't (yet?) be run with the parser tests"); |
98 | 101 | if(!isset($wgServerName) || !isset($wgServer)) { |
99 | 102 | $this->markTestIncomplete('This test needs $wgServerName and $wgServer to '. |
100 | 103 | 'be set in LocalSettings.php'); |
— | — | @@ -111,8 +114,9 @@ |
112 | 115 | } |
113 | 116 | |
114 | 117 | function testApiLoginGoodPass() { |
115 | | - global $wgServerName, $wgServer; |
| 118 | + global $wgServerName, $wgServer, $wgDBprefix; |
116 | 119 | |
| 120 | + if($wgDBprefix === "parsertest_") $this->markTestSkipped("This test can't (yet?) be run with the parser tests"); |
117 | 121 | if(!isset($wgServerName) || !isset($wgServer)) { |
118 | 122 | $this->markTestIncomplete('This test needs $wgServerName and $wgServer to '. |
119 | 123 | 'be set in LocalSettings.php'); |
— | — | @@ -130,8 +134,9 @@ |
131 | 135 | } |
132 | 136 | |
133 | 137 | function testApiGotCookie() { |
134 | | - global $wgServerName, $wgServer, $wgScriptPath; |
| 138 | + global $wgServerName, $wgServer, $wgScriptPath, $wgDBprefix; |
135 | 139 | |
| 140 | + if($wgDBprefix === "parsertest_") $this->markTestSkipped("This test can't (yet?) be run with the parser tests"); |
136 | 141 | if(!isset($wgServerName) || !isset($wgServer)) { |
137 | 142 | $this->markTestIncomplete('This test needs $wgServerName and $wgServer to '. |
138 | 143 | 'be set in LocalSettings.php'); |
— | — | @@ -154,8 +159,9 @@ |
155 | 160 | */ |
156 | 161 | function testApiListPages(CookieJar $cj) { |
157 | 162 | $this->markTestIncomplete("Not done with this yet"); |
158 | | - global $wgServerName, $wgServer; |
| 163 | + global $wgServerName, $wgServer, $wgDBprefix; |
159 | 164 | |
| 165 | + if($wgDBprefix === "parsertest_") $this->markTestSkipped("This test can't (yet?) be run with the parser tests"); |
160 | 166 | if($wgServerName == "localhost" || $wgServer == "http://localhost") { |
161 | 167 | $this->markTestIncomplete('This test needs $wgServerName and $wgServer to '. |
162 | 168 | 'be set in LocalSettings.php'); |
Index: trunk/phase3/maintenance/tests/UploadFromChunksTest.php |
— | — | @@ -1,7 +1,11 @@ |
2 | 2 | <?php |
3 | 3 | |
4 | 4 | require_once( "ApiSetup.php" ); |
| 5 | +require_once( dirname( dirname( __FILE__ ) )."/deleteArchivedFiles.inc" ); |
| 6 | +require_once( dirname( dirname( __FILE__ ) )."/deleteArchivedRevisions.inc" ); |
5 | 7 | |
| 8 | +class nullClass {public function handleOutput(){}} |
| 9 | + |
6 | 10 | class UploadFromChunksTest extends ApiSetup { |
7 | 11 | |
8 | 12 | function setUp() { |
— | — | @@ -9,6 +13,14 @@ |
10 | 14 | |
11 | 15 | $wgEnableUploads = true; |
12 | 16 | parent::setup(); |
| 17 | + $wgLocalFileRepo = array( |
| 18 | + 'class' => 'LocalRepo', |
| 19 | + 'name' => 'local', |
| 20 | + 'directory' => 'test-repo', |
| 21 | + 'url' => 'http://example.com/images', |
| 22 | + 'hashLevels' => 2, |
| 23 | + 'transformVia404' => false, |
| 24 | + ); |
13 | 25 | |
14 | 26 | ini_set( 'file_loads', 1 ); |
15 | 27 | ini_set( 'log_errors', 1 ); |
— | — | @@ -64,6 +76,7 @@ |
65 | 77 | 'action' => 'login', |
66 | 78 | 'lgname' => self::$userName, |
67 | 79 | 'lgpassword' => self::$passWord ) ); |
| 80 | + |
68 | 81 | $this->assertArrayHasKey( "login", $data[0] ); |
69 | 82 | $this->assertArrayHasKey( "result", $data[0]['login'] ); |
70 | 83 | $this->assertEquals( "Success", $data[0]['login']['result'] ); |
— | — | @@ -202,15 +215,35 @@ |
203 | 216 | /** |
204 | 217 | * @depends testLogin |
205 | 218 | */ |
206 | | - function testUploadChunkDoneDuplicate( $data ) { |
| 219 | + function testUploadChunkDoneGood( $data ) { |
207 | 220 | global $wgUser, $wgVerifyMimeType; |
| 221 | + $wgVerifyMimeType = false; |
208 | 222 | |
209 | | - $wgVerifyMimeType = false; |
| 223 | + DeleteArchivedFilesImplementation::doDelete(new nullClass, true); |
| 224 | + DeleteArchivedRevisionsImplementation::doDelete(new nullClass); |
| 225 | + |
| 226 | + $id = Title::newFromText( "Twar.png", NS_FILE )->getArticleID(); |
| 227 | + $oldFile = Article::newFromID( $id ); |
| 228 | + if ( $oldFile ) { |
| 229 | + $oldFile->doDeleteArticle(); |
| 230 | + $oldFile->doPurge(); |
| 231 | + } |
| 232 | + |
| 233 | + $oldFile = wfFindFile( "Twar.png" ); |
| 234 | + if ( $oldFile ) { |
| 235 | + $oldFile->delete(); |
| 236 | + } |
| 237 | + $id = Title::newFromText( "Twar.png", NS_FILE )->getArticleID(); |
| 238 | + $this->assertEquals(0, $id); |
| 239 | + |
| 240 | + $oldFile = Article::newFromID( $id ); |
| 241 | + $this->assertEquals(null, $oldFile); |
| 242 | + |
210 | 243 | $wgUser = User::newFromName( self::$userName ); |
211 | 244 | $data[2]['wsEditToken'] = $data[2]['wsToken']; |
212 | 245 | $token = md5( $data[2]['wsToken'] ) . EDIT_TOKEN_SUFFIX; |
213 | 246 | $data = $this->doApiRequest( array( |
214 | | - 'filename' => 'tmp.png', |
| 247 | + 'filename' => 'twar.png', |
215 | 248 | 'action' => 'upload', |
216 | 249 | 'enablechunks' => true, |
217 | 250 | 'token' => $token ), $data ); |
— | — | @@ -218,7 +251,7 @@ |
219 | 252 | $url = $data[0]['uploadUrl']; |
220 | 253 | $params = wfCgiToArray( substr( $url, strpos( $url, "?" ) ) ); |
221 | 254 | $size = 0; |
222 | | - for ( $i = 0; $i < 4; $i++ ) { |
| 255 | + for ( $i = 0; $i < 5; $i++ ) { |
223 | 256 | $this->makeChunk( "123" ); |
224 | 257 | $size += $_FILES['chunk']['size']; |
225 | 258 | |
— | — | @@ -234,41 +267,29 @@ |
235 | 268 | |
236 | 269 | $params['done'] = true; |
237 | 270 | |
238 | | - $this->makeChunk( "123" ); |
| 271 | + $this->makeChunk( "456" ); |
239 | 272 | $data = $this->doApiRequest( $params, $data ); |
| 273 | + |
240 | 274 | $this->cleanChunk(); |
| 275 | + $this->assertArrayHasKey( 'result', $data[0] ); |
| 276 | + $this->assertEquals( 1, $data[0]['result'] ); |
241 | 277 | |
242 | | - $this->assertArrayHasKey( 'upload', $data[0] ); |
243 | | - $this->assertArrayHasKey( 'result', $data[0]['upload'] ); |
244 | | - $this->assertEquals( 'Warning', $data[0]['upload']['result'] ); |
| 278 | + $this->assertArrayHasKey( 'done', $data[0] ); |
| 279 | + $this->assertEquals( 1, $data[0]['done'] ); |
245 | 280 | |
246 | | - $this->assertArrayHasKey( 'warnings', $data[0]['upload'] ); |
247 | | - $this->assertArrayHasKey( 'exists', |
248 | | - $data[0]['upload']['warnings'] ); |
249 | | - $this->assertEquals( 'Tmp.png', |
250 | | - $data[0]['upload']['warnings']['exists'] ); |
251 | | - |
| 281 | + $this->assertArrayHasKey( 'resultUrl', $data[0] ); |
| 282 | + $this->assertRegExp( '/File:Twar.png/', $data[0]['resultUrl'] ); |
252 | 283 | } |
253 | 284 | |
254 | 285 | /** |
255 | 286 | * @depends testLogin |
256 | 287 | */ |
257 | | - function testUploadChunkDoneGood( $data ) { |
| 288 | + function testUploadChunkDoneDuplicate( $data ) { |
258 | 289 | global $wgUser, $wgVerifyMimeType; |
259 | | - $wgVerifyMimeType = false; |
260 | 290 | |
261 | | - $id = Title::newFromText( "Twar.png", NS_FILE )->getArticleID(); |
| 291 | + $this->markTestIncomplete("Not working yet"); |
262 | 292 | |
263 | | - $oldFile = Article::newFromID( $id ); |
264 | | - if ( $oldFile ) { |
265 | | - $oldFile->doDeleteArticle(); |
266 | | - $oldFile->doPurge(); |
267 | | - } |
268 | | - $oldFile = wfFindFile( "Twar.png" ); |
269 | | - if ( $oldFile ) { |
270 | | - $oldFile->delete(); |
271 | | - } |
272 | | - |
| 293 | + $wgVerifyMimeType = false; |
273 | 294 | $wgUser = User::newFromName( self::$userName ); |
274 | 295 | $data[2]['wsEditToken'] = $data[2]['wsToken']; |
275 | 296 | $token = md5( $data[2]['wsToken'] ) . EDIT_TOKEN_SUFFIX; |
— | — | @@ -281,38 +302,30 @@ |
282 | 303 | $url = $data[0]['uploadUrl']; |
283 | 304 | $params = wfCgiToArray( substr( $url, strpos( $url, "?" ) ) ); |
284 | 305 | $size = 0; |
285 | | - for ( $i = 0; $i < 5; $i++ ) { |
| 306 | + $gotException = false; |
| 307 | + for ( $i = 0; $i < 30; $i++ ) { |
286 | 308 | $this->makeChunk( "123" ); |
287 | 309 | $size += $_FILES['chunk']['size']; |
| 310 | + try { |
| 311 | + $data = $this->doApiRequest( $params, $data ); |
| 312 | + } catch (UsageException $e) { |
| 313 | + $arr = $e->getMessageArray(); |
| 314 | + $this->assertArrayHasKey( "code", $arr ); |
| 315 | + $this->assertEquals( "internal-error", $arr['code'] ); |
288 | 316 | |
289 | | - $data = $this->doApiRequest( $params, $data ); |
290 | | - $this->assertArrayHasKey( "result", $data[0] ); |
291 | | - $this->assertTrue( (bool)$data[0]["result"] ); |
292 | | - |
293 | | - $this->assertArrayHasKey( "filesize", $data[0] ); |
294 | | - $this->assertEquals( $size, $data[0]['filesize'] ); |
295 | | - |
296 | | - $this->cleanChunk(); |
| 317 | + $this->assertEquals( "fileexistserror", $arr[0][0] ); |
| 318 | + $gotException = true; |
| 319 | + } |
297 | 320 | } |
298 | | - |
299 | | - $params['done'] = true; |
300 | | - |
301 | | - $this->makeChunk( "456" ); |
302 | | - $data = $this->doApiRequest( $params, $data ); |
303 | | - |
304 | 321 | $this->cleanChunk(); |
| 322 | + $this->assertTrue($gotException); |
| 323 | + } |
305 | 324 | |
306 | | - if ( isset( $data[0]['upload'] ) ) { |
307 | | - $this->markTestSkipped( "Please run 'php maintenance/deleteArchivedFiles.php --delete --force' and 'php maintenance/deleteArchivedRevisions.php --delete'" ); |
308 | | - } |
309 | | - |
310 | | - $this->assertArrayHasKey( 'result', $data[0] ); |
311 | | - $this->assertEquals( 1, $data[0]['result'] ); |
312 | | - |
313 | | - $this->assertArrayHasKey( 'done', $data[0] ); |
314 | | - $this->assertEquals( 1, $data[0]['done'] ); |
315 | | - |
316 | | - $this->assertArrayHasKey( 'resultUrl', $data[0] ); |
317 | | - $this->assertRegExp( '/File:Twar.png/', $data[0]['resultUrl'] ); |
| 325 | + function testCleanup() { |
| 326 | + $dbw = wfGetDB( DB_MASTER ); |
| 327 | + $dbw->begin(); |
| 328 | + $dbw->delete("image", array('img_user_text' => self::$userName )); |
| 329 | + $dbw->commit(); |
| 330 | + $this->assertTrue(true); |
318 | 331 | } |
319 | 332 | } |
Index: trunk/phase3/maintenance/tests/SearchMySQLTest.php |
— | — | @@ -5,6 +5,9 @@ |
6 | 6 | var $db; |
7 | 7 | |
8 | 8 | function setUp() { |
| 9 | + global $wgDBprefix; |
| 10 | + if($wgDBprefix === "parsertest_") $this->markTestSkipped("This test can't (yet?) be run with the parser tests"); |
| 11 | + |
9 | 12 | $GLOBALS['wgContLang'] = new Language; |
10 | 13 | $this->db = $this->buildTestDatabase( |
11 | 14 | array( 'page', 'revision', 'text', 'searchindex', 'user' ) ); |
Index: trunk/phase3/maintenance/tests/phpunit.xml |
— | — | @@ -7,6 +7,19 @@ |
8 | 8 | <!-- convertWarningsToExceptions="true" --> |
9 | 9 | <testsuite name="MediaWiki Test Suite"> |
10 | 10 | <directory>.</directory> |
| 11 | + <!-- <file>HttpTest.php</file> --> |
| 12 | + <!-- <file>SearchEngineTest.php</file> --> |
| 13 | + <!-- <file>SiteConfigurationTest.php</file> --> |
| 14 | + <!-- <file>RevisionTest.php</file> --> |
| 15 | + <!-- <file>XmlTest.php</file> --> |
| 16 | + <!-- <file>TimeAdjustTest.php</file> --> |
| 17 | + <!-- <file>ApiTest.php</file> --> |
| 18 | + <!-- <file>LanguageConverterTest.php</file> --> |
| 19 | + <!-- <file>TitleTest.php</file> --> |
| 20 | + <!-- <file>UploadFromChunksTest.php</file> --> |
| 21 | + <!-- <file>LocalFileTest.php</file> --> |
| 22 | + <!-- <file>XmlTest.php</file> --> |
| 23 | + <!-- <file>MediaWikiParserTest.php</file> --> |
11 | 24 | </testsuite> |
12 | 25 | <groups> |
13 | 26 | <exclude> |
Index: trunk/phase3/maintenance/tests/MediaWikiParserTest.php |
— | — | @@ -18,14 +18,23 @@ |
19 | 19 | } |
20 | 20 | |
21 | 21 | class MediaWikiParserTestSuite extends PHPUnit_Framework_TestSuite { |
22 | | -#implements PHPUnit_Framework_SelfDescribing { |
23 | 22 | static private $count; |
24 | 23 | static public $parser; |
25 | 24 | static public $iter; |
26 | 25 | |
| 26 | + public static function addTables(&$tables) { |
| 27 | + $tables[] = 'user_properties'; |
| 28 | + $tables[] = 'filearchive'; |
| 29 | + $tables[] = 'logging'; |
| 30 | + return true; |
| 31 | + } |
| 32 | + |
27 | 33 | public static function suite() { |
28 | 34 | $suite = new PHPUnit_Framework_TestSuite(); |
29 | 35 | |
| 36 | + global $wgHooks; |
| 37 | + $wgHooks['ParserTestTables'][] = "MediaWikiParserTestSuite::addTables"; |
| 38 | + |
30 | 39 | self::$iter = new TestFileIterator( PARSER_TESTS ); |
31 | 40 | |
32 | 41 | foreach(self::$iter as $i => $test) { |
— | — | @@ -57,12 +66,12 @@ |
58 | 67 | $wgLocalFileRepo = array( |
59 | 68 | 'class' => 'LocalRepo', |
60 | 69 | 'name' => 'local', |
61 | | - 'directory' => '', |
| 70 | + 'directory' => 'test-repo', |
62 | 71 | 'url' => 'http://example.com/images', |
63 | 72 | 'hashLevels' => 2, |
64 | 73 | 'transformVia404' => false, |
65 | 74 | ); |
66 | | - $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; |
| 75 | + $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; |
67 | 76 | $wgNamespaceAliases['Image'] = NS_FILE; |
68 | 77 | $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; |
69 | 78 | |
— | — | @@ -88,12 +97,12 @@ |
89 | 98 | return $suite; |
90 | 99 | } |
91 | 100 | |
92 | | - public function tearDown() { |
93 | | - $this->teardownDatabase(); |
94 | | - $this->recorder->report(); |
95 | | - $this->recorder->end(); |
96 | | - $this->teardownUploadDir($this->uploadDir); |
97 | | - } |
| 101 | + /* public function tearDown() { */ |
| 102 | + /* $this->teardownDatabase(); */ |
| 103 | + /* $this->recorder->report(); */ |
| 104 | + /* $this->recorder->end(); */ |
| 105 | + /* $this->teardownUploadDir($this->uploadDir); */ |
| 106 | + /* } */ |
98 | 107 | |
99 | 108 | public function count() {return self::$count;} |
100 | 109 | |
— | — | @@ -102,7 +111,6 @@ |
103 | 112 | } |
104 | 113 | |
105 | 114 | |
106 | | - private $db; |
107 | 115 | private $uploadDir; |
108 | 116 | private $keepUploads; |
109 | 117 | /** |
— | — | @@ -198,11 +206,18 @@ |
199 | 207 | } |
200 | 208 | } |
201 | 209 | |
| 210 | +/** |
| 211 | + * @group Stub |
| 212 | + */ |
202 | 213 | class ParserUnitTest extends PHPUnit_Framework_TestCase { |
203 | 214 | private $number = 0; |
204 | 215 | private $test = ""; |
205 | 216 | |
206 | | - public function __construct($number, $test) { |
| 217 | + public function testBogus() { |
| 218 | + $this->markTestSkipped("This is a stub"); |
| 219 | + } |
| 220 | + |
| 221 | + public function __construct($number = null, $test = null) { |
207 | 222 | $this->number = $number; |
208 | 223 | $this->test = $test; |
209 | 224 | } |
Index: trunk/phase3/maintenance/deleteArchivedRevisions.inc |
— | — | @@ -0,0 +1,49 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/** |
| 5 | + * Delete archived (deleted from public) revisions from the database |
| 6 | + * |
| 7 | + * This program is free software; you can redistribute it and/or modify |
| 8 | + * it under the terms of the GNU General Public License as published by |
| 9 | + * the Free Software Foundation; either version 2 of the License, or |
| 10 | + * (at your option) any later version. |
| 11 | + * |
| 12 | + * This program is distributed in the hope that it will be useful, |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | + * GNU General Public License for more details. |
| 16 | + * |
| 17 | + * You should have received a copy of the GNU General Public License along |
| 18 | + * with this program; if not, write to the Free Software Foundation, Inc., |
| 19 | + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 20 | + * http://www.gnu.org/copyleft/gpl.html |
| 21 | + * |
| 22 | + * @ingroup Maintenance |
| 23 | + */ |
| 24 | + |
| 25 | +class DeleteArchivedRevisionsImplementation { |
| 26 | + |
| 27 | + static public function doDelete($output) { |
| 28 | + $dbw = wfGetDB( DB_MASTER ); |
| 29 | + |
| 30 | + $dbw->begin(); |
| 31 | + |
| 32 | + $tbl_arch = $dbw->tableName( 'archive' ); |
| 33 | + |
| 34 | + # Delete as appropriate |
| 35 | + $output->handleOutput( "Deleting archived revisions... " ); |
| 36 | + $dbw->query( "TRUNCATE TABLE $tbl_arch" ); |
| 37 | + |
| 38 | + $count = $dbw->affectedRows(); |
| 39 | + $deletedRows = $count != 0; |
| 40 | + |
| 41 | + $output->handleOutput( "done. $count revisions deleted.\n" ); |
| 42 | + |
| 43 | + # This bit's done |
| 44 | + # Purge redundant text records |
| 45 | + $dbw->commit(); |
| 46 | + if( $deletedRows ) { |
| 47 | + $output->purgeRedundantText( true ); |
| 48 | + } |
| 49 | + } |
| 50 | +} |
\ No newline at end of file |
Index: trunk/phase3/maintenance/deleteArchivedRevisions.php |
— | — | @@ -24,6 +24,7 @@ |
25 | 25 | */ |
26 | 26 | |
27 | 27 | require_once( dirname(__FILE__) . '/Maintenance.php' ); |
| 28 | +require_once( dirname(__FILE__) . '/deleteArchivedRevisions.inc' ); |
28 | 29 | |
29 | 30 | class DeleteArchivedRevisions extends Maintenance { |
30 | 31 | public function __construct() { |
— | — | @@ -32,31 +33,17 @@ |
33 | 34 | $this->addOption( 'delete', 'Performs the deletion' ); |
34 | 35 | } |
35 | 36 | |
| 37 | + public function handleOutput($str) { |
| 38 | + $this->output($str); |
| 39 | + } |
| 40 | + |
36 | 41 | public function execute() { |
37 | 42 | $this->output( "Delete archived revisions\n\n" ); |
38 | 43 | # Data should come off the master, wrapped in a transaction |
39 | | - $dbw = wfGetDB( DB_MASTER ); |
40 | 44 | if( $this->hasOption('delete') ) { |
41 | | - $dbw->begin(); |
42 | | - |
43 | | - $tbl_arch = $dbw->tableName( 'archive' ); |
44 | | - |
45 | | - # Delete as appropriate |
46 | | - $this->output( "Deleting archived revisions... " ); |
47 | | - $dbw->query( "TRUNCATE TABLE $tbl_arch" ); |
48 | | - |
49 | | - $count = $dbw->affectedRows(); |
50 | | - $deletedRows = $count != 0; |
51 | | - |
52 | | - $this->output( "done. $count revisions deleted.\n" ); |
53 | | - |
54 | | - # This bit's done |
55 | | - # Purge redundant text records |
56 | | - $dbw->commit(); |
57 | | - if( $deletedRows ) { |
58 | | - $this->purgeRedundantText( true ); |
59 | | - } |
| 45 | + DeleteArchivedRevisionsImplementation::doDelete($this); |
60 | 46 | } else { |
| 47 | + $dbw = wfGetDB( DB_MASTER ); |
61 | 48 | $res = $dbw->selectRow( 'archive', 'COUNT(*) as count', array(), __FUNCTION__ ); |
62 | 49 | $this->output( "Found {$res->count} revisions to delete.\n" ); |
63 | 50 | $this->output( "Please run the script again with the --delete option to really delete the revisions.\n" ); |
Index: trunk/phase3/maintenance/deleteArchivedFiles.inc |
— | — | @@ -0,0 +1,62 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Core functions for deleteArchivedFiles.php |
| 5 | + * |
| 6 | + * This program is free software; you can redistribute it and/or modify |
| 7 | + * it under the terms of the GNU General Public License as published by |
| 8 | + * the Free Software Foundation; either version 2 of the License, or |
| 9 | + * (at your option) any later version. |
| 10 | + * |
| 11 | + * This program is distributed in the hope that it will be useful, |
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | + * GNU General Public License for more details. |
| 15 | + * |
| 16 | + * You should have received a copy of the GNU General Public License along |
| 17 | + * with this program; if not, write to the Free Software Foundation, Inc., |
| 18 | + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 19 | + * http://www.gnu.org/copyleft/gpl.html |
| 20 | + * |
| 21 | + * @ingroup Maintenance |
| 22 | + */ |
| 23 | + |
| 24 | +class DeleteArchivedFilesImplementation { |
| 25 | + static public function doDelete($output, $force) { |
| 26 | + # Data should come off the master, wrapped in a transaction |
| 27 | + $dbw = wfGetDB( DB_MASTER ); |
| 28 | + $dbw->begin(); |
| 29 | + $tbl_arch = $dbw->tableName( 'filearchive' ); |
| 30 | + $repo = RepoGroup::singleton()->getLocalRepo(); |
| 31 | + # Get "active" revisions from the filearchive table |
| 32 | + $output->handleOutput( "Searching for and deleting archived files...\n" ); |
| 33 | + $res = $dbw->query( "SELECT fa_id,fa_storage_group,fa_storage_key FROM $tbl_arch" ); |
| 34 | + $count = 0; |
| 35 | + foreach( $res as $row ) { |
| 36 | + $key = $row->fa_storage_key; |
| 37 | + $group = $row->fa_storage_group; |
| 38 | + $id = $row->fa_id; |
| 39 | + $path = $repo->getZonePath( 'deleted' ).'/'.$repo->getDeletedHashPath($key).$key; |
| 40 | + $sha1 = substr( $key, 0, strcspn( $key, '.' ) ); |
| 41 | + // Check if the file is used anywhere... |
| 42 | + $inuse = $dbw->selectField( 'oldimage', '1', |
| 43 | + array( 'oi_sha1' => $sha1, |
| 44 | + 'oi_deleted & '.File::DELETED_FILE => File::DELETED_FILE ), |
| 45 | + __METHOD__, |
| 46 | + array( 'FOR UPDATE' ) |
| 47 | + ); |
| 48 | + if ( $path && file_exists($path) && !$inuse ) { |
| 49 | + unlink($path); // delete |
| 50 | + $count++; |
| 51 | + $dbw->query( "DELETE FROM $tbl_arch WHERE fa_id = $id" ); |
| 52 | + } else { |
| 53 | + $output->handleOutput( "Notice - file '$key' not found in group '$group'\n" ); |
| 54 | + if ( $force ) { |
| 55 | + $outpu->handleOutput( "Got --force, deleting DB entry\n" ); |
| 56 | + $dbw->query( "DELETE FROM $tbl_arch WHERE fa_id = $id" ); |
| 57 | + } |
| 58 | + } |
| 59 | + } |
| 60 | + $dbw->commit(); |
| 61 | + $output->handleOutput( "Done! [$count file(s)]\n" ); |
| 62 | + } |
| 63 | +} |
\ No newline at end of file |
Index: trunk/phase3/maintenance/deleteArchivedFiles.php |
— | — | @@ -24,6 +24,7 @@ |
25 | 25 | */ |
26 | 26 | |
27 | 27 | require_once( dirname(__FILE__) . '/Maintenance.php' ); |
| 28 | +require_once( dirname(__FILE__) . '/deleteArchivedFiles.inc' ); |
28 | 29 | |
29 | 30 | class DeleteArchivedFiles extends Maintenance { |
30 | 31 | public function __construct() { |
— | — | @@ -33,48 +34,17 @@ |
34 | 35 | $this->addOption( 'force', 'Force deletion of rows from filearchive' ); |
35 | 36 | } |
36 | 37 | |
| 38 | + public function handleOutput($str) { |
| 39 | + return $this->output($str); |
| 40 | + } |
| 41 | + |
37 | 42 | public function execute() { |
38 | 43 | if( !$this->hasOption('delete') ) { |
39 | 44 | $this->output( "Use --delete to actually confirm this script\n" ); |
40 | 45 | return; |
41 | 46 | } |
42 | 47 | $force = $this->hasOption( 'force' ); |
43 | | - # Data should come off the master, wrapped in a transaction |
44 | | - $dbw = wfGetDB( DB_MASTER ); |
45 | | - $dbw->begin(); |
46 | | - $tbl_arch = $dbw->tableName( 'filearchive' ); |
47 | | - $repo = RepoGroup::singleton()->getLocalRepo(); |
48 | | - # Get "active" revisions from the filearchive table |
49 | | - $this->output( "Searching for and deleting archived files...\n" ); |
50 | | - $res = $dbw->query( "SELECT fa_id,fa_storage_group,fa_storage_key FROM $tbl_arch" ); |
51 | | - $count = 0; |
52 | | - foreach( $res as $row ) { |
53 | | - $key = $row->fa_storage_key; |
54 | | - $group = $row->fa_storage_group; |
55 | | - $id = $row->fa_id; |
56 | | - $path = $repo->getZonePath( 'deleted' ).'/'.$repo->getDeletedHashPath($key).$key; |
57 | | - $sha1 = substr( $key, 0, strcspn( $key, '.' ) ); |
58 | | - // Check if the file is used anywhere... |
59 | | - $inuse = $dbw->selectField( 'oldimage', '1', |
60 | | - array( 'oi_sha1' => $sha1, |
61 | | - 'oi_deleted & '.File::DELETED_FILE => File::DELETED_FILE ), |
62 | | - __METHOD__, |
63 | | - array( 'FOR UPDATE' ) |
64 | | - ); |
65 | | - if ( $path && file_exists($path) && !$inuse ) { |
66 | | - unlink($path); // delete |
67 | | - $count++; |
68 | | - $dbw->query( "DELETE FROM $tbl_arch WHERE fa_id = $id" ); |
69 | | - } else { |
70 | | - $this->output( "Notice - file '$key' not found in group '$group'\n" ); |
71 | | - if ( $force ) { |
72 | | - $this->output( "Got --force, deleting DB entry\n" ); |
73 | | - $dbw->query( "DELETE FROM $tbl_arch WHERE fa_id = $id" ); |
74 | | - } |
75 | | - } |
76 | | - } |
77 | | - $dbw->commit(); |
78 | | - $this->output( "Done! [$count file(s)]\n" ); |
| 48 | + DeleteArchivedFilesImplementation::doDelete($this, $force); |
79 | 49 | } |
80 | 50 | } |
81 | 51 | |