Merge "maintenance: Script to rename titles for Unicode uppercasing changes"
[lhc/web/wiklou.git] / includes / libs / rdbms / database / DatabaseSqlite.php
index 17f12d3..c875e56 100644 (file)
@@ -23,6 +23,7 @@
  */
 namespace Wikimedia\Rdbms;
 
+use NullLockManager;
 use PDO;
 use PDOException;
 use Exception;
@@ -39,7 +40,7 @@ class DatabaseSqlite extends Database {
        /** @var bool Whether full text is enabled */
        private static $fulltextEnabled = null;
 
-       /** @var string Directory */
+       /** @var string|null Directory */
        protected $dbDir;
        /** @var string File name for SQLite database file */
        protected $dbPath;
@@ -91,10 +92,16 @@ class DatabaseSqlite extends Database {
                        $this->queryLogger->warning( "Invalid SQLite transaction mode provided." );
                }
 
-               $this->lockMgr = new FSLockManager( [
-                       'domain' => $lockDomain,
-                       'lockDirectory' => "{$this->dbDir}/locks"
-               ] );
+               if ( $this->hasProcessMemoryPath() ) {
+                       $this->lockMgr = new NullLockManager( [ 'domain' => $lockDomain ] );
+               } else {
+                       $this->lockMgr = new FSLockManager( [
+                               'domain' => $lockDomain,
+                               'lockDirectory' => is_string( $this->dbDir )
+                                       ? "{$this->dbDir}/locks"
+                                       : dirname( $this->dbPath ) . "/locks"
+                       ] );
+               }
 
                parent::__construct( $p );
        }
