* Add include for AdminSettings.php to allow table creation and deletion. This allow...
[lhc/web/wiklou.git] / maintenance / convertLinks.php
1 <?php
2 # Convert from the old links schema (string->ID) to the new schema (ID->ID)
3 # This hasn't been thoroughly tested yet.
4
5 # The wiki should be put into read-only mode while this script executes
6
7 include_once( "commandLine.inc" );
8 # the below should probably be moved into commandLine.inc at some point
9 include_once( "../AdminSettings.php" );
10
11 $numRows = $tuplesAdded = $numBadLinks = $curRowsRead = 0; #counters etc
12 $totalTuplesInserted = 0; # total tuples INSERTed into links_temp
13 $reportCurReadProgress = true; #whether or not to give progress reports while reading IDs from cur table
14 $curReadReportInterval = 1000; #number of rows between progress reports
15 $reportLinksConvProgress = true; #whether or not to give progress reports during conversion
16 $linksConvInsertInterval = 1000; #number of rows between INSERTs and, optionally, reports
17 $initialRowOffset = 0;
18 $finalRowOffset = 0; # not used yet; highest row number from links table to process
19 $createTemporaryTable = 1; # create a temporary table to hold new links table during conv process
20 $overwriteLinksTable = 0; # overwrite the old links table with the new one
21
22 $res = wfQuery( "SELECT COUNT(*) AS count FROM links", DB_WRITE );
23 $row = wfFetchObject($res);
24 $numRows = $row->count;
25 wfFreeResult( $res );
26
27 if ( $numRows == 0 ) {
28 print "No rows to convert. Updating schema...\n";
29 createTempTable();
30 } else {
31 $row = wfFetchObject( $res );
32 if ( is_numeric( $row->l_from ) ) {
33 print "Schema already converted\n";
34 exit;
35 }
36
37 # Create a title -> cur_id map
38 print "Loading IDs from cur table...";
39 wfBufferSQLResults( false );
40 $res = wfQuery( "SELECT cur_namespace,cur_title,cur_id FROM cur", DB_WRITE );
41 $ids = array();
42
43 while ( $row = wfFetchObject( $res ) ) {
44 $title = $row->cur_title;
45 if ( $row->cur_namespace ) {
46 $title = $wgLang->getNsText( $row->cur_namespace ) . ":$title";
47 }
48 $ids[$title] = $row->cur_id;
49 $curRowsRead++;
50 if ($reportCurReadProgress) {
51 if (($curRowsRead % $curReadReportInterval) == 0) {
52 print "\t$curRowsRead rows of cur table read.\n";
53 }
54 }
55 }
56 wfFreeResult( $res );
57 wfBufferSQLResults( true );
58 print "Finished loading IDs.\n";
59 if ( $createTemporaryTable ) {
60 # Create temporary table which will become the new links table.
61 createTempTable();
62 }
63
64 # Now, step through the links table (in chunks of $linksConvInsertInterval rows),
65 # convert, and write to the new table.
66 print "Processing $numRows rows from links table...\n";
67 for ($rowOffset = $initialRowOffset; $rowOffset < $numRows; $rowOffset += $linksConvInsertInterval) {
68 $sqlRead = "SELECT * FROM links LIMIT $linksConvInsertInterval OFFSET $rowOffset";
69 $res = wfQuery($sqlRead, DB_READ);
70 $sqlWrite = array("INSERT IGNORE INTO links_temp(l_from,l_to) VALUES ");
71 $tuplesAdded = 0; # no tuples added to INSERT yet
72 while ( $row = wfFetchObject($res) ) {
73 $fromTitle = $row->l_from;
74 if ( array_key_exists( $fromTitle, $ids ) ) { # valid title
75 $from = $ids[$fromTitle];
76 $to = $row->l_to;
77 if ( $tuplesAdded != 0 ) {
78 $sqlWrite[] = ",";
79 }
80 $sqlWrite[] = "($from,$to)";
81 $tuplesAdded++;
82 } else { # invalid title
83 $numBadLinks++;
84 }
85 }
86 wfFreeResult($res);
87 #print "rowOffset: $rowOffset\ttuplesAdded: $tuplesAdded\tnumBadLinks: $numBadLinks\n";
88 if ( $tuplesAdded != 0 ) {
89 if ($reportLinksConvProgress)
90 print "Inserting $tuplesAdded tuples into links_temp...";
91 wfQuery( implode("",$sqlWrite) , DB_WRITE );
92 $totalTuplesInserted += $tuplesAdded;
93 if ($reportLinksConvProgress)
94 print " done. Total $totalTuplesInserted tuples inserted.\n";
95 }
96 }
97 print "$totalTuplesInserted valid titles and $numBadLinks invalid titles were processed.\n";
98 }
99
100 if ( $overwriteLinksTable ) {
101 $dbConn = Database::newFromParams( $wgDBserver, $wgDBadminuser, $wgDBadminpassword, $wgDBname );
102 if (!($dbConn->isOpen())) {
103 print "Opening connection to database failed.\n";
104 exit;
105 }
106 # Check for existing links_backup, and delete it if it exists.
107 print "Dropping backup links table if it exists...";
108 $dbConn->query( "DROP TABLE IF EXISTS links_backup", DB_WRITE);
109 print " done.\n";
110
111 # Swap in the new table, and move old links table to links_backup
112 print "Swapping tables 'links' to 'links_backup'; 'links_temp' to 'links'...";
113 $dbConn->query( "RENAME TABLE links TO links_backup, links_temp TO links", DB_WRITE );
114 print " done.\n";
115
116 $dbConn->close();
117 print "Conversion complete. The old table remains at links_backup;\n";
118 print "delete at your leisure.\n";
119 } else {
120 print "Conversion complete.\n";
121 }
122
123 function createTempTable() {
124 global $wgDBserver, $wgDBadminuser, $wgDBadminpassword, $wgDBname;
125 $dbConn = Database::newFromParams( $wgDBserver, $wgDBadminuser, $wgDBadminpassword, $wgDBname );
126
127 if (!($dbConn->isOpen())) {
128 print "Opening connection to database failed.\n";
129 exit;
130 }
131
132 print "Dropping temporary links table if it exists...";
133 $dbConn->query( "DROP TABLE IF EXISTS links_temp", DB_WRITE);
134 print " done.\n";
135
136 print "Creating temporary links table...";
137 $dbConn->query( "CREATE TABLE links_temp (
138 l_from int(8) unsigned NOT NULL default '0',
139 l_to int(8) unsigned NOT NULL default '0',
140 UNIQUE KEY l_from(l_from,l_to),
141 KEY (l_to))", DB_WRITE);
142 print " done.\n";
143 }
144 ?>