<?php
use Wikimedia\Rdbms\IDatabase;
+use Wikimedia\Rdbms\LBFactorySingle;
use Wikimedia\Rdbms\TransactionProfiler;
use Wikimedia\TestingAccessWrapper;
class DatabaseTest extends PHPUnit_Framework_TestCase {
+ use MediaWikiCoversValidator;
+
protected function setUp() {
$this->db = new DatabaseTestHelper( __CLASS__ . '::' . $this->getName() );
}
);
}
+ public function provideTableNamesWithIndexClauseOrJOIN() {
+ return [
+ 'one-element array' => [
+ [ 'table' ], [], 'table '
+ ],
+ 'comma join' => [
+ [ 'table1', 'table2' ], [], 'table1,table2 '
+ ],
+ 'real join' => [
+ [ 'table1', 'table2' ],
+ [ 'table2' => [ 'LEFT JOIN', 't1_id = t2_id' ] ],
+ 'table1 LEFT JOIN table2 ON ((t1_id = t2_id))'
+ ],
+ 'real join with multiple conditionals' => [
+ [ 'table1', 'table2' ],
+ [ 'table2' => [ 'LEFT JOIN', [ 't1_id = t2_id', 't2_x = \'X\'' ] ] ],
+ 'table1 LEFT JOIN table2 ON ((t1_id = t2_id) AND (t2_x = \'X\'))'
+ ],
+ 'join with parenthesized group' => [
+ [ 'table1', 'n' => [ 'table2', 'table3' ] ],
+ [
+ 'table3' => [ 'JOIN', 't2_id = t3_id' ],
+ 'n' => [ 'LEFT JOIN', 't1_id = t2_id' ],
+ ],
+ 'table1 LEFT JOIN (table2 JOIN table3 ON ((t2_id = t3_id))) ON ((t1_id = t2_id))'
+ ],
+ 'join with degenerate parenthesized group' => [
+ [ 'table1', 'n' => [ 't2' => 'table2' ] ],
+ [
+ 'n' => [ 'LEFT JOIN', 't1_id = t2_id' ],
+ ],
+ 'table1 LEFT JOIN table2 t2 ON ((t1_id = t2_id))'
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider provideTableNamesWithIndexClauseOrJOIN
+ * @covers Wikimedia\Rdbms\Database::tableNamesWithIndexClauseOrJOIN
+ */
+ public function testTableNamesWithIndexClauseOrJOIN( $tables, $join_conds, $expect ) {
+ $clause = TestingAccessWrapper::newFromObject( $this->db )
+ ->tableNamesWithIndexClauseOrJOIN( $tables, [], [], $join_conds );
+ $this->assertSame( $expect, $clause );
+ }
+
/**
* @covers Wikimedia\Rdbms\Database::onTransactionIdle
* @covers Wikimedia\Rdbms\Database::runOnTransactionIdleCallbacks
$this->assertFalse( $db->getFlag( DBO_TRX ), 'DBO_TRX restored to default' );
}
+ /**
+ * @covers Wikimedia\Rdbms\Database::onTransactionPreCommitOrIdle
+ * @covers Wikimedia\Rdbms\Database::runOnTransactionPreCommitCallbacks
+ */
+ public function testTransactionPreCommitOrIdle() {
+ $db = $this->getMockDB( [ 'isOpen' ] );
+ $db->method( 'isOpen' )->willReturn( true );
+ $db->clearFlag( DBO_TRX );
+
+ $this->assertFalse( $db->getFlag( DBO_TRX ), 'DBO_TRX is not set' );
+
+ $called = false;
+ $db->onTransactionPreCommitOrIdle(
+ function () use ( &$called ) {
+ $called = true;
+ },
+ __METHOD__
+ );
+ $this->assertTrue( $called, 'Called when idle' );
+
+ $db->begin( __METHOD__ );
+ $called = false;
+ $db->onTransactionPreCommitOrIdle(
+ function () use ( &$called ) {
+ $called = true;
+ },
+ __METHOD__
+ );
+ $this->assertFalse( $called, 'Not called when transaction is active' );
+ $db->commit( __METHOD__ );
+ $this->assertTrue( $called, 'Called when transaction is committed' );
+ }
+
+ /**
+ * @covers Wikimedia\Rdbms\Database::onTransactionPreCommitOrIdle
+ * @covers Wikimedia\Rdbms\Database::runOnTransactionPreCommitCallbacks
+ */
+ public function testTransactionPreCommitOrIdle_TRX() {
+ $db = $this->getMockDB( [ 'isOpen' ] );
+ $db->method( 'isOpen' )->willReturn( true );
+ $db->setFlag( DBO_TRX );
+
+ $lbFactory = LBFactorySingle::newFromConnection( $db );
+ // Ask for the connectin so that LB sets internal state
+ // about this connection being the master connection
+ $lb = $lbFactory->getMainLB();
+ $conn = $lb->openConnection( $lb->getWriterIndex() );
+ $this->assertSame( $db, $conn, 'Same DB instance' );
+ $this->assertTrue( $db->getFlag( DBO_TRX ), 'DBO_TRX is set' );
+
+ $called = false;
+ $db->onTransactionPreCommitOrIdle(
+ function () use ( &$called ) {
+ $called = true;
+ }
+ );
+ $this->assertFalse( $called, 'Not called when idle if DBO_TRX is set' );
+
+ $lbFactory->beginMasterChanges( __METHOD__ );
+ $this->assertFalse( $called, 'Not called when lb-transaction is active' );
+
+ $lbFactory->commitMasterChanges( __METHOD__ );
+ $this->assertTrue( $called, 'Called when lb-transaction is committed' );
+ }
+
/**
* @covers Wikimedia\Rdbms\Database::onTransactionResolution
* @covers Wikimedia\Rdbms\Database::runOnTransactionIdleCallbacks