9 use Wikimedia\TestingAccessWrapper;
19 use MediaWikiCoversValidator;
30 $m = Database::NEW_UNCONNECTED;
31 $p = [
'host' =>
'localhost',
'user' =>
'me',
'password' =>
'myself',
'dbname' =>
'i' ];
39 $x = $p + [
'port' => 10000,
'UseWindowsAuth' =>
false ];
42 $x = $p + [
'dbFilePath' =>
'some/file.sqlite' ];
44 $x = $p + [
'dbDirectory' =>
'some/file' ];
52 [ 1234.5678,
"'1234.5678'" ],
53 [
'string',
"'string'" ],
54 [
'string\'s cause trouble',
"'string\'s cause trouble'" ],
63 $this->assertEquals( $expected, $this->db->addQuotes(
$input ) );
84 [
'dbname' =>
'sharedb',
'schema' =>
null,
'prefix' =>
'' ],
90 [
'dbname' =>
'sharedb',
'schema' =>
null,
'prefix' =>
'' ],
93 'sharedb.sh_tablename',
96 [
'dbname' =>
'sharedb',
'schema' =>
null,
'prefix' =>
'sh_' ],
98 'shared-prefix-raw' => [
99 'sharedb.sh_tablename',
102 [
'dbname' =>
'sharedb',
'schema' =>
null,
'prefix' =>
'sh_' ],
105 'databasename.tablename',
106 'databasename.tablename',
110 'databasename.tablename',
111 'databasename.tablename',
123 $this->db->setTableAliases( [ $table => $alias ] );
127 $this->db->tableName( $table, $format ?:
'quoted' )
133 'one-element array' => [
134 [
'table' ], [],
'table '
137 [
'table1',
'table2' ], [],
'table1,table2 '
140 [
'table1',
'table2' ],
141 [
'table2' => [
'LEFT JOIN',
't1_id = t2_id' ] ],
142 'table1 LEFT JOIN table2 ON ((t1_id = t2_id))'
144 'real join with multiple conditionals' => [
145 [
'table1',
'table2' ],
146 [
'table2' => [
'LEFT JOIN', [
't1_id = t2_id',
't2_x = \'X\'' ] ] ],
147 'table1 LEFT JOIN table2 ON ((t1_id = t2_id) AND (t2_x = \'X\'))'
149 'join with parenthesized group' => [
150 [
'table1',
'n' => [
'table2',
'table3' ] ],
152 'table3' => [
'JOIN',
't2_id = t3_id' ],
153 'n' => [
'LEFT JOIN',
't1_id = t2_id' ],
155 'table1 LEFT JOIN (table2 JOIN table3 ON ((t2_id = t3_id))) ON ((t1_id = t2_id))'
157 'join with degenerate parenthesized group' => [
158 [
'table1',
'n' => [
't2' =>
'table2' ] ],
160 'n' => [
'LEFT JOIN',
't1_id = t2_id' ],
162 'table1 LEFT JOIN table2 t2 ON ((t1_id = t2_id))'
172 $clause = TestingAccessWrapper::newFromObject( $this->db )
173 ->tableNamesWithIndexClauseOrJOIN(
$tables, [], [], $join_conds );
174 $this->assertSame( $expect, $clause );
187 $callback =
function ( $trigger,
IDatabase $db )
use ( &$flagSet, &$called ) {
193 $this->assertTrue( $called,
'Callback reached' );
194 $this->assertFalse( $flagSet,
'DBO_TRX off in callback' );
201 $this->assertFalse( $called,
'Callback not reached during TRX' );
204 $this->assertTrue( $called,
'Callback reached after COMMIT' );
205 $this->assertFalse( $flagSet,
'DBO_TRX off in callback' );
223 $db = $this->
getMockDB( [
'isOpen',
'ping',
'getDBname' ] );
224 $db->method(
'isOpen' )->willReturn(
true );
225 $db->method(
'ping' )->willReturn(
true );
226 $db->method(
'getDBname' )->willReturn(
'' );
229 $lbFactory = LBFactorySingle::newFromConnection(
$db );
232 $lb = $lbFactory->getMainLB();
233 $conn = $lb->openConnection( $lb->getWriterIndex() );
234 $this->assertSame(
$db, $conn,
'Same DB instance' );
239 $callback =
function ()
use (
$db, &$flagSet, &$called ) {
245 $this->assertTrue( $called,
'Called when idle if DBO_TRX is set' );
246 $this->assertFalse( $flagSet,
'DBO_TRX off in callback' );
250 $lbFactory->beginMasterChanges( __METHOD__ );
252 $this->assertFalse( $called,
'Not called when lb-transaction is active' );
254 $lbFactory->commitMasterChanges( __METHOD__ );
255 $this->assertTrue( $called,
'Called when lb-transaction is committed' );
258 $lbFactory->beginMasterChanges( __METHOD__ );
260 $this->assertFalse( $called,
'Not called when lb-transaction is active' );
262 $lbFactory->rollbackMasterChanges( __METHOD__ );
263 $this->assertFalse( $called,
'Not called when lb-transaction is rolled back' );
265 $lbFactory->commitMasterChanges( __METHOD__ );
266 $this->assertFalse( $called,
'Not called in next round commit' );
271 throw new RuntimeException(
'test' );
273 $this->fail(
"Exception not thrown" );
274 }
catch ( RuntimeException
$e ) {
285 $db->method(
'isOpen' )->willReturn(
true );
297 $this->assertTrue( $called,
'Called when idle' );
307 $this->assertFalse( $called,
'Not called when transaction is active' );
309 $this->assertTrue( $called,
'Called when transaction is committed' );
317 $db = $this->
getMockDB( [
'isOpen',
'ping',
'getDBname' ] );
318 $db->method(
'isOpen' )->willReturn(
true );
319 $db->method(
'ping' )->willReturn(
true );
320 $db->method(
'getDBname' )->willReturn(
'unittest' );
323 $lbFactory = LBFactorySingle::newFromConnection(
$db );
326 $lb = $lbFactory->getMainLB();
327 $conn = $lb->openConnection( $lb->getWriterIndex() );
328 $this->assertSame(
$db, $conn,
'Same DB instance' );
330 $this->assertFalse( $lb->hasMasterChanges() );
337 $this->assertTrue( $called,
'Called when idle if DBO_TRX is set' );
339 $lbFactory->commitMasterChanges();
340 $this->assertFalse( $called );
343 $lbFactory->beginMasterChanges( __METHOD__ );
345 $this->assertFalse( $called,
'Not called when lb-transaction is active' );
346 $lbFactory->commitMasterChanges( __METHOD__ );
347 $this->assertTrue( $called,
'Called when lb-transaction is committed' );
350 $lbFactory->beginMasterChanges( __METHOD__ );
352 $this->assertFalse( $called,
'Not called when lb-transaction is active' );
354 $lbFactory->rollbackMasterChanges( __METHOD__ );
355 $this->assertFalse( $called,
'Not called when lb-transaction is rolled back' );
357 $lbFactory->commitMasterChanges( __METHOD__ );
358 $this->assertFalse( $called,
'Not called in next round commit' );
377 $this->assertTrue( $called,
'Callback reached' );
388 $this->assertTrue( $called,
'Callback reached' );
404 $this->assertTrue( $called,
'Callback reached' );
409 $this->assertTrue( $called,
'Callback still reached' );
414 $this->assertTrue( $called,
'Callback reached' );
420 $this->assertFalse( $called,
'Callback not reached' );
433 static $abstractMethods = [
434 'fetchAffectedRowCount',
438 'fetchObject',
'fetchRow',
439 'fieldInfo',
'fieldName',
440 'getSoftwareLink',
'getServerVersion',
444 'lastError',
'lastErrno',
445 'numFields',
'numRows',
451 ->disableOriginalConstructor()
452 ->setMethods( array_values( array_unique( array_merge(
457 $wdb = TestingAccessWrapper::newFromObject(
$db );
459 $wdb->connLogger = new \Psr\Log\NullLogger();
460 $wdb->queryLogger = new \Psr\Log\NullLogger();
461 $wdb->currentDomain = DatabaseDomain::newUnspecified();
470 $db->method(
'isOpen' )->willReturn(
true );
476 $db->
query(
'SELECT 1', __METHOD__ );
477 $this->assertTrue( (
bool)
$db->
trxLevel(),
"Transaction started." );
481 $this->assertFalse( (
bool)
$db->
trxLevel(),
"Transaction cleared." );
492 $db->method(
'isOpen' )->willReturn(
true );
493 $db->method(
'getDBname' )->willReturn(
'unittest' );
496 $this->assertEquals(
true,
$db->
lockIsFree(
'x', __METHOD__ ) );
497 $this->assertEquals(
true,
$db->
lock(
'x', __METHOD__ ) );
498 $this->assertEquals(
false,
$db->
lockIsFree(
'x', __METHOD__ ) );
499 $this->assertEquals(
true,
$db->
unlock(
'x', __METHOD__ ) );
500 $this->assertEquals(
true,
$db->
lockIsFree(
'x', __METHOD__ ) );
504 $this->assertEquals(
true,
$db->
lockIsFree(
'x', __METHOD__ ) );
505 $this->assertEquals(
true,
$db->
lock(
'x', __METHOD__ ) );
506 $this->assertEquals(
false,
$db->
lockIsFree(
'x', __METHOD__ ) );
507 $this->assertEquals(
true,
$db->
unlock(
'x', __METHOD__ ) );
508 $this->assertEquals(
true,
$db->
lockIsFree(
'x', __METHOD__ ) );
515 $db->
query(
"DELETE FROM test WHERE t = 1" );
518 $this->fail(
"Exception not reached" );
520 $this->assertEquals( 1,
$db->
trxLevel(),
"Transaction not committed." );
521 $this->assertTrue(
$db->
lockIsFree(
'meow', __METHOD__ ),
'Lock not acquired' );
523 $db->
rollback( __METHOD__, IDatabase::FLUSHING_ALL_PEERS );
529 $db->
query(
"DELETE FROM test WHERE t = 1" );
532 $this->fail(
"Exception not reached" );
534 $this->assertEquals( 1,
$db->
trxLevel(),
"Transaction not committed." );
535 $this->assertTrue(
$db->
lockIsFree(
'meow2', __METHOD__ ),
'Lock not acquired' );
542 $db->
query(
"SELECT 1", __METHOD__ );
546 $this->assertFalse(
$db->
lockIsFree(
'wuff', __METHOD__ ),
'Lock already acquired' );
547 $db->
rollback( __METHOD__, IDatabase::FLUSHING_ALL_PEERS );
555 $this->fail(
"Exception not reached" );
557 $this->assertEquals( 1,
$db->
trxLevel(),
"Transaction not committed." );
558 $this->assertFalse(
$db->
lockIsFree(
'wuff2', __METHOD__ ),
'Lock not acquired' );
609 ->disableOriginalConstructor()
622 ->disableOriginalConstructor()
634 $ud = DatabaseDomain::newUnspecified();
636 $this->assertEquals( $ud->getId(), $this->db->getDomainID() );
638 $old = $this->db->tablePrefix();
639 $oldDomain = $this->db->getDomainId();
640 $this->assertInternalType(
'string', $old,
'Prefix is string' );
641 $this->assertSame( $old, $this->db->tablePrefix(),
"Prefix unchanged" );
642 $this->assertSame( $old, $this->db->tablePrefix(
'xxx_' ) );
643 $this->assertSame(
'xxx_', $this->db->tablePrefix(),
"Prefix set" );
644 $this->db->tablePrefix( $old );
645 $this->assertNotEquals(
'xxx_', $this->db->tablePrefix() );
646 $this->assertSame( $oldDomain, $this->db->getDomainId() );
648 $old = $this->db->dbSchema();
649 $oldDomain = $this->db->getDomainId();
650 $this->assertInternalType(
'string', $old,
'Schema is string' );
651 $this->assertSame( $old, $this->db->dbSchema(),
"Schema unchanged" );
653 $this->db->selectDB(
'y' );
654 $this->assertSame( $old, $this->db->dbSchema(
'xxx' ) );
655 $this->assertSame(
'xxx', $this->db->dbSchema(),
"Schema set" );
656 $this->db->dbSchema( $old );
657 $this->assertNotEquals(
'xxx', $this->db->dbSchema() );
658 $this->assertSame(
"y", $this->db->getDomainId() );
667 $ud = DatabaseDomain::newUnspecified();
669 $this->assertEquals( $ud->getId(), $this->db->getDomainID() );
670 $this->assertSame(
'', $this->db->dbSchema() );
672 $this->db->dbSchema(
'xxx' );
679 $oldDomain = $this->db->getDomainId();
680 $oldDatabase = $this->db->getDBname();
681 $oldSchema = $this->db->dbSchema();
682 $oldPrefix = $this->db->tablePrefix();
684 $this->db->selectDomain(
'testselectdb-xxx_' );
685 $this->assertSame(
'testselectdb', $this->db->getDBname() );
686 $this->assertSame(
'', $this->db->dbSchema() );
687 $this->assertSame(
'xxx_', $this->db->tablePrefix() );
689 $this->db->selectDomain( $oldDomain );
690 $this->assertSame( $oldDatabase, $this->db->getDBname() );
691 $this->assertSame( $oldSchema, $this->db->dbSchema() );
692 $this->assertSame( $oldPrefix, $this->db->tablePrefix() );
693 $this->assertSame( $oldDomain, $this->db->getDomainId() );
695 $this->db->selectDomain(
'testselectdb-schema-xxx_' );
696 $this->assertSame(
'testselectdb', $this->db->getDBname() );
697 $this->assertSame(
'schema', $this->db->dbSchema() );
698 $this->assertSame(
'xxx_', $this->db->tablePrefix() );
700 $this->db->selectDomain( $oldDomain );
701 $this->assertSame( $oldDatabase, $this->db->getDBname() );
702 $this->assertSame( $oldSchema, $this->db->dbSchema() );
703 $this->assertSame( $oldPrefix, $this->db->tablePrefix() );
704 $this->assertSame( $oldDomain, $this->db->getDomainId() );