MediaWiki
REL1_22
|
00001 <?php 00025 require_once __DIR__ . '/Maintenance.php'; 00026 00032 class MwSql extends Maintenance { 00033 public function __construct() { 00034 parent::__construct(); 00035 $this->mDescription = "Send SQL queries to a MediaWiki database"; 00036 $this->addOption( 'cluster', 'Use an external cluster by name', false, true ); 00037 $this->addOption( 'slave', 'Use a slave server (either "any" or by name)', false, true ); 00038 } 00039 00040 public function execute() { 00041 // Get the appropriate load balancer (for this wiki) 00042 if ( $this->hasOption( 'cluster' ) ) { 00043 $lb = wfGetLBFactory()->getExternalLB( $this->getOption( 'cluster' ) ); 00044 } else { 00045 $lb = wfGetLB(); 00046 } 00047 // Figure out which server to use 00048 if ( $this->hasOption( 'slave' ) ) { 00049 $server = $this->getOption( 'slave' ); 00050 if ( $server === 'any' ) { 00051 $index = DB_SLAVE; 00052 } else { 00053 $index = null; 00054 for ( $i = 0; $i < $lb->getServerCount(); ++$i ) { 00055 if ( $lb->getServerName( $i ) === $server ) { 00056 $index = $i; 00057 break; 00058 } 00059 } 00060 if ( $index === null ) { 00061 $this->error( "No slave server configured with the name '$server'.", 1 ); 00062 } 00063 } 00064 } else { 00065 $index = DB_MASTER; 00066 } 00067 // Get a DB handle (with this wiki's DB selected) from the appropriate load balancer 00068 $dbw = $lb->getConnection( $index ); 00069 if ( $this->hasOption( 'slave' ) && $dbw->getLBInfo( 'master' ) !== null ) { 00070 $this->error( "The server selected ({$dbw->getServer()}) is not a slave.", 1 ); 00071 } 00072 00073 if ( $this->hasArg( 0 ) ) { 00074 $file = fopen( $this->getArg( 0 ), 'r' ); 00075 if ( !$file ) { 00076 $this->error( "Unable to open input file", true ); 00077 } 00078 00079 $error = $dbw->sourceStream( $file, false, array( $this, 'sqlPrintResult' ) ); 00080 if ( $error !== true ) { 00081 $this->error( $error, true ); 00082 } else { 00083 exit( 0 ); 00084 } 00085 } 00086 00087 $useReadline = function_exists( 'readline_add_history' ) 00088 && Maintenance::posix_isatty( 0 /*STDIN*/ ); 00089 00090 if ( $useReadline ) { 00091 global $IP; 00092 $historyFile = isset( $_ENV['HOME'] ) ? 00093 "{$_ENV['HOME']}/.mwsql_history" : "$IP/maintenance/.mwsql_history"; 00094 readline_read_history( $historyFile ); 00095 } 00096 00097 $wholeLine = ''; 00098 $newPrompt = '> '; 00099 $prompt = $newPrompt; 00100 while ( ( $line = Maintenance::readconsole( $prompt ) ) !== false ) { 00101 if ( !$line ) { 00102 # User simply pressed return key 00103 continue; 00104 } 00105 $done = $dbw->streamStatementEnd( $wholeLine, $line ); 00106 00107 $wholeLine .= $line; 00108 00109 if ( !$done ) { 00110 $wholeLine .= ' '; 00111 $prompt = ' -> '; 00112 continue; 00113 } 00114 if ( $useReadline ) { 00115 # Delimiter is eated by streamStatementEnd, we add it 00116 # up in the history (bug 37020) 00117 readline_add_history( $wholeLine . $dbw->getDelimiter() ); 00118 readline_write_history( $historyFile ); 00119 } 00120 try { 00121 $res = $dbw->query( $wholeLine ); 00122 $this->sqlPrintResult( $res, $dbw ); 00123 $prompt = $newPrompt; 00124 $wholeLine = ''; 00125 } catch ( DBQueryError $e ) { 00126 $doDie = ! Maintenance::posix_isatty( 0 ); 00127 $this->error( $e, $doDie ); 00128 } 00129 } 00130 wfWaitForSlaves(); 00131 } 00132 00138 public function sqlPrintResult( $res, $db ) { 00139 if ( !$res ) { 00140 // Do nothing 00141 return; 00142 } elseif ( is_object( $res ) && $res->numRows() ) { 00143 foreach ( $res as $row ) { 00144 $this->output( print_r( $row, true ) ); 00145 } 00146 } else { 00147 $affected = $db->affectedRows(); 00148 $this->output( "Query OK, $affected row(s) affected\n" ); 00149 } 00150 } 00151 00155 public function getDbType() { 00156 return Maintenance::DB_ADMIN; 00157 } 00158 } 00159 00160 $maintClass = "MwSql"; 00161 require_once RUN_MAINTENANCE_IF_MAIN;