Give sql.php eval.php type scrollback
authorSam Reed <reedy@users.mediawiki.org>
Thu, 12 Jan 2012 22:57:51 +0000 (22:57 +0000)
committerSam Reed <reedy@users.mediawiki.org>
Thu, 12 Jan 2012 22:57:51 +0000 (22:57 +0000)
includes/db/Database.php
includes/db/DatabaseMysql.php
maintenance/sql.php

index c51a0c1..e0b63e1 100644 (file)
@@ -846,7 +846,6 @@ abstract class DatabaseBase implements DatabaseType {
                        $sqlx = substr( $commentedSql, 0, 500 );
                        $sqlx = strtr( $sqlx, "\t\n", '  ' );
 
-
                        $master = $isMaster ? 'master' : 'slave';
                        wfDebug( "Query {$this->mDBname} ($cnt) ($master): $sqlx\n" );
                }
@@ -3154,7 +3153,7 @@ abstract class DatabaseBase implements DatabaseType {
         * @param $inputCallback Callback: Optional function called for each complete line (ended with ;) sent
         * @return bool|string
         */
-       function sourceStream( $fp, $lineCallback = false, $resultCallback = false,
+       public function sourceStream( $fp, $lineCallback = false, $resultCallback = false,
                $fname = 'DatabaseBase::sourceStream', $inputCallback = false )
        {
                $cmd = '';
@@ -3208,11 +3207,11 @@ abstract class DatabaseBase implements DatabaseType {
        /**
         * Called by sourceStream() to check if we've reached a statement end
         *
-        * @param $sql String: SQL assembled so far
-        * @param $newLine String: New line about to be added to $sql
-        * @returns Bool: Whether $newLine contains end of the statement
+        * @param $sql String SQL assembled so far
+        * @param $newLine String New line about to be added to $sql
+        * @return Bool Whether $newLine contains end of the statement
         */
-       protected function streamStatementEnd( &$sql, &$newLine ) {
+       public function streamStatementEnd( &$sql, &$newLine ) {
                if ( $this->delimiter ) {
                        $prev = $newLine;
                        $newLine = preg_replace( '/' . preg_quote( $this->delimiter, '/' ) . '$/', '', $newLine );
index 95d3968..c179b72 100644 (file)
@@ -670,7 +670,7 @@ class DatabaseMysql extends DatabaseBase {
                }
        }
 
-       protected function streamStatementEnd( &$sql, &$newLine ) {
+       public function streamStatementEnd( &$sql, &$newLine ) {
                if ( strtoupper( substr( $newLine, 0, 9 ) ) == 'DELIMITER' ) {
                        preg_match( '/^DELIMITER\s+(\S+)/' , $newLine, $m );
                        $this->delimiter = $m[1];
index e1f2bb5..a5c7314 100644 (file)
@@ -33,29 +33,52 @@ class MwSql extends Maintenance {
                if ( $this->hasArg() ) {
                        $fileName = $this->getArg();
                        $file = fopen( $fileName, 'r' );
-                       $promptCallback = false;
                } else {
                        $file = $this->getStdin();
-                       $promptObject = new SqlPromptPrinter( "> " );
-                       $promptCallback = $promptObject->cb();
                }
 
-               if ( !$file )
+               if ( !$file ) {
                        $this->error( "Unable to open input file", true );
+               }
+
+               $useReadline = function_exists( 'readline_add_history' )
+                               && Maintenance::posix_isatty( 0 /*STDIN*/ );
+
+               if ( $useReadline ) {
+                       global $IP;
+                       $historyFile = isset( $_ENV['HOME'] ) ?
+                                       "{$_ENV['HOME']}/.mwsql_history" : "$IP/maintenance/.mwsql_history";
+                       readline_read_history( $historyFile );
+               }
 
                $dbw = wfGetDB( DB_MASTER );
-               $error = $dbw->sourceStream( $file, $promptCallback, array( $this, 'sqlPrintResult' ) );
-               if ( $error !== true ) {
-                       $this->error( $error, true );
-               } else {
-                       exit( 0 );
+               $wholeLine = '';
+               while ( ( $line = Maintenance::readconsole() ) !== false ) {
+                       $done = $dbw->streamStatementEnd( $wholeLine, $line );
+
+                       $wholeLine .= $line;
+
+                       if ( !$done ) {
+                               continue;
+                       }
+                       if ( $useReadline ) {
+                               readline_add_history( $wholeLine );
+                               readline_write_history( $historyFile );
+                       }
+                       try{
+                               $res = $dbw->query( $wholeLine );
+                               $this->sqlPrintResult( $res, $dbw );
+                               $wholeLine = '';
+                       } catch (DBQueryError $e) {
+                               $this->error( $e, true );
+                       }
                }
        }
 
        /**
         * Print the results, callback for $db->sourceStream()
-        * @param $res The results object
-        * @param $db Database object
+        * @param $res ResultWrapper The results object
+        * @param $db DatabaseBase object
         */
        public function sqlPrintResult( $res, $db ) {
                if ( !$res ) {
@@ -70,24 +93,13 @@ class MwSql extends Maintenance {
                }
        }
 
+       /**
+        * @return int DB_TYPE constant
+        */
        public function getDbType() {
                return Maintenance::DB_ADMIN;
        }
 }
 
-class SqlPromptPrinter {
-       function __construct( $prompt ) {
-               $this->prompt = $prompt;
-       }
-
-       function cb() {
-               return array( $this, 'printPrompt' );
-       }
-
-       function printPrompt() {
-               echo $this->prompt;
-       }
-}
-
 $maintClass = "MwSql";
 require_once( RUN_MAINTENANCE_IF_MAIN );