Clean up CDB classes
authorChad Horohoe <chadh@wikimedia.org>
Thu, 7 Nov 2013 22:03:08 +0000 (14:03 -0800)
committerChad Horohoe <chadh@wikimedia.org>
Sat, 9 Nov 2013 01:19:50 +0000 (17:19 -0800)
- Inheritance was a little funny, reduced some duplication
- Throw CdbException instead of plain MWException
- Abstracted wfDebug() to encourage reuse
- Declare visibility on a couple of public methods
- Move DBA implementations to their own file

Change-Id: I2edfeabaf62e39927abe869764ff2bd676821cd0

includes/AutoLoader.php
includes/utils/Cdb.php
includes/utils/CdbDBA.php [new file with mode: 0644]
includes/utils/CdbPHP.php

index 29d2209..96dda05 100644 (file)
@@ -1046,12 +1046,13 @@ $wgAutoloadLocalClasses = array(
 
        # includes/utils
        'ArrayUtils' => 'includes/utils/ArrayUtils.php',
+       'CdbException' => 'includes/utils/Cdb.php',
        'CdbFunctions' => 'includes/utils/CdbPHP.php',
        'CdbReader' => 'includes/utils/Cdb.php',
-       'CdbReaderDBA' => 'includes/utils/Cdb.php',
+       'CdbReaderDBA' => 'includes/utils/CdbDBA.php',
        'CdbReaderPHP' => 'includes/utils/CdbPHP.php',
        'CdbWriter' => 'includes/utils/Cdb.php',
-       'CdbWriterDBA' => 'includes/utils/Cdb.php',
+       'CdbWriterDBA' => 'includes/utils/CdbDBA.php',
        'CdbWriterPHP' => 'includes/utils/CdbPHP.php',
        'ConfEditor' => 'includes/utils/ConfEditor.php',
        'ConfEditorParseError' => 'includes/utils/ConfEditor.php',
index c6de088..71fa8c8 100644 (file)
  * http://cr.yp.to/cdb.html
  */
 abstract class CdbReader {
+       /**
+        * The file handle
+        */
+       protected $handle;
+
        /**
         * Open a file and return a subclass instance
         *
@@ -34,13 +39,9 @@ abstract class CdbReader {
         * @return CdbReader
         */
        public static function open( $fileName ) {
-               if ( self::haveExtension() ) {
-                       return new CdbReaderDBA( $fileName );
-               } else {
-                       wfDebug( "Warning: no dba extension found, using emulation.\n" );
-
-                       return new CdbReaderPHP( $fileName );
-               }
+               return self::haveExtension() ?
+                       new CdbReaderDBA( $fileName ) :
+                       new CdbReaderPHP( $fileName );
        }
 
        /**
@@ -61,14 +62,16 @@ abstract class CdbReader {
        }
 
        /**
-        * Construct the object and open the file
+        * Create the object and open the file
+        *
+        * @param $fileName string
         */
-       abstract function __construct( $fileName );
+       abstract public function __construct( $fileName );
 
        /**
         * Close the file. Optional, you can just let the variable go out of scope.
         */
-       abstract function close();
+       abstract public function close();
 
        /**
         * Get a value with a given key. Only string values are supported.
@@ -83,6 +86,23 @@ abstract class CdbReader {
  * Native and pure PHP implementations are provided.
  */
 abstract class CdbWriter {
+       /**
+        * The file handle
+        */
+       protected $handle;
+
+       /**
+        * File we'll be writing to when we're done
+        * @var string
+        */
+       protected $realFileName;
+
+       /**
+        * File we write to temporarily until we're done
+        * @var string
+        */
+       protected $tmpFileName;
+
        /**
         * Open a writer and return a subclass instance.
         * The user must have write access to the directory, for temporary file creation.
@@ -92,13 +112,9 @@ abstract class CdbWriter {
         * @return CdbWriterDBA|CdbWriterPHP
         */
        public static function open( $fileName ) {
-               if ( CdbReader::haveExtension() ) {
-                       return new CdbWriterDBA( $fileName );
-               } else {
-                       wfDebug( "Warning: no dba extension found, using emulation.\n" );
-
-                       return new CdbWriterPHP( $fileName );
-               }
+               return CdbReader::haveExtension() ?
+                       new CdbWriterDBA( $fileName ) :
+                       new CdbWriterPHP( $fileName );
        }
 
        /**
@@ -106,7 +122,7 @@ abstract class CdbWriter {
         *
         * @param $fileName string
         */
-       abstract function __construct( $fileName );
+       abstract public function __construct( $fileName );
 
        /**
         * Set a key to a given value. The value will be converted to string.
@@ -120,68 +136,18 @@ abstract class CdbWriter {
         * goes out of scope, to write out the final hashtables.
         */
        abstract public function close();
-}
-
-/**
- * Reader class which uses the DBA extension
- */
-class CdbReaderDBA {
-       var $handle;
 
-       function __construct( $fileName ) {
-               $this->handle = dba_open( $fileName, 'r-', 'cdb' );
-               if ( !$this->handle ) {
-                       throw new MWException( 'Unable to open CDB file "' . $fileName . '"' );
-               }
-       }
-
-       function close() {
+       /**
+        * If the object goes out of scope, close it for sanity
+        */
+       public function __destruct() {
                if ( isset( $this->handle ) ) {
-                       dba_close( $this->handle );
+                       $this->close();
                }
-               unset( $this->handle );
-       }
-
-       function get( $key ) {
-               return dba_fetch( $key, $this->handle );
        }
 }
 
 /**
- * Writer class which uses the DBA extension
+ * Exception for Cdb errors
  */
-class CdbWriterDBA {
-       var $handle, $realFileName, $tmpFileName;
-
-       function __construct( $fileName ) {
-               $this->realFileName = $fileName;
-               $this->tmpFileName = $fileName . '.tmp.' . mt_rand( 0, 0x7fffffff );
-               $this->handle = dba_open( $this->tmpFileName, 'n', 'cdb_make' );
-               if ( !$this->handle ) {
-                       throw new MWException( 'Unable to open CDB file for write "' . $fileName . '"' );
-               }
-       }
-
-       function set( $key, $value ) {
-               return dba_insert( $key, $value, $this->handle );
-       }
-
-       function close() {
-               if ( isset( $this->handle ) ) {
-                       dba_close( $this->handle );
-               }
-               if ( wfIsWindows() ) {
-                       unlink( $this->realFileName );
-               }
-               if ( !rename( $this->tmpFileName, $this->realFileName ) ) {
-                       throw new MWException( 'Unable to move the new CDB file into place.' );
-               }
-               unset( $this->handle );
-       }
-
-       function __destruct() {
-               if ( isset( $this->handle ) ) {
-                       $this->close();
-               }
-       }
-}
+class CdbException extends MWException {}
diff --git a/includes/utils/CdbDBA.php b/includes/utils/CdbDBA.php
new file mode 100644 (file)
index 0000000..5193409
--- /dev/null
@@ -0,0 +1,75 @@
+<?php
+/**
+ * DBA-based CDB reader/writer
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Reader class which uses the DBA extension
+ */
+class CdbReaderDBA extends CdbReader {
+       public function __construct( $fileName ) {
+               $this->handle = dba_open( $fileName, 'r-', 'cdb' );
+               if ( !$this->handle ) {
+                       throw new CdbException( 'Unable to open CDB file "' . $fileName . '"' );
+               }
+       }
+
+       public function close() {
+               if ( isset( $this->handle ) ) {
+                       dba_close( $this->handle );
+               }
+               unset( $this->handle );
+       }
+
+       public function get( $key ) {
+               return dba_fetch( $key, $this->handle );
+       }
+}
+
+/**
+ * Writer class which uses the DBA extension
+ */
+class CdbWriterDBA extends CdbWriter {
+       public function __construct( $fileName ) {
+               $this->realFileName = $fileName;
+               $this->tmpFileName = $fileName . '.tmp.' . mt_rand( 0, 0x7fffffff );
+               $this->handle = dba_open( $this->tmpFileName, 'n', 'cdb_make' );
+               if ( !$this->handle ) {
+                       throw new CdbException( 'Unable to open CDB file for write "' . $fileName . '"' );
+               }
+       }
+
+       public function set( $key, $value ) {
+               return dba_insert( $key, $value, $this->handle );
+       }
+
+       public function close() {
+               if ( isset( $this->handle ) ) {
+                       dba_close( $this->handle );
+               }
+               if ( wfIsWindows() ) {
+                       unlink( $this->realFileName );
+               }
+               if ( !rename( $this->tmpFileName, $this->realFileName ) ) {
+                       throw new CdbException( 'Unable to move the new CDB file into place.' );
+               }
+               unset( $this->handle );
+       }
+}
index e7bb4bc..c6edaf5 100644 (file)
@@ -103,9 +103,6 @@ class CdbReaderPHP extends CdbReader {
        /** The filename */
        var $fileName;
 
-       /** The file handle */
-       var $handle;
-
        /* number of hash slots searched under this key */
        var $loop;
 
@@ -129,18 +126,18 @@ class CdbReaderPHP extends CdbReader {
 
        /**
         * @param $fileName string
-        * @throws MWException
+        * @throws CdbException
         */
-       function __construct( $fileName ) {
+       public function __construct( $fileName ) {
                $this->fileName = $fileName;
                $this->handle = fopen( $fileName, 'rb' );
                if ( !$this->handle ) {
-                       throw new MWException( 'Unable to open CDB file "' . $this->fileName . '".' );
+                       throw new CdbException( 'Unable to open CDB file "' . $this->fileName . '".' );
                }
                $this->findStart();
        }
 
-       function close() {
+       public function close() {
                if ( isset( $this->handle ) ) {
                        fclose( $this->handle );
                }
@@ -176,7 +173,7 @@ class CdbReaderPHP extends CdbReader {
        }
 
        /**
-        * @throws MWException
+        * @throws CdbException
         * @param $length
         * @param $pos
         * @return string
@@ -184,7 +181,7 @@ class CdbReaderPHP extends CdbReader {
        protected function read( $length, $pos ) {
                if ( fseek( $this->handle, $pos ) == -1 ) {
                        // This can easily happen if the internal pointers are incorrect
-                       throw new MWException(
+                       throw new CdbException(
                                'Seek failed, file "' . $this->fileName . '" may be corrupted.' );
                }
 
@@ -194,7 +191,7 @@ class CdbReaderPHP extends CdbReader {
 
                $buf = fread( $this->handle, $length );
                if ( $buf === false || strlen( $buf ) !== $length ) {
-                       throw new MWException(
+                       throw new CdbException(
                                'Read from CDB file failed, file "' . $this->fileName . '" may be corrupted.' );
                }
 
@@ -204,13 +201,13 @@ class CdbReaderPHP extends CdbReader {
        /**
         * Unpack an unsigned integer and throw an exception if it needs more than 31 bits
         * @param $s
-        * @throws MWException
+        * @throws CdbException
         * @return mixed
         */
        protected function unpack31( $s ) {
                $data = unpack( 'V', $s );
                if ( $data[1] > 0x7fffffff ) {
-                       throw new MWException(
+                       throw new CdbException(
                                'Error in CDB file "' . $this->fileName . '", integer too big.' );
                }
 
@@ -291,15 +288,13 @@ class CdbReaderPHP extends CdbReader {
  * CDB writer class
  */
 class CdbWriterPHP extends CdbWriter {
-       var $handle, $realFileName, $tmpFileName;
-
        var $hplist;
        var $numentries, $pos;
 
        /**
         * @param $fileName string
         */
-       function __construct( $fileName ) {
+       public function __construct( $fileName ) {
                $this->realFileName = $fileName;
                $this->tmpFileName = $fileName . '.tmp.' . mt_rand( 0, 0x7fffffff );
                $this->handle = fopen( $this->tmpFileName, 'wb' );
@@ -315,12 +310,6 @@ class CdbWriterPHP extends CdbWriter {
                }
        }
 
-       function __destruct() {
-               if ( isset( $this->handle ) ) {
-                       $this->close();
-               }
-       }
-
        /**
         * @param $key
         * @param $value
@@ -338,7 +327,7 @@ class CdbWriterPHP extends CdbWriter {
        }
 
        /**
-        * @throws MWException
+        * @throws CdbException
         */
        public function close() {
                $this->finish();
@@ -355,7 +344,7 @@ class CdbWriterPHP extends CdbWriter {
        }
 
        /**
-        * @throws MWException
+        * @throws CdbException
         * @param $buf
         */
        protected function write( $buf ) {
@@ -366,7 +355,7 @@ class CdbWriterPHP extends CdbWriter {
        }
 
        /**
-        * @throws MWException
+        * @throws CdbException
         * @param $len
         */
        protected function posplus( $len ) {
@@ -396,7 +385,7 @@ class CdbWriterPHP extends CdbWriter {
        }
 
        /**
-        * @throws MWException
+        * @throws CdbException
         * @param $keylen
         * @param $datalen
         */
@@ -412,7 +401,7 @@ class CdbWriterPHP extends CdbWriter {
        }
 
        /**
-        * @throws MWException
+        * @throws CdbException
         */
        protected function finish() {
                // Hack for DBA cross-check
@@ -491,13 +480,13 @@ class CdbWriterPHP extends CdbWriter {
         * Clean up the temp file and throw an exception
         *
         * @param $msg string
-        * @throws MWException
+        * @throws CdbException
         */
        protected function throwException( $msg ) {
                if ( $this->handle ) {
                        fclose( $this->handle );
                        unlink( $this->tmpFileName );
                }
-               throw new MWException( $msg );
+               throw new CdbException( $msg );
        }
 }