use Wikimedia\TestingAccessWrapper;
use Wikimedia\Rdbms\DBTransactionStateError;
use Wikimedia\Rdbms\DBUnexpectedError;
+use Wikimedia\Rdbms\DBTransactionError;
/**
* Test the parts of the Database abstract class that deal
// phpcs:ignore Generic.Files.LineLength
$this->assertLastSql( 'BEGIN; SAVEPOINT wikimedia_rdbms_atomic1; ROLLBACK TO SAVEPOINT wikimedia_rdbms_atomic1; COMMIT' );
- $this->database->doAtomicSection( __METHOD__, function () {
- } );
+ $noOpCallack = function () {
+ };
+
+ $this->database->doAtomicSection( __METHOD__, $noOpCallack, IDatabase::ATOMIC_CANCELABLE );
+ $this->assertLastSql( 'BEGIN; COMMIT' );
+
+ $this->database->doAtomicSection( __METHOD__, $noOpCallack );
$this->assertLastSql( 'BEGIN; COMMIT' );
$this->database->begin( __METHOD__ );
- $this->database->doAtomicSection( __METHOD__, function () {
- } );
+ $this->database->doAtomicSection( __METHOD__, $noOpCallack, IDatabase::ATOMIC_CANCELABLE );
$this->database->rollback( __METHOD__ );
// phpcs:ignore Generic.Files.LineLength
$this->assertLastSql( 'BEGIN; SAVEPOINT wikimedia_rdbms_atomic1; RELEASE SAVEPOINT wikimedia_rdbms_atomic1; ROLLBACK' );
$this->database->begin( __METHOD__ );
try {
- $this->database->doAtomicSection( __METHOD__, function () {
- throw new RuntimeException( 'Test exception' );
- } );
+ $this->database->doAtomicSection(
+ __METHOD__,
+ function () {
+ $this->database->startAtomic( 'inner_func1' );
+ $this->database->startAtomic( 'inner_func2' );
+
+ throw new RuntimeException( 'Test exception' );
+ },
+ IDatabase::ATOMIC_CANCELABLE
+ );
$this->fail( 'Expected exception not thrown' );
} catch ( RuntimeException $ex ) {
$this->assertSame( 'Test exception', $ex->getMessage() );
$this->database->commit( __METHOD__ );
// phpcs:ignore Generic.Files.LineLength
$this->assertLastSql( 'BEGIN; SAVEPOINT wikimedia_rdbms_atomic1; ROLLBACK TO SAVEPOINT wikimedia_rdbms_atomic1; COMMIT' );
+
+ $this->database->begin( __METHOD__ );
+ try {
+ $this->database->doAtomicSection(
+ __METHOD__,
+ function () {
+ throw new RuntimeException( 'Test exception' );
+ }
+ );
+ $this->fail( 'Test exception not thrown' );
+ } catch ( RuntimeException $ex ) {
+ $this->assertSame( 'Test exception', $ex->getMessage() );
+ }
+ $this->database->rollback( __METHOD__ );
+ $this->assertLastSql( 'BEGIN; ROLLBACK' );
}
public static function provideAtomicSectionMethodsForErrors() {
$this->fail( 'Expected exception not thrown' );
} catch ( DBUnexpectedError $ex ) {
$this->assertSame(
- 'No atomic transaction is open (got ' . __METHOD__ . ').',
+ 'No atomic section is open (got ' . __METHOD__ . ').',
$ex->getMessage()
);
}
$this->fail( 'Expected exception not thrown' );
} catch ( DBUnexpectedError $ex ) {
$this->assertSame(
- 'Invalid atomic section ended (got ' . __METHOD__ . ').',
+ 'Invalid atomic section ended (got ' . __METHOD__ . ' but expected ' .
+ __METHOD__ . 'X' . ').',
$ex->getMessage()
);
}
$this->database->startAtomic( __METHOD__ );
try {
$this->database->cancelAtomic( __METHOD__ );
+ $this->database->select( 'test', '1', [], __METHOD__ );
$this->fail( 'Expected exception not thrown' );
- } catch ( DBUnexpectedError $ex ) {
+ } catch ( DBTransactionError $ex ) {
$this->assertSame(
- 'Uncancelable atomic section canceled (got ' . __METHOD__ . ').',
+ 'Cannot execute query from ' . __METHOD__ . ' while transaction status is ERROR.',
$ex->getMessage()
);
}