X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2Flibs%2Frdbms%2Fdatabase%2FDatabaseSqlite.php;h=d0d62e9edb84000c21dd3948a51aa1ad555c2aea;hp=01772cf809b273706264a21b690586b0ecd81723;hb=434d5a6321329ec53110faf441fb825c609347ac;hpb=9d1eeb9ded86352b4000a076e30b344baa0d44df diff --git a/includes/libs/rdbms/database/DatabaseSqlite.php b/includes/libs/rdbms/database/DatabaseSqlite.php index 01772cf809..d0d62e9edb 100644 --- a/includes/libs/rdbms/database/DatabaseSqlite.php +++ b/includes/libs/rdbms/database/DatabaseSqlite.php @@ -46,12 +46,12 @@ class DatabaseSqlite extends Database { protected $trxMode; /** @var int The number of rows affected as an integer */ - protected $mAffectedRows; + protected $lastAffectedRowCount; /** @var resource */ - protected $mLastResult; + protected $lastResultHandle; /** @var PDO */ - protected $mConn; + protected $conn; /** @var FSLockManager (hopefully on the same server as the DB) */ protected $lockMgr; @@ -69,24 +69,13 @@ class DatabaseSqlite extends Database { */ function __construct( array $p ) { if ( isset( $p['dbFilePath'] ) ) { - parent::__construct( $p ); - // Standalone .sqlite file mode. - // Super doesn't open when $user is false, but we can work with $dbName, - // which is derived from the file path in this case. - $this->openFile( $p['dbFilePath'] ); - $lockDomain = md5( $p['dbFilePath'] ); - } elseif ( !isset( $p['dbDirectory'] ) ) { - throw new InvalidArgumentException( "Need 'dbDirectory' or 'dbFilePath' parameter." ); - } else { + $this->dbPath = $p['dbFilePath']; + $lockDomain = md5( $this->dbPath ); + } elseif ( isset( $p['dbDirectory'] ) ) { $this->dbDir = $p['dbDirectory']; - $this->mDBname = $p['dbname']; - $lockDomain = $this->mDBname; - // Stock wiki mode using standard file names per DB. - parent::__construct( $p ); - // Super doesn't open when $user is false, but we can work with $dbName - if ( $p['dbname'] && !$this->isOpen() ) { - $this->open( $p['host'], $p['user'], $p['password'], $p['dbname'] ); - } + $lockDomain = $p['dbname']; + } else { + throw new InvalidArgumentException( "Need 'dbDirectory' or 'dbFilePath' parameter." ); } $this->trxMode = isset( $p['trxMode'] ) ? strtoupper( $p['trxMode'] ) : null; @@ -101,6 +90,12 @@ class DatabaseSqlite extends Database { 'domain' => $lockDomain, 'lockDirectory' => "{$this->dbDir}/locks" ] ); + + parent::__construct( $p ); + } + + protected static function getAttributes() { + return [ self::ATTR_DB_LEVEL_LOCKING => true ]; } /** @@ -122,6 +117,28 @@ class DatabaseSqlite extends Database { return $db; } + protected function doInitConnection() { + if ( $this->dbPath !== null ) { + // Standalone .sqlite file mode. + $this->openFile( $this->dbPath ); + } elseif ( $this->dbDir !== null ) { + // Stock wiki mode using standard file names per DB + if ( strlen( $this->connectionParams['dbname'] ) ) { + $this->open( + $this->connectionParams['host'], + $this->connectionParams['user'], + $this->connectionParams['password'], + $this->connectionParams['dbname'] + ); + } else { + // Caller will manually call open() later? + $this->connLogger->debug( __METHOD__ . ': no database opened.' ); + } + } else { + throw new InvalidArgumentException( "Need 'dbDirectory' or 'dbFilePath' parameter." ); + } + } + /** * @return string */ @@ -142,7 +159,7 @@ class DatabaseSqlite extends Database { * NOTE: only $dbName is used, the other parameters are irrelevant for SQLite databases * * @param string $server - * @param string $user + * @param string $user Unused * @param string $pass * @param string $dbName * @@ -153,12 +170,16 @@ class DatabaseSqlite extends Database { $this->close(); $fileName = self::generateFileName( $this->dbDir, $dbName ); if ( !is_readable( $fileName ) ) { - $this->mConn = false; + $this->conn = false; throw new DBConnectionError( $this, "SQLite database not accessible" ); } $this->openFile( $fileName ); - return (bool)$this->mConn; + if ( $this->conn ) { + $this->dbName = $dbName; + } + + return (bool)$this->conn; } /** @@ -173,29 +194,29 @@ class DatabaseSqlite extends Database { $this->dbPath = $fileName; try { - if ( $this->mFlags & self::DBO_PERSISTENT ) { - $this->mConn = new PDO( "sqlite:$fileName", '', '', + if ( $this->flags & self::DBO_PERSISTENT ) { + $this->conn = new PDO( "sqlite:$fileName", '', '', [ PDO::ATTR_PERSISTENT => true ] ); } else { - $this->mConn = new PDO( "sqlite:$fileName", '', '' ); + $this->conn = new PDO( "sqlite:$fileName", '', '' ); } } catch ( PDOException $e ) { $err = $e->getMessage(); } - if ( !$this->mConn ) { + if ( !$this->conn ) { $this->queryLogger->debug( "DB connection error: $err\n" ); throw new DBConnectionError( $this, $err ); } - $this->mOpened = !!$this->mConn; - if ( $this->mOpened ) { + $this->opened = is_object( $this->conn ); + if ( $this->opened ) { # Set error codes only, don't raise exceptions - $this->mConn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT ); + $this->conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT ); # Enforce LIKE to be case sensitive, just like MySQL $this->query( 'PRAGMA case_sensitive_like = 1' ); - return $this->mConn; + return $this->conn; } return false; @@ -218,7 +239,7 @@ class DatabaseSqlite extends Database { * @return bool */ protected function closeConnection() { - $this->mConn = null; + $this->conn = null; return true; } @@ -311,13 +332,13 @@ class DatabaseSqlite extends Database { * @return bool|ResultWrapper */ protected function doQuery( $sql ) { - $res = $this->mConn->query( $sql ); + $res = $this->getBindingHandle()->query( $sql ); if ( $res === false ) { return false; } $r = $res instanceof ResultWrapper ? $res->result : $res; - $this->mAffectedRows = $r->rowCount(); + $this->lastAffectedRowCount = $r->rowCount(); $res = new ResultWrapper( $this, $r->fetchAll() ); return $res; @@ -447,7 +468,7 @@ class DatabaseSqlite extends Database { */ function insertId() { // PDO::lastInsertId yields a string :( - return intval( $this->mConn->lastInsertId() ); + return intval( $this->getBindingHandle()->lastInsertId() ); } /** @@ -472,10 +493,10 @@ class DatabaseSqlite extends Database { * @return string */ function lastError() { - if ( !is_object( $this->mConn ) ) { + if ( !is_object( $this->conn ) ) { return "Cannot return last error, no db connection"; } - $e = $this->mConn->errorInfo(); + $e = $this->conn->errorInfo(); return isset( $e[2] ) ? $e[2] : ''; } @@ -484,10 +505,10 @@ class DatabaseSqlite extends Database { * @return string */ function lastErrno() { - if ( !is_object( $this->mConn ) ) { + if ( !is_object( $this->conn ) ) { return "Cannot return last error, no db connection"; } else { - $info = $this->mConn->errorInfo(); + $info = $this->conn->errorInfo(); return $info[1]; } @@ -497,7 +518,7 @@ class DatabaseSqlite extends Database { * @return int */ protected function fetchAffectedRowCount() { - return $this->mAffectedRows; + return $this->lastAffectedRowCount; } /** @@ -720,7 +741,7 @@ class DatabaseSqlite extends Database { * @return string Version information from the database */ function getServerVersion() { - $ver = $this->mConn->getAttribute( PDO::ATTR_SERVER_VERSION ); + $ver = $this->getBindingHandle()->getAttribute( PDO::ATTR_SERVER_VERSION ); return $ver; } @@ -752,7 +773,7 @@ class DatabaseSqlite extends Database { } else { $this->query( 'BEGIN', $fname ); } - $this->mTrxLevel = 1; + $this->trxLevel = 1; } /** @@ -810,8 +831,17 @@ class DatabaseSqlite extends Database { ); return "x'" . bin2hex( (string)$s ) . "'"; } else { - return $this->mConn->quote( (string)$s ); + return $this->getBindingHandle()->quote( (string)$s ); + } + } + + public function buildSubstring( $input, $startPosition, $length = null ) { + $this->assertBuildSubstringParams( $startPosition, $length ); + $params = [ $input, $startPosition ]; + if ( $length !== null ) { + $params[] = $length; } + return 'SUBSTR(' . implode( ',', $params ) . ')'; } /** @@ -1046,15 +1076,20 @@ class DatabaseSqlite extends Database { } } - protected function requiresDatabaseUser() { - return false; // just a file - } - /** * @return string */ public function __toString() { - return 'SQLite ' . (string)$this->mConn->getAttribute( PDO::ATTR_SERVER_VERSION ); + return is_object( $this->conn ) + ? 'SQLite ' . (string)$this->conn->getAttribute( PDO::ATTR_SERVER_VERSION ) + : '(not connected)'; + } + + /** + * @return PDO + */ + protected function getBindingHandle() { + return parent::getBindingHandle(); } }