TYPO3 CMS  TYPO3_8-7
DatabaseConnectionTest.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
19 
23 class DatabaseConnectionTest extends \TYPO3\TestingFramework\Core\Functional\FunctionalTestCase
24 {
28  protected $subject = null;
29 
33  protected $testTable = 'test_database_connection';
34 
38  protected $testField = 'test_field';
39 
43  protected $anotherTestField = 'another_test_field';
44 
48  protected function setUp()
49  {
50  parent::setUp();
51  Bootstrap::getInstance()->initializeTypo3DbGlobal();
52  $this->subject = $GLOBALS['TYPO3_DB'];
53  $this->subject->sql_query(
54  "CREATE TABLE {$this->testTable} (" .
55  ' id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,' .
56  " {$this->testField} MEDIUMBLOB," .
57  " {$this->anotherTestField} MEDIUMBLOB," .
58  ' PRIMARY KEY (id)' .
59  ') ENGINE=MyISAM DEFAULT CHARSET=utf8;'
60  );
61  }
62 
66  protected function tearDown()
67  {
68  $this->subject->sql_query("DROP TABLE {$this->testTable};");
69  unset($this->subject);
70  }
71 
78  public function selectDbReturnsTrue()
79  {
80  $this->assertTrue($this->subject->sql_select_db());
81  }
82 
89  public function selectDbReturnsFalse()
90  {
91  $this->expectException(\RuntimeException::class);
92  $this->expectExceptionCode(1270853883);
93  $this->expectExceptionMessage('TYPO3 Fatal Error: Cannot connect to the current database, "Foo"!');
94 
95  $this->subject->setDatabaseName('Foo');
96  $this->assertFalse($this->subject->sql_select_db());
97  }
98 
106  {
107  $this->subject->exec_INSERTquery($this->testTable, [$this->testField => 'test']);
108  $this->assertEquals(1, $this->subject->sql_affected_rows());
109  }
110 
117  public function sqlInsertIdReturnsCorrectId()
118  {
119  $this->subject->exec_INSERTquery($this->testTable, [$this->testField => 'test']);
120  $this->assertEquals(1, $this->subject->sql_insert_id());
121  }
122 
129  public function noSqlError()
130  {
131  $this->subject->exec_INSERTquery($this->testTable, [$this->testField => 'test']);
132  $this->assertEquals('', $this->subject->sql_error());
133  }
134 
142  {
143  $this->subject->exec_INSERTquery($this->testTable, ['test' => 'test']);
144  $this->assertEquals('Unknown column \'test\' in \'field list\'', $this->subject->sql_error());
145  }
146 
153  public function noSqlErrorCode()
154  {
155  $this->subject->exec_INSERTquery($this->testTable, [$this->testField => 'test']);
156  $this->assertEquals(0, $this->subject->sql_errno());
157  }
158 
166  {
167  $this->subject->exec_INSERTquery($this->testTable, ['test' => 'test']);
168  $this->assertEquals(1054, $this->subject->sql_errno());
169  }
170 
178  {
179  $this->assertInstanceOf('mysqli', $this->subject->sql_pconnect());
180  }
181 
188  public function connectDbThrowsExeptionsWhenNoDatabaseIsGiven()
189  {
190  $this->expectException(\RuntimeException::class);
191  $this->expectExceptionCode(1270853882);
192 
194  $subject = $this->getAccessibleMock(DatabaseConnection::class, ['dummy'], [], '', false);
195  $subject->connectDB();
196  }
197 
205  {
206  $this->subject->connectDB();
207  $this->assertTrue($this->subject->isConnected());
208  }
209 
217  {
218  $this->assertTrue($this->subject->isConnected());
219  $env = getenv('typo3DatabaseHost');
220  $databaseHost = is_string($env) ? trim($env) : '127.0.0.1';
221  $this->subject->setDatabaseHost($databaseHost);
222  $this->assertFalse($this->subject->isConnected());
223  }
224 
233  {
234  return [
235  'NULL string with ReturnNull is allowed' => [
236  [null, true],
237  'NULL',
238  ],
239  'NULL string with ReturnNull is false' => [
240  [null, false],
241  "''",
242  ],
243  'Normal string' => [
244  ['Foo', false],
245  "'Foo'",
246  ],
247  'Single quoted string' => [
248  ["'Hello'", false],
249  "'\\'Hello\\''",
250  ],
251  'Double quoted string' => [
252  ['"Hello"', false],
253  "'\\\"Hello\\\"'",
254  ],
255  'String with internal single tick' => [
256  ['It\'s me', false],
257  "'It\\'s me'",
258  ],
259  'Slashes' => [
260  ['/var/log/syslog.log', false],
261  "'/var/log/syslog.log'",
262  ],
263  'Backslashes' => [
264  ['\\var\\log\\syslog.log', false],
265  "'\\\\var\\\\log\\\\syslog.log'",
266  ],
267  ];
268  }
269 
280  public function fullQuoteStrReturnsQuotedString($values, $expectedResult)
281  {
283  $quotedStr = $this->subject->fullQuoteStr($values[0], 'tt_content', $values[1]);
284  $this->assertEquals($expectedResult, $quotedStr);
285  }
286 
295  {
296  return [
297  'NULL array with ReturnNull is allowed' => [
298  [
299  [null, null],
300  false,
301  true,
302  ],
303  ['NULL', 'NULL'],
304  ],
305 
306  'NULL array with ReturnNull is false' => [
307  [
308  [null, null],
309  false,
310  false,
311  ],
312  ["''", "''"],
313  ],
314 
315  'Strings in array' => [
316  [
317  ['Foo', 'Bar'],
318  false,
319  false,
320  ],
321  ["'Foo'", "'Bar'"],
322  ],
323 
324  'Single quotes in array' => [
325  [
326  ["'Hello'"],
327  false,
328  false,
329  ],
330  ["'\\'Hello\\''"],
331  ],
332 
333  'Double quotes in array' => [
334  [
335  ['"Hello"'],
336  false,
337  false,
338  ],
339  ["'\\\"Hello\\\"'"],
340  ],
341 
342  'Slashes in array' => [
343  [
344  ['/var/log/syslog.log'],
345  false,
346  false,
347  ],
348  ["'/var/log/syslog.log'"],
349  ],
350 
351  'Backslashes in array' => [
352  [
353  ['\var\log\syslog.log'],
354  false,
355  false,
356  ],
357  ["'\\\\var\\\\log\\\\syslog.log'"],
358  ],
359 
360  'Strings with internal single tick' => [
361  [
362  ['Hey!', 'It\'s me'],
363  false,
364  false,
365  ],
366  ["'Hey!'", "'It\\'s me'"],
367  ],
368 
369  'no quotes strings from array' => [
370  [
371  [
372  'First' => 'Hey!',
373  'Second' => 'It\'s me',
374  'Third' => 'O\' Reily',
375  ],
376  ['First', 'Third'],
377  false,
378  ],
379  ['First' => 'Hey!', 'Second' => "'It\\'s me'", 'Third' => "O' Reily"],
380  ],
381 
382  'no quotes strings from string' => [
383  [
384  [
385  'First' => 'Hey!',
386  'Second' => 'It\'s me',
387  'Third' => 'O\' Reily',
388  ],
389  'First,Third',
390  false,
391  ],
392  ['First' => 'Hey!', 'Second' => "'It\\'s me'", 'Third' => "O' Reily"],
393  ],
394  ];
395  }
396 
407  public function fullQuoteArrayQuotesArray($values, $expectedResult)
408  {
409  $quotedResult = $this->subject->fullQuoteArray($values[0], $this->testTable, $values[1], $values[2]);
410  $this->assertSame($expectedResult, $quotedResult);
411  }
412 
421  {
422  return [
423  'Double Quotes' => [
424  '"Hello"',
425  '\\"Hello\\"'
426  ],
427  'Single Quotes' => [
428  '\'Hello\'',
429  "\\'Hello\\'"
430  ],
431  'Slashes' => [
432  '/var/log/syslog.log',
433  '/var/log/syslog.log'
434  ],
435  'Literal Backslashes' => [
436  '\\var\\log\\syslog.log',
437  '\\\\var\\\\log\\\\syslog.log'
438  ],
439  'Fallback Literal Backslashes' => [
440  '\var\log\syslog.log',
441  '\\\\var\\\\log\\\\syslog.log'
442  ],
443  ];
444  }
445 
456  public function quoteStrQuotesDoubleQuotesCorrectly($string, $expectedResult)
457  {
458  $quotedString = $this->subject->quoteStr($string, $this->testTable);
459  $this->assertSame($expectedResult, $quotedString);
460  }
461 
469  {
470  $this->assertTrue(
471  $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('foo')")
472  );
473  }
474 
482  {
483  $this->assertTrue(
484  $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('foo')")
485  );
486  $id = $this->subject->sql_insert_id();
487  $this->assertTrue(
488  $this->subject->admin_query("UPDATE {$this->testTable} SET {$this->testField}='bar' WHERE id={$id}")
489  );
490  }
491 
499  {
500  $this->assertTrue(
501  $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('foo')")
502  );
503  $id = $this->subject->sql_insert_id();
504  $this->assertTrue($this->subject->admin_query("DELETE FROM {$this->testTable} WHERE id={$id}"));
505  }
506 
514  {
515  $this->assertTrue(
516  $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('foo')")
517  );
518  $res = $this->subject->admin_query("SELECT {$this->testField} FROM {$this->testTable}");
519  $this->assertInstanceOf('mysqli_result', $res);
520  $result = $res->fetch_assoc();
521  $this->assertEquals('foo', $result[$this->testField]);
522  }
523 
530  public function adminGetCharsetsReturnsArrayWithCharsets()
531  {
532  $columnsRes = $this->subject->admin_query('SHOW CHARACTER SET');
533  $result = $this->subject->admin_get_charsets();
534  $this->assertEquals(count($result), $columnsRes->num_rows);
535 
537  while (($row = $columnsRes->fetch_assoc())) {
538  $this->assertArrayHasKey($row['Charset'], $result);
539  }
540  }
541 
549  {
550  $result = $this->subject->admin_get_keys($this->testTable);
551  $this->assertEquals('id', $result[0]['Column_name']);
552  }
553 
561  {
562  $result = $this->subject->admin_get_fields($this->testTable);
563  $this->assertArrayHasKey('id', $result);
564  $this->assertArrayHasKey($this->testField, $result);
565  }
566 
574  {
575  $result = $this->subject->admin_get_tables();
576  $this->assertArrayHasKey('tt_content', $result);
577  $this->assertArrayHasKey('pages', $result);
578  }
579 
587  {
589  $databases = $this->subject->admin_query('SELECT SCHEMA_NAME FROM information_schema.SCHEMATA');
590  $result = $this->subject->admin_get_dbs();
591  $this->assertSame(count($result), $databases->num_rows);
592 
593  $i = 0;
594  while ($database = $databases->fetch_assoc()) {
595  $this->assertSame($database['SCHEMA_NAME'], $result[$i]);
596  $i++;
597  }
598  }
599 
608  {
609  $sql1 = "SELECT * FROM {$this->testTable} WHERE {$this->testField}='baz'";
610  $sql2 = "SELECT * FROM {$this->testTable} WHERE {$this->testField}='baz' OR {$this->testField}='bar'";
611  $sql3 = "SELECT * FROM {$this->testTable} WHERE {$this->testField} IN ('baz', 'bar', 'foo')";
612 
613  return [
614  'One result' => [$sql1, 1],
615  'Two results' => [$sql2, 2],
616  'Three results' => [$sql3, 3],
617  ];
618  }
619 
630  public function sqlNumRowsReturnsCorrectAmountOfRows($sql, $expectedResult)
631  {
632  $this->assertTrue(
633  $this->subject->admin_query(
634  "INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('foo'), ('bar'), ('baz')"
635  )
636  );
637 
638  $res = $this->subject->admin_query($sql);
639  $numRows = $this->subject->sql_num_rows($res);
640  $this->assertSame($expectedResult, $numRows);
641  }
642 
649  public function sqlNumRowsReturnsFalse()
650  {
651  $res = $this->subject->admin_query("SELECT * FROM {$this->testTable} WHERE test='baz'");
652  $numRows = $this->subject->sql_num_rows($res);
653  $this->assertFalse($numRows);
654  }
655 
659  protected function prepareTableForFetchTests()
660  {
661  $this->assertTrue(
662  $this->subject->sql_query(
663  "ALTER TABLE {$this->testTable} " .
664  'ADD name mediumblob, ' .
665  'ADD deleted int, ' .
666  'ADD street varchar(100), ' .
667  'ADD city varchar(50), ' .
668  'ADD country varchar(100)'
669  )
670  );
671 
672  $this->assertTrue(
673  $this->subject->admin_query(
674  "INSERT INTO {$this->testTable} (name,street,city,country,deleted) VALUES " .
675  "('Mr. Smith','Oakland Road','Los Angeles','USA',0)," .
676  "('Ms. Smith','Oakland Road','Los Angeles','USA',0)," .
677  "('Alice im Wunderland','Große Straße','Königreich der Herzen','Wunderland',0)," .
678  "('Agent Smith','Unbekannt','Unbekannt','Matrix',1)"
679  )
680  );
681  }
682 
690  {
691  $this->prepareTableForFetchTests();
692 
693  $res = $this->subject->admin_query("SELECT * FROM {$this->testTable} ORDER BY id");
694  $expectedResult = [
695  [
696  'id' => '1',
697  $this->testField => null,
698  $this->anotherTestField => null,
699  'name' => 'Mr. Smith',
700  'deleted' => '0',
701  'street' => 'Oakland Road',
702  'city' => 'Los Angeles',
703  'country' => 'USA',
704  ],
705  [
706  'id' => '2',
707  $this->testField => null,
708  $this->anotherTestField => null,
709  'name' => 'Ms. Smith',
710  'deleted' => '0',
711  'street' => 'Oakland Road',
712  'city' => 'Los Angeles',
713  'country' => 'USA',
714  ],
715  [
716  'id' => '3',
717  $this->testField => null,
718  $this->anotherTestField => null,
719  'name' => 'Alice im Wunderland',
720  'deleted' => '0',
721  'street' => 'Große Straße',
722  'city' => 'Königreich der Herzen',
723  'country' => 'Wunderland',
724  ],
725  [
726  'id' => '4',
727  $this->testField => null,
728  $this->anotherTestField => null,
729  'name' => 'Agent Smith',
730  'deleted' => '1',
731  'street' => 'Unbekannt',
732  'city' => 'Unbekannt',
733  'country' => 'Matrix',
734  ],
735  ];
736  $i = 0;
737  while ($row = $this->subject->sql_fetch_assoc($res)) {
738  $this->assertSame($expectedResult[$i], $row);
739  $i++;
740  }
741  }
742 
750  {
751  $this->prepareTableForFetchTests();
752  $res = $this->subject->admin_query("SELECT * FROM {$this->testTable} ORDER BY id");
753  $expectedResult = [
754  ['1', null, null, 'Mr. Smith', '0', 'Oakland Road', 'Los Angeles', 'USA'],
755  ['2', null, null, 'Ms. Smith', '0', 'Oakland Road', 'Los Angeles', 'USA'],
756  ['3', null, null, 'Alice im Wunderland', '0', 'Große Straße', 'Königreich der Herzen', 'Wunderland'],
757  ['4', null, null, 'Agent Smith', '1', 'Unbekannt', 'Unbekannt', 'Matrix'],
758  ];
759  $i = 0;
760  while ($row = $this->subject->sql_fetch_row($res)) {
761  $this->assertSame($expectedResult[$i], $row);
762  $i++;
763  }
764  }
765 
773  {
774  $this->assertTrue(
775  $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('baz')")
776  );
777  $res = $this->subject->admin_query("SELECT * FROM {$this->testTable} WHERE {$this->testField}=baz");
778  $this->assertFalse($this->subject->sql_free_result($res));
779  }
780 
788  {
789  $this->assertTrue(
790  $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('baz')")
791  );
792  $res = $this->subject->admin_query("SELECT * FROM {$this->testTable} WHERE {$this->testField}='baz'");
793  $this->assertTrue($this->subject->sql_free_result($res));
794  }
795 }
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']