namespace Wikimedia\Rdbms;
use Exception;
+use RuntimeException;
use stdClass;
use Wikimedia\AtEase\AtEase;
return $statementOnly;
}
+ public function serverIsReadOnly() {
+ $encDatabase = $this->addQuotes( $this->getDBname() );
+ $res = $this->query(
+ "SELECT IS_READ_ONLY FROM SYS.DATABASES WHERE NAME = $encDatabase",
+ __METHOD__
+ );
+ $row = $this->fetchObject( $res );
+
+ return $row ? (bool)$row->IS_READ_ONLY : false;
+ }
+
/**
* @return int
*/
$this->query( 'ROLLBACK TRANSACTION ' . $this->addIdentifierQuotes( $identifier ), $fname );
}
- /**
- * Begin a transaction, committing any previously open transaction
- * @param string $fname
- */
protected function doBegin( $fname = __METHOD__ ) {
- sqlsrv_begin_transaction( $this->conn );
- $this->trxLevel = 1;
+ if ( !sqlsrv_begin_transaction( $this->conn ) ) {
+ $this->reportQueryError( $this->lastError(), $this->lastErrno(), 'BEGIN', $fname );
+ }
}
/**
* @param string $fname
*/
protected function doCommit( $fname = __METHOD__ ) {
- sqlsrv_commit( $this->conn );
- $this->trxLevel = 0;
+ if ( !sqlsrv_commit( $this->conn ) ) {
+ $this->reportQueryError( $this->lastError(), $this->lastErrno(), 'COMMIT', $fname );
+ }
}
/**
* @param string $fname
*/
protected function doRollback( $fname = __METHOD__ ) {
- sqlsrv_rollback( $this->conn );
- $this->trxLevel = 0;
+ if ( !sqlsrv_rollback( $this->conn ) ) {
+ $this->queryLogger->error(
+ "{fname}\t{db_server}\t{errno}\t{error}\t",
+ $this->getLogContext( [
+ 'errno' => $this->lastErrno(),
+ 'error' => $this->lastError(),
+ 'fname' => $fname,
+ 'trace' => ( new RuntimeException() )->getTraceAsString()
+ ] )
+ );
+ }
}
/**
throw new DBExpectedError( $this, __CLASS__ . ": domain schemas are not supported." );
}
- $fileName = self::generateFileName( $this->dbDir, $dbName );
- if ( !is_readable( $fileName ) ) {
- $error = "SQLite database file not readable";
- $this->connLogger->error(
- "Error connecting to {db_server}: {error}",
- $this->getLogContext( [ 'method' => __METHOD__, 'error' => $error ] )
- );
- throw new DBConnectionError( $this, $error );
- }
-
// Only $dbName is used, the other parameters are irrelevant for SQLite databases
- $this->openFile( $fileName, $dbName, $tablePrefix );
+ $this->openFile( self::generateFileName( $this->dbDir, $dbName ), $dbName, $tablePrefix );
}
/**
* @throws DBConnectionError
*/
protected function openFile( $fileName, $dbName, $tablePrefix ) {
+ if ( !$this->hasMemoryPath() && !is_readable( $fileName ) ) {
+ $error = "SQLite database file not readable";
+ $this->connLogger->error(
+ "Error connecting to {db_server}: {error}",
+ $this->getLogContext( [ 'method' => __METHOD__, 'error' => $error ] )
+ );
+ throw new DBConnectionError( $this, $error );
+ }
+
$this->dbPath = $fileName;
try {
$this->conn = new PDO(
return false;
}
+ public function serverIsReadOnly() {
+ return ( !$this->hasMemoryPath() && !is_writable( $this->dbPath ) );
+ }
+
+ /**
+ * @return bool
+ */
+ private function hasMemoryPath() {
+ return ( strpos( $this->dbPath, ':memory:' ) === 0 );
+ }
+
/**
* @return string Wikitext of a link to the server software's web site
*/
} else {
$this->query( 'BEGIN', $fname );
}
- $this->trxLevel = 1;
}
/**