protected $lockMgr;
/** @var array List of shared database already attached to this connection */
- private $alreadyAttached = [];
+ private $sessionAttachedDbs = [];
/** @var string[] See https://www.sqlite.org/lang_transaction.html */
private static $VALID_TRX_MODES = [ '', 'DEFERRED', 'IMMEDIATE', 'EXCLUSIVE' ];
if ( in_array( $sync, [ 'EXTRA', 'FULL', 'NORMAL', 'OFF' ], true ) ) {
$this->query( "PRAGMA synchronous = $sync", __METHOD__, $flags );
}
+ $this->attachDatabasesFromTableAliases();
} catch ( Exception $e ) {
throw $this->newExceptionAfterConnectError( $e->getMessage() );
}
return in_array( 'UNIQUE', $options );
}
- /**
- * Filter the options used in SELECT statements
- *
- * @param array $options
- * @return array
- */
- function makeSelectOptions( $options ) {
+ protected function makeSelectOptions( array $options ) {
+ // Remove problematic options that the base implementation converts to SQL
foreach ( $options as $k => $v ) {
- if ( is_numeric( $k ) && ( $v == 'FOR UPDATE' || $v == 'LOCK IN SHARE MODE' ) ) {
+ if ( is_numeric( $k ) && ( $v === 'FOR UPDATE' || $v === 'LOCK IN SHARE MODE' ) ) {
$options[$k] = '';
}
}
public function setTableAliases( array $aliases ) {
parent::setTableAliases( $aliases );
+ if ( $this->isOpen() ) {
+ $this->attachDatabasesFromTableAliases();
+ }
+ }
+
+ /**
+ * Issue ATTATCH statements for all unattached foreign DBs in table aliases
+ */
+ private function attachDatabasesFromTableAliases() {
foreach ( $this->tableAliases as $params ) {
- if ( isset( $this->alreadyAttached[$params['dbname']] ) ) {
- continue;
+ if (
+ $params['dbname'] !== $this->getDBname() &&
+ !isset( $this->sessionAttachedDbs[$params['dbname']] )
+ ) {
+ $this->attachDatabase( $params['dbname'] );
+ $this->sessionAttachedDbs[$params['dbname']] = true;
}
- $this->attachDatabase( $params['dbname'] );
- $this->alreadyAttached[$params['dbname']] = true;
}
}
return true;
}
+ protected function doHandleSessionLossPreconnect() {
+ $this->sessionAttachedDbs = [];
+ }
+
/**
* @return PDO
*/