TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
Functional/Database/DatabaseConnectionTest.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Functional\Database;
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 
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 
50  protected function setUp()
51  {
52  parent::setUp();
53  $this->subject = $GLOBALS['TYPO3_DB'];
54  $this->subject->sql_query(
55  "CREATE TABLE {$this->testTable} (" .
56  ' id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,' .
57  " {$this->testField} MEDIUMBLOB," .
58  " {$this->anotherTestField} MEDIUMBLOB," .
59  ' PRIMARY KEY (id)' .
60  ') ENGINE=MyISAM DEFAULT CHARSET=utf8;'
61  );
62  }
63 
69  protected function tearDown()
70  {
71  $this->subject->sql_query("DROP TABLE {$this->testTable};");
72  unset($this->subject);
73  }
74 
80  public function selectDbReturnsTrue()
81  {
82  $this->assertTrue($this->subject->sql_select_db());
83  }
84 
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 
105  {
106  $this->subject->exec_INSERTquery($this->testTable, [$this->testField => 'test']);
107  $this->assertEquals(1, $this->subject->sql_affected_rows());
108  }
109 
115  public function sqlInsertIdReturnsCorrectId()
116  {
117  $this->subject->exec_INSERTquery($this->testTable, [$this->testField => 'test']);
118  $this->assertEquals(1, $this->subject->sql_insert_id());
119  }
120 
126  public function noSqlError()
127  {
128  $this->subject->exec_INSERTquery($this->testTable, [$this->testField => 'test']);
129  $this->assertEquals('', $this->subject->sql_error());
130  }
131 
138  {
139  $this->subject->exec_INSERTquery($this->testTable, ['test' => 'test']);
140  $this->assertEquals('Unknown column \'test\' in \'field list\'', $this->subject->sql_error());
141  }
142 
148  public function noSqlErrorCode()
149  {
150  $this->subject->exec_INSERTquery($this->testTable, [$this->testField => 'test']);
151  $this->assertEquals(0, $this->subject->sql_errno());
152  }
153 
160  {
161  $this->subject->exec_INSERTquery($this->testTable, ['test' => 'test']);
162  $this->assertEquals(1054, $this->subject->sql_errno());
163  }
164 
169  {
170  $this->assertInstanceOf('mysqli', $this->subject->sql_pconnect());
171  }
172 
176  public function connectDbThrowsExeptionsWhenNoDatabaseIsGiven()
177  {
178  $this->expectException(\RuntimeException::class);
179  $this->expectExceptionCode(1270853882);
180 
182  $subject = $this->getAccessibleMock(DatabaseConnection::class, ['dummy'], [], '', false);
183  $subject->connectDB();
184  }
185 
192  {
193  $this->subject->connectDB();
194  $this->assertTrue($this->subject->isConnected());
195  }
196 
203  {
204  $this->assertTrue($this->subject->isConnected());
205  $this->subject->setDatabaseHost('127.0.0.1');
206  $this->assertFalse($this->subject->isConnected());
207  }
208 
217  {
218  return [
219  'NULL string with ReturnNull is allowed' => [
220  [null, true],
221  'NULL',
222  ],
223  'NULL string with ReturnNull is false' => [
224  [null, false],
225  "''",
226  ],
227  'Normal string' => [
228  ['Foo', false],
229  "'Foo'",
230  ],
231  'Single quoted string' => [
232  ["'Hello'", false],
233  "'\\'Hello\\''",
234  ],
235  'Double quoted string' => [
236  ['"Hello"', false],
237  "'\\\"Hello\\\"'",
238  ],
239  'String with internal single tick' => [
240  ['It\'s me', false],
241  "'It\\'s me'",
242  ],
243  'Slashes' => [
244  ['/var/log/syslog.log', false],
245  "'/var/log/syslog.log'",
246  ],
247  'Backslashes' => [
248  ['\\var\\log\\syslog.log', false],
249  "'\\\\var\\\\log\\\\syslog.log'",
250  ],
251  ];
252  }
253 
263  public function fullQuoteStrReturnsQuotedString($values, $expectedResult)
264  {
266  $quotedStr = $this->subject->fullQuoteStr($values[0], 'tt_content', $values[1]);
267  $this->assertEquals($expectedResult, $quotedStr);
268  }
269 
278  {
279  return [
280  'NULL array with ReturnNull is allowed' => [
281  [
282  [null, null],
283  false,
284  true,
285  ],
286  ['NULL', 'NULL'],
287  ],
288 
289  'NULL array with ReturnNull is false' => [
290  [
291  [null, null],
292  false,
293  false,
294  ],
295  ["''", "''"],
296  ],
297 
298  'Strings in array' => [
299  [
300  ['Foo', 'Bar'],
301  false,
302  false,
303  ],
304  ["'Foo'", "'Bar'"],
305  ],
306 
307  'Single quotes in array' => [
308  [
309  ["'Hello'"],
310  false,
311  false,
312  ],
313  ["'\\'Hello\\''"],
314  ],
315 
316  'Double quotes in array' => [
317  [
318  ['"Hello"'],
319  false,
320  false,
321  ],
322  ["'\\\"Hello\\\"'"],
323  ],
324 
325  'Slashes in array' => [
326  [
327  ['/var/log/syslog.log'],
328  false,
329  false,
330  ],
331  ["'/var/log/syslog.log'"],
332  ],
333 
334  'Backslashes in array' => [
335  [
336  ['\var\log\syslog.log'],
337  false,
338  false,
339  ],
340  ["'\\\\var\\\\log\\\\syslog.log'"],
341  ],
342 
343  'Strings with internal single tick' => [
344  [
345  ['Hey!', 'It\'s me'],
346  false,
347  false,
348  ],
349  ["'Hey!'", "'It\\'s me'"],
350  ],
351 
352  'no quotes strings from array' => [
353  [
354  [
355  'First' => 'Hey!',
356  'Second' => 'It\'s me',
357  'Third' => 'O\' Reily',
358  ],
359  ['First', 'Third'],
360  false,
361  ],
362  ['First' => 'Hey!', 'Second' => "'It\\'s me'", 'Third' => "O' Reily"],
363  ],
364 
365  'no quotes strings from string' => [
366  [
367  [
368  'First' => 'Hey!',
369  'Second' => 'It\'s me',
370  'Third' => 'O\' Reily',
371  ],
372  'First,Third',
373  false,
374  ],
375  ['First' => 'Hey!', 'Second' => "'It\\'s me'", 'Third' => "O' Reily"],
376  ],
377  ];
378  }
379 
389  public function fullQuoteArrayQuotesArray($values, $expectedResult)
390  {
391  $quotedResult = $this->subject->fullQuoteArray($values[0], $this->testTable, $values[1], $values[2]);
392  $this->assertSame($expectedResult, $quotedResult);
393  }
394 
403  {
404  return [
405  'Double Quotes' => [
406  '"Hello"',
407  '\\"Hello\\"'
408  ],
409  'Single Quotes' => [
410  '\'Hello\'',
411  "\\'Hello\\'"
412  ],
413  'Slashes' => [
414  '/var/log/syslog.log',
415  '/var/log/syslog.log'
416  ],
417  'Literal Backslashes' => [
418  '\\var\\log\\syslog.log',
419  '\\\\var\\\\log\\\\syslog.log'
420  ],
421  'Fallback Literal Backslashes' => [
422  '\var\log\syslog.log',
423  '\\\\var\\\\log\\\\syslog.log'
424  ],
425  ];
426  }
427 
437  public function quoteStrQuotesDoubleQuotesCorrectly($string, $expectedResult)
438  {
439  $quotedString = $this->subject->quoteStr($string, $this->testTable);
440  $this->assertSame($expectedResult, $quotedString);
441  }
442 
449  {
450  $this->assertTrue(
451  $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('foo')")
452  );
453  }
454 
461  {
462  $this->assertTrue(
463  $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('foo')")
464  );
465  $id = $this->subject->sql_insert_id();
466  $this->assertTrue(
467  $this->subject->admin_query("UPDATE {$this->testTable} SET {$this->testField}='bar' WHERE id={$id}")
468  );
469  }
470 
477  {
478  $this->assertTrue(
479  $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('foo')")
480  );
481  $id = $this->subject->sql_insert_id();
482  $this->assertTrue($this->subject->admin_query("DELETE FROM {$this->testTable} WHERE id={$id}"));
483  }
484 
491  {
492  $this->assertTrue(
493  $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('foo')")
494  );
495  $res = $this->subject->admin_query("SELECT {$this->testField} FROM {$this->testTable}");
496  $this->assertInstanceOf('mysqli_result', $res);
497  $result = $res->fetch_assoc();
498  $this->assertEquals('foo', $result[$this->testField]);
499  }
500 
506  public function adminGetCharsetsReturnsArrayWithCharsets()
507  {
508  $columnsRes = $this->subject->admin_query('SHOW CHARACTER SET');
509  $result = $this->subject->admin_get_charsets();
510  $this->assertEquals(count($result), $columnsRes->num_rows);
511 
513  while (($row = $columnsRes->fetch_assoc())) {
514  $this->assertArrayHasKey($row['Charset'], $result);
515  }
516  }
517 
524  {
525  $result = $this->subject->admin_get_keys($this->testTable);
526  $this->assertEquals('id', $result[0]['Column_name']);
527  }
528 
535  {
536  $result = $this->subject->admin_get_fields($this->testTable);
537  $this->assertArrayHasKey('id', $result);
538  $this->assertArrayHasKey($this->testField, $result);
539  }
540 
547  {
548  $result = $this->subject->admin_get_tables();
549  $this->assertArrayHasKey('tt_content', $result);
550  $this->assertArrayHasKey('pages', $result);
551  }
552 
559  {
561  $databases = $this->subject->admin_query('SELECT SCHEMA_NAME FROM information_schema.SCHEMATA');
562  $result = $this->subject->admin_get_dbs();
563  $this->assertSame(count($result), $databases->num_rows);
564 
565  $i = 0;
566  while ($database = $databases->fetch_assoc()) {
567  $this->assertSame($database['SCHEMA_NAME'], $result[$i]);
568  $i++;
569  }
570  }
571 
580  {
581  $sql1 = "SELECT * FROM {$this->testTable} WHERE {$this->testField}='baz'";
582  $sql2 = "SELECT * FROM {$this->testTable} WHERE {$this->testField}='baz' OR {$this->testField}='bar'";
583  $sql3 = "SELECT * FROM {$this->testTable} WHERE {$this->testField} IN ('baz', 'bar', 'foo')";
584 
585  return [
586  'One result' => [$sql1, 1],
587  'Two results' => [$sql2, 2],
588  'Three results' => [$sql3, 3],
589  ];
590  }
591 
601  public function sqlNumRowsReturnsCorrectAmountOfRows($sql, $expectedResult)
602  {
603  $this->assertTrue(
604  $this->subject->admin_query(
605  "INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('foo'), ('bar'), ('baz')"
606  )
607  );
608 
609  $res = $this->subject->admin_query($sql);
610  $numRows = $this->subject->sql_num_rows($res);
611  $this->assertSame($expectedResult, $numRows);
612  }
613 
619  public function sqlNumRowsReturnsFalse()
620  {
621  $res = $this->subject->admin_query("SELECT * FROM {$this->testTable} WHERE test='baz'");
622  $numRows = $this->subject->sql_num_rows($res);
623  $this->assertFalse($numRows);
624  }
625 
631  protected function prepareTableForFetchTests()
632  {
633  $this->assertTrue(
634  $this->subject->sql_query(
635  "ALTER TABLE {$this->testTable} " .
636  'ADD name mediumblob, ' .
637  'ADD deleted int, ' .
638  'ADD street varchar(100), ' .
639  'ADD city varchar(50), ' .
640  'ADD country varchar(100)'
641  )
642  );
643 
644  $this->assertTrue(
645  $this->subject->admin_query(
646  "INSERT INTO {$this->testTable} (name,street,city,country,deleted) VALUES " .
647  "('Mr. Smith','Oakland Road','Los Angeles','USA',0)," .
648  "('Ms. Smith','Oakland Road','Los Angeles','USA',0)," .
649  "('Alice im Wunderland','Große Straße','Königreich der Herzen','Wunderland',0)," .
650  "('Agent Smith','Unbekannt','Unbekannt','Matrix',1)"
651  )
652  );
653  }
654 
661  {
662  $this->prepareTableForFetchTests();
663 
664  $res = $this->subject->admin_query("SELECT * FROM {$this->testTable} ORDER BY id");
665  $expectedResult = [
666  [
667  'id' => '1',
668  $this->testField => null,
669  $this->anotherTestField => null,
670  'name' => 'Mr. Smith',
671  'deleted' => '0',
672  'street' => 'Oakland Road',
673  'city' => 'Los Angeles',
674  'country' => 'USA',
675  ],
676  [
677  'id' => '2',
678  $this->testField => null,
679  $this->anotherTestField => null,
680  'name' => 'Ms. Smith',
681  'deleted' => '0',
682  'street' => 'Oakland Road',
683  'city' => 'Los Angeles',
684  'country' => 'USA',
685  ],
686  [
687  'id' => '3',
688  $this->testField => null,
689  $this->anotherTestField => null,
690  'name' => 'Alice im Wunderland',
691  'deleted' => '0',
692  'street' => 'Große Straße',
693  'city' => 'Königreich der Herzen',
694  'country' => 'Wunderland',
695  ],
696  [
697  'id' => '4',
698  $this->testField => null,
699  $this->anotherTestField => null,
700  'name' => 'Agent Smith',
701  'deleted' => '1',
702  'street' => 'Unbekannt',
703  'city' => 'Unbekannt',
704  'country' => 'Matrix',
705  ],
706  ];
707  $i = 0;
708  while ($row = $this->subject->sql_fetch_assoc($res)) {
709  $this->assertSame($expectedResult[$i], $row);
710  $i++;
711  }
712  }
713 
720  {
721  $this->prepareTableForFetchTests();
722  $res = $this->subject->admin_query("SELECT * FROM {$this->testTable} ORDER BY id");
723  $expectedResult = [
724  ['1', null, null, 'Mr. Smith', '0', 'Oakland Road', 'Los Angeles', 'USA'],
725  ['2', null, null, 'Ms. Smith', '0', 'Oakland Road', 'Los Angeles', 'USA'],
726  ['3', null, null, 'Alice im Wunderland', '0', 'Große Straße', 'Königreich der Herzen', 'Wunderland'],
727  ['4', null, null, 'Agent Smith', '1', 'Unbekannt', 'Unbekannt', 'Matrix'],
728  ];
729  $i = 0;
730  while ($row = $this->subject->sql_fetch_row($res)) {
731  $this->assertSame($expectedResult[$i], $row);
732  $i++;
733  }
734  }
735 
742  {
743  $this->assertTrue(
744  $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('baz')")
745  );
746  $res = $this->subject->admin_query("SELECT * FROM {$this->testTable} WHERE {$this->testField}=baz");
747  $this->assertFalse($this->subject->sql_free_result($res));
748  }
749 
756  {
757  $this->assertTrue(
758  $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('baz')")
759  );
760  $res = $this->subject->admin_query("SELECT * FROM {$this->testTable} WHERE {$this->testField}='baz'");
761  $this->assertTrue($this->subject->sql_free_result($res));
762  }
763 }
if(TYPO3_MODE=== 'BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
getAccessibleMock($originalClassName, $methods=[], array $arguments=[], $mockClassName= '', $callOriginalConstructor=true, $callOriginalClone=true, $callAutoload=true)