From: Ryan Schmidt Date: Tue, 2 Jan 2018 17:56:32 +0000 (-0600) Subject: Fix $wgSharedDB with sqlite X-Git-Tag: 1.31.0-rc.0~759^2 X-Git-Url: http://git.cyclocoop.org/%24image?a=commitdiff_plain;h=50aa07938510c1a2e58c62123bb0286dd7560d5a;p=lhc%2Fweb%2Fwiklou.git Fix $wgSharedDB with sqlite At the time of the constructor, tableAliases will always be an empty array. As such, the ATTACH command is never run for shared dbs, and we get query errors when later trying to reference them. This changes it so that the shared db is attached whenever the table aliases are finally set. Since table aliases may be set multiple times, the list of already attached dbs was moved into class scope so that subsequent calls to set the aliases do not result in query errors. Bug: T181962 Change-Id: Ia654e996f54077bc3749b884a528e121ab25a2d2 --- diff --git a/includes/libs/rdbms/database/DatabaseSqlite.php b/includes/libs/rdbms/database/DatabaseSqlite.php index 2b0660707c..3bdcd65671 100644 --- a/includes/libs/rdbms/database/DatabaseSqlite.php +++ b/includes/libs/rdbms/database/DatabaseSqlite.php @@ -56,6 +56,9 @@ class DatabaseSqlite extends Database { /** @var FSLockManager (hopefully on the same server as the DB) */ protected $lockMgr; + /** @var array List of shared database already attached to this connection */ + private $alreadyAttached = []; + /** * Additional params include: * - dbDirectory : directory containing the DB and the lock file directory @@ -82,16 +85,7 @@ class DatabaseSqlite extends Database { parent::__construct( $p ); // Super doesn't open when $user is false, but we can work with $dbName if ( $p['dbname'] && !$this->isOpen() ) { - if ( $this->open( $p['host'], $p['user'], $p['password'], $p['dbname'] ) ) { - $done = []; - foreach ( $this->tableAliases as $params ) { - if ( isset( $done[$params['dbname']] ) ) { - continue; - } - $this->attachDatabase( $params['dbname'] ); - $done[$params['dbname']] = 1; - } - } + $this->open( $p['host'], $p['user'], $p['password'], $p['dbname'] ); } } @@ -302,6 +296,14 @@ class DatabaseSqlite extends Database { return parent::isWriteQuery( $sql ) && !preg_match( '/^(ATTACH|PRAGMA)\b/i', $sql ); } + protected function isTransactableQuery( $sql ) { + return parent::isTransactableQuery( $sql ) && !in_array( + $this->getQueryVerb( $sql ), + [ 'ATTACH', 'PRAGMA' ], + true + ); + } + /** * SQLite doesn't allow buffered results or data seeking etc, so we'll use fetchAll as the result * @@ -1033,6 +1035,17 @@ class DatabaseSqlite extends Database { return $this->query( $sql, $fName ); } + public function setTableAliases( array $aliases ) { + parent::setTableAliases( $aliases ); + foreach ( $this->tableAliases as $params ) { + if ( isset( $this->alreadyAttached[$params['dbname']] ) ) { + continue; + } + $this->attachDatabase( $params['dbname'] ); + $this->alreadyAttached[$params['dbname']] = true; + } + } + protected function requiresDatabaseUser() { return false; // just a file }