Index: trunk/phase3/maintenance/sql.php |
— | — | @@ -33,29 +33,52 @@ |
34 | 34 | if ( $this->hasArg() ) { |
35 | 35 | $fileName = $this->getArg(); |
36 | 36 | $file = fopen( $fileName, 'r' ); |
37 | | - $promptCallback = false; |
38 | 37 | } else { |
39 | 38 | $file = $this->getStdin(); |
40 | | - $promptObject = new SqlPromptPrinter( "> " ); |
41 | | - $promptCallback = $promptObject->cb(); |
42 | 39 | } |
43 | 40 | |
44 | | - if ( !$file ) |
| 41 | + if ( !$file ) { |
45 | 42 | $this->error( "Unable to open input file", true ); |
| 43 | + } |
46 | 44 | |
| 45 | + $useReadline = function_exists( 'readline_add_history' ) |
| 46 | + && Maintenance::posix_isatty( 0 /*STDIN*/ ); |
| 47 | + |
| 48 | + if ( $useReadline ) { |
| 49 | + global $IP; |
| 50 | + $historyFile = isset( $_ENV['HOME'] ) ? |
| 51 | + "{$_ENV['HOME']}/.mwsql_history" : "$IP/maintenance/.mwsql_history"; |
| 52 | + readline_read_history( $historyFile ); |
| 53 | + } |
| 54 | + |
47 | 55 | $dbw = wfGetDB( DB_MASTER ); |
48 | | - $error = $dbw->sourceStream( $file, $promptCallback, array( $this, 'sqlPrintResult' ) ); |
49 | | - if ( $error !== true ) { |
50 | | - $this->error( $error, true ); |
51 | | - } else { |
52 | | - exit( 0 ); |
| 56 | + $wholeLine = ''; |
| 57 | + while ( ( $line = Maintenance::readconsole() ) !== false ) { |
| 58 | + $done = $dbw->streamStatementEnd( $wholeLine, $line ); |
| 59 | + |
| 60 | + $wholeLine .= $line; |
| 61 | + |
| 62 | + if ( !$done ) { |
| 63 | + continue; |
| 64 | + } |
| 65 | + if ( $useReadline ) { |
| 66 | + readline_add_history( $wholeLine ); |
| 67 | + readline_write_history( $historyFile ); |
| 68 | + } |
| 69 | + try{ |
| 70 | + $res = $dbw->query( $wholeLine ); |
| 71 | + $this->sqlPrintResult( $res, $dbw ); |
| 72 | + $wholeLine = ''; |
| 73 | + } catch (DBQueryError $e) { |
| 74 | + $this->error( $e, true ); |
| 75 | + } |
53 | 76 | } |
54 | 77 | } |
55 | 78 | |
56 | 79 | /** |
57 | 80 | * Print the results, callback for $db->sourceStream() |
58 | | - * @param $res The results object |
59 | | - * @param $db Database object |
| 81 | + * @param $res ResultWrapper The results object |
| 82 | + * @param $db DatabaseBase object |
60 | 83 | */ |
61 | 84 | public function sqlPrintResult( $res, $db ) { |
62 | 85 | if ( !$res ) { |
— | — | @@ -70,24 +93,13 @@ |
71 | 94 | } |
72 | 95 | } |
73 | 96 | |
| 97 | + /** |
| 98 | + * @return int DB_TYPE constant |
| 99 | + */ |
74 | 100 | public function getDbType() { |
75 | 101 | return Maintenance::DB_ADMIN; |
76 | 102 | } |
77 | 103 | } |
78 | 104 | |
79 | | -class SqlPromptPrinter { |
80 | | - function __construct( $prompt ) { |
81 | | - $this->prompt = $prompt; |
82 | | - } |
83 | | - |
84 | | - function cb() { |
85 | | - return array( $this, 'printPrompt' ); |
86 | | - } |
87 | | - |
88 | | - function printPrompt() { |
89 | | - echo $this->prompt; |
90 | | - } |
91 | | -} |
92 | | - |
93 | 105 | $maintClass = "MwSql"; |
94 | 106 | require_once( RUN_MAINTENANCE_IF_MAIN ); |
Index: trunk/phase3/includes/db/DatabaseMysql.php |
— | — | @@ -670,7 +670,7 @@ |
671 | 671 | } |
672 | 672 | } |
673 | 673 | |
674 | | - protected function streamStatementEnd( &$sql, &$newLine ) { |
| 674 | + public function streamStatementEnd( &$sql, &$newLine ) { |
675 | 675 | if ( strtoupper( substr( $newLine, 0, 9 ) ) == 'DELIMITER' ) { |
676 | 676 | preg_match( '/^DELIMITER\s+(\S+)/' , $newLine, $m ); |
677 | 677 | $this->delimiter = $m[1]; |
Index: trunk/phase3/includes/db/Database.php |
— | — | @@ -846,7 +846,6 @@ |
847 | 847 | $sqlx = substr( $commentedSql, 0, 500 ); |
848 | 848 | $sqlx = strtr( $sqlx, "\t\n", ' ' ); |
849 | 849 | |
850 | | - |
851 | 850 | $master = $isMaster ? 'master' : 'slave'; |
852 | 851 | wfDebug( "Query {$this->mDBname} ($cnt) ($master): $sqlx\n" ); |
853 | 852 | } |
— | — | @@ -3154,7 +3153,7 @@ |
3155 | 3154 | * @param $inputCallback Callback: Optional function called for each complete line (ended with ;) sent |
3156 | 3155 | * @return bool|string |
3157 | 3156 | */ |
3158 | | - function sourceStream( $fp, $lineCallback = false, $resultCallback = false, |
| 3157 | + public function sourceStream( $fp, $lineCallback = false, $resultCallback = false, |
3159 | 3158 | $fname = 'DatabaseBase::sourceStream', $inputCallback = false ) |
3160 | 3159 | { |
3161 | 3160 | $cmd = ''; |
— | — | @@ -3208,11 +3207,11 @@ |
3209 | 3208 | /** |
3210 | 3209 | * Called by sourceStream() to check if we've reached a statement end |
3211 | 3210 | * |
3212 | | - * @param $sql String: SQL assembled so far |
3213 | | - * @param $newLine String: New line about to be added to $sql |
3214 | | - * @returns Bool: Whether $newLine contains end of the statement |
| 3211 | + * @param $sql String SQL assembled so far |
| 3212 | + * @param $newLine String New line about to be added to $sql |
| 3213 | + * @return Bool Whether $newLine contains end of the statement |
3215 | 3214 | */ |
3216 | | - protected function streamStatementEnd( &$sql, &$newLine ) { |
| 3215 | + public function streamStatementEnd( &$sql, &$newLine ) { |
3217 | 3216 | if ( $this->delimiter ) { |
3218 | 3217 | $prev = $newLine; |
3219 | 3218 | $newLine = preg_replace( '/' . preg_quote( $this->delimiter, '/' ) . '$/', '', $newLine ); |