@@ -186,7 +193,7 @@ class DatabaseSqlite extends Database {
         * @throws DBConnectionError
         */
        protected function openFile( $fileName, $dbName, $tablePrefix ) {
-               if ( !$this->hasMemoryPath() && !is_readable( $fileName ) ) {
+               if ( !$this->hasProcessMemoryPath() && !is_readable( $fileName ) ) {
                        $error = "SQLite database file not readable";
                        $this->connLogger->error(
                                "Error connecting to {db_server}: {error}",
@@ -348,9 +355,9 @@ class DatabaseSqlite extends Database {
                        return false;
                }
 
-               $r = $res instanceof ResultWrapper ? $res->result : $res;
-               $this->lastAffectedRowCount = $r->rowCount();
-               $res = new ResultWrapper( $this, $r->fetchAll() );
+               $resource = ResultWrapper::unwrap( $res );
+               $this->lastAffectedRowCount = $resource->rowCount();
+               $res = new ResultWrapper( $this, $resource->fetchAll() );
 
                return $res;
        }
@@ -360,9 +367,7 @@ class DatabaseSqlite extends Database {
         */
        function freeResult( $res ) {
                if ( $res instanceof ResultWrapper ) {
-                       $res->result = null;
-               } else {
-                       $res = null;
+                       $res->free();
                }
        }
 
@@ -371,15 +376,11 @@ class DatabaseSqlite extends Database {
         * @return stdClass|bool
         */
        function fetchObject( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $r =& $res->result;
-               } else {
-                       $r =& $res;
-               }
+               $resource =& ResultWrapper::unwrap( $res );
 
-               $cur = current( $r );
+               $cur = current( $resource );
                if ( is_array( $cur ) ) {
-                       next( $r );
+                       next( $resource );
                        $obj = new stdClass;
                        foreach ( $cur as $k => $v ) {
                                if ( !is_numeric( $k ) ) {
@@ -398,14 +399,10 @@ class DatabaseSqlite extends Database {
         * @return array|bool
         */
        function fetchRow( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $r =& $res->result;
-               } else {
-                       $r =& $res;
-               }
-               $cur = current( $r );
+               $resource =& ResultWrapper::unwrap( $res );
+               $cur = current( $resource );
                if ( is_array( $cur ) ) {
-                       next( $r );
+                       next( $resource );
 
                        return $cur;
                }
@@ -421,9 +418,9 @@ class DatabaseSqlite extends Database {
         */
        function numRows( $res ) {
                // false does not implement Countable
-               $r = $res instanceof ResultWrapper ? $res->result : $res;
+               $resource = ResultWrapper::unwrap( $res );
 
-               return is_array( $r ) ? count( $r ) : 0;
+               return is_array( $resource ) ? count( $resource ) : 0;
        }
 
        /**
@@ -431,10 +428,10 @@ class DatabaseSqlite extends Database {
         * @return int
         */
        function numFields( $res ) {
-               $r = $res instanceof ResultWrapper ? $res->result : $res;
-               if ( is_array( $r ) && count( $r ) > 0 ) {
+               $resource = ResultWrapper::unwrap( $res );
+               if ( is_array( $resource ) && count( $resource ) > 0 ) {
                        // The size of the result array is twice the number of fields. (T67578)
-                       return count( $r[0] ) / 2;
+                       return count( $resource[0] ) / 2;
                } else {
                        // If the result is empty return 0
                        return 0;
@@ -447,9 +444,9 @@ class DatabaseSqlite extends Database {
         * @return bool
         */
        function fieldName( $res, $n ) {
-               $r = $res instanceof ResultWrapper ? $res->result : $res;
-               if ( is_array( $r ) ) {
-                       $keys = array_keys( $r[0] );
+               $resource = ResultWrapper::unwrap( $res );
+               if ( is_array( $resource ) ) {
+                       $keys = array_keys( $resource[0] );
 
                        return $keys[$n];
                }
@@ -488,15 +485,11 @@ class DatabaseSqlite extends Database {
         * @param int $row
         */
        function dataSeek( $res, $row ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $r =& $res->result;
-               } else {
-                       $r =& $res;
-               }
-               reset( $r );
+               $resource =& ResultWrapper::unwrap( $res );
+               reset( $resource );
                if ( $row > 0 ) {
                        for ( $i = 0; $i < $row; $i++ ) {
-                               next( $r );
+                               next( $resource );
                        }
                }
        }
@@ -772,13 +765,13 @@ class DatabaseSqlite extends Database {
        }
 
        public function serverIsReadOnly() {
-               return ( !$this->hasMemoryPath() && !is_writable( $this->dbPath ) );
+               return ( !$this->hasProcessMemoryPath() && !is_writable( $this->dbPath ) );
        }
 
        /**
         * @return bool
         */
-       private function hasMemoryPath() {
+       private function hasProcessMemoryPath() {
                return ( strpos( $this->dbPath, ':memory:' ) === 0 );
        }
 
@@ -974,17 +967,19 @@ class DatabaseSqlite extends Database {
        }
 
        public function lock( $lockName, $method, $timeout = 5 ) {
-               if ( !is_dir( "{$this->dbDir}/locks" ) ) { // create dir as needed
-                       if ( !is_writable( $this->dbDir ) || !mkdir( "{$this->dbDir}/locks" ) ) {
-                               throw new DBError( $this, "Cannot create directory \"{$this->dbDir}/locks\"." );
-                       }
+               // Give better error message for permission problems than just returning false
+               if (
+                       !is_dir( "{$this->dbDir}/locks" ) &&
+                       ( !is_writable( $this->dbDir ) || !mkdir( "{$this->dbDir}/locks" ) )
+               ) {
+                       throw new DBError( $this, "Cannot create directory \"{$this->dbDir}/locks\"." );
                }
 
                return $this->lockMgr->lock( [ $lockName ], LockManager::LOCK_EX, $timeout )->isOK();
        }
 
        public function unlock( $lockName, $method ) {
-               return $this->lockMgr->unlock( [ $lockName ], LockManager::LOCK_EX )->isOK();
+               return $this->lockMgr->unlock( [ $lockName ], LockManager::LOCK_EX )->isGood();
        }
 
        /**