ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
ilDatabaseImplementationBaseTest.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2009 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +-----------------------------------------------------------------------------+
22 */
23 
31 
32  const INDEX_NAME = 'i1';
33  const TABLE_NAME = 'il_ut_en';
34  const CREATE_TABLE_ARRAY_KEY = 'create table';
38  protected $error_reporting_backup = 0;
42  protected $backupGlobals = false;
46  protected $db;
50  protected $mock;
54  protected $outputs;
58  protected $ildb_backup;
62  protected $type = '';
66  protected $ini_file = '/var/www/ilias/data/trunk/client.ini.php';
70  protected $set_up = false;
71 
72 
73  protected function setUp() {
74  if ($this->set_up) {
75  return;
76  }
77  // echo phpversion() . "\n";
78  $this->error_reporting_backup = error_reporting();
79  error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_WARNING & ~E_STRICT); // Due to PEAR Lib MDB2
80 
81  PHPUnit_Framework_Error_Notice::$enabled = false;
82  PHPUnit_Framework_Error_Deprecated::$enabled = false;
83 
84  require_once('./libs/composer/vendor/autoload.php');
85  if (!defined('DEVMODE')) {
86  define('DEVMODE', true);
87  }
88  require_once('./Services/Database/classes/class.ilDBWrapperFactory.php');
89  $this->db = $this->getDBInstance();
90  global $DIC, $ilDB;
91  $DIC['ilDB'] = $this->db;
92  $ilDB = $this->db;
93  $this->connect($this->db);
94 
95  switch ($this->type) {
96  default:
97  require_once('./Services/Database/test/Implementations/data/MySQL/class.ilDatabaseMySQLTestMockData.php');
98  require_once('./Services/Database/test/Implementations/data/MySQL/class.ilDatabaseMySQLTestsDataOutputs.php');
99  $this->mock = new ilDatabaseMySQLTestMockData();
100  $this->outputs = new ilDatabaseMySQLTestsDataOutputs();
101  break;
104  require_once('./Services/Database/test/Implementations/data/Postgres/class.ilDatabasePostgresTestMockData.php');
105  require_once('./Services/Database/test/Implementations/data/Postgres/class.ilDatabasePostgresTestsDataOutputs.php');
106  $this->mock = new ilDatabasePostgresTestMockData();
107  $this->outputs = new ilDatabasePostgresTestsDataOutputs();
108  break;
109  }
110  $this->set_up = true;
111  }
112 
113 
117  protected function getIniFile() {
118  return $this->ini_file;
119  }
120 
121 
126  protected final function connect(ilDBInterface $ilDBInterface, $missing_ini = false) {
127  require_once('./Services/Init/classes/class.ilIniFile.php');
128  require_once('./Services/Init/classes/class.ilErrorHandling.php');
129  $ilClientIniFile = new ilIniFile($this->getIniFile());
130  $ilClientIniFile->read();
131  $this->type = $ilClientIniFile->readVariable("db", "type");
132  if ($missing_ini) {
133  $ilClientIniFile = new ilIniFile('');
134  }
135  $ilDBInterface->initFromIniFile($ilClientIniFile);
136  $return = $ilDBInterface->connect($missing_ini);
137 
138  return $return;
139  }
140 
141 
145  protected function getTableName() {
146  return strtolower(self::TABLE_NAME . '_' . $this->db->getDBType());
147  }
148 
149 
150  protected function tearDown() {
151  $this->db = null;
152  $this->mock = null;
153  $this->outputs = null;
154  $this->type = null;
155  $this->set_up = false;
156  error_reporting($this->error_reporting_backup);
157  }
158 
159 
164  abstract protected function getDBInstance();
165 
166 
170  public function testInstance() {
171  $this->assertTrue($this->db instanceof ilDBInterface);
172  }
173 
174 
175  public function testConnection() {
176  // $this->assertFalse($this->connect($this->getDBInstance(), true)); // Currently MDB2 Postgres doesn't check if connections possible
177  $this->assertTrue($this->connect($this->getDBInstance()));
178  if ($this->db->supportsEngineMigration()) {
179  // $this->db->migrateAllTablesToEngine($this->db->getStorageEngine());
180  }
181  }
182 
183 
184  public function testCompareCreateTableQueries() {
188  $manager = $this->db->loadModule(ilDBConstants::MODULE_MANAGER);
189  $query = $manager->getTableCreationQuery($this->getTableName(), $this->mock->getDBFields(), array());
190  $this->assertEquals($this->outputs->getCreationQueryBuildByILIAS($this->getTableName()), $this->normalizeSQL($query));
191  }
192 
193 
197  public function testCreateDatabase() {
198  $fields = $this->mock->getDBFields();
199  $this->db->createTable($this->getTableName(), $fields, true);
200  $this->db->addPrimaryKey($this->getTableName(), array( 'id' ));
201  $this->assertTrue($this->db->tableExists($this->getTableName()));
202 
203  if (in_array($this->type, array( ilDBConstants::TYPE_PDO_POSTGRE, ilDBConstants::TYPE_POSTGRES ))) {
204  return; // SHOW CREATE TABLE CURRENTLY NOT SUPPORTED IN POSTGRES
205  }
206 
207  $res = $this->db->query('SHOW CREATE TABLE ' . $this->getTableName());
208  $data = $this->db->fetchAssoc($res);
209 
210  $data = array_change_key_case($data, CASE_LOWER);
211 
212  $create_table = $this->normalizeSQL($data[self::CREATE_TABLE_ARRAY_KEY]);
213  $create_table_mock = $this->normalizeSQL($this->mock->getTableCreateSQL($this->getTableName(), $this->db->getStorageEngine()));
214 
215  $this->assertEquals($create_table_mock, $create_table);
216  }
217 
218 
222  public function testInsertNative() {
223  $values = $this->mock->getInputArray(false, false);
224  $id = $values['id'][1];
225 
226  // PDO
227  $this->db->insert($this->getTableName(), $values);
228  $this->db->setLimit(1);
229  $res_pdo = $this->db->query("SELECT * FROM " . $this->getTableName() . " WHERE id = $id");
230  $data_pdo = $this->db->fetchAssoc($res_pdo);
231  $this->assertEquals(ilDatabaseCommonTestsDataOutputs::$output_after_native_input, $data_pdo);
232  }
233 
234 
235  public function testQueryUtils() {
236  $this->assertEquals($this->mock->getLike(), $this->db->like('column', 'text', 22));
237 
238  $this->assertEquals($this->mock->getNow(), $this->db->now());
239 
240  $this->assertEquals($this->mock->getLocate(), $this->db->locate('needle', 'mystring', 5));
241 
242  $this->assertEquals($this->mock->getConcat(false), $this->db->concat(array( 'one', 'two', 'three' ), false));
243 
244  $this->assertEquals($this->mock->getConcat(true), $this->db->concat(array( 'one', 'two', 'three' ), true));
245  }
246 
247 
251  public function testUpdateNative() {
252  // With / without clob
253  $with_clob = $this->mock->getInputArray(2222, true);
254  $without_clob = $this->mock->getInputArray(2222, true, false);
255  $id = $with_clob['id'][1];
256 
257  // PDO
258  $this->db->update($this->getTableName(), $with_clob, array( 'id' => array( 'integer', $id ) ));
259  $this->db->setLimit(1, 0);
260  $res_pdo = $this->db->query("SELECT * FROM " . $this->getTableName() . " WHERE id = $id ");
261  $data_pdo = $this->db->fetchAssoc($res_pdo);
263 
264  $this->db->update($this->getTableName(), $without_clob, array( 'id' => array( 'integer', $id ) ));
265  $this->db->setLimit(1, 0);
266  $res_pdo = $this->db->query("SELECT * FROM " . $this->getTableName() . " WHERE id = $id ");
267  $data_pdo = $this->db->fetchAssoc($res_pdo);
269  }
270 
271 
275  public function testInsertSQL() {
276  // PDO
277  $this->db->manipulate($this->mock->getInsertQuery($this->getTableName()));
278  $this->db->setLimit(1, 0);
279  $res_pdo = $this->db->query("SELECT * FROM " . $this->getTableName() . " WHERE id = 58");
280  $data_pdo = $this->db->fetchObject($res_pdo);
281 
282  $this->assertEquals((object)ilDatabaseCommonTestsDataOutputs::$insert_sql_output, $data_pdo);
283  }
284 
285 
290  public function testSelectUsrData() {
292 
293  $query = 'SELECT usr_id, login, is_self_registered FROM usr_data WHERE usr_id = 6';
294  // PDO
295  $this->db->setLimit(1, 0);
296  $result = $this->db->query($query);
297  $data = $this->db->fetchObject($result);
298  $this->assertEquals($output, $data);
299 
300  $result = $this->db->queryF('SELECT usr_id, login, is_self_registered FROM usr_data WHERE usr_id = %s', array( ilDBPdoFieldDefinition::T_INTEGER ), array( 6 ));
301  $this->db->setLimit(1, 0);
302  $data = $this->db->fetchObject($result);
303  $this->assertEquals($output, $data);
304 
305  $query = 'SELECT usr_id, login, is_self_registered FROM usr_data WHERE ' . $this->db->in('usr_id', array( 6, 13 ), false, 'integer');
306  $this->db->setLimit(2, 0);
307  $result = $this->db->query($query);
308  $data = $this->db->fetchAll($result);
310  $this->assertTrue(in_array($item, $data));
311  }
312 
313  $this->assertEquals(2, $this->db->numRows($result));
314  }
315 
316 
320  public function testIndices() {
321  // Add index
322  $this->db->addIndex($this->getTableName(), array( 'init_mob_id' ), self::INDEX_NAME);
323  $this->assertTrue($this->db->indexExistsByFields($this->getTableName(), array( 'init_mob_id' )));
324 
325  // Drop index
326  $this->db->dropIndex($this->getTableName(), self::INDEX_NAME);
327  $this->assertFalse($this->db->indexExistsByFields($this->getTableName(), array( 'init_mob_id' )));
328 
329  // FullText
330  $this->db->addIndex($this->getTableName(), array( 'address' ), 'i2', true);
331  if ($this->db->supportsFulltext()) {
332  $this->assertTrue($this->db->indexExistsByFields($this->getTableName(), array( 'address' )));
333  } else {
334  $this->assertFalse($this->db->indexExistsByFields($this->getTableName(), array( 'address' )));
335  }
336 
337  // Drop By Fields
338  $this->db->addIndex($this->getTableName(), array( 'elevation' ), 'i3');
339  $this->assertTrue($this->db->indexExistsByFields($this->getTableName(), array( 'elevation' )));
340 
341  $this->db->dropIndexByFields($this->getTableName(), array( 'elevation' ));
342  $this->assertFalse($this->db->indexExistsByFields($this->getTableName(), array( 'elevation' )));
343  }
344 
345 
349  public function testTableColums() {
350  $this->assertTrue($this->db->tableColumnExists($this->getTableName(), 'init_mob_id'));
351 
352  $this->db->addTableColumn($this->getTableName(), "export", array( "type" => "text", "length" => 1024 ));
353  $this->assertTrue($this->db->tableColumnExists($this->getTableName(), 'export'));
354 
355  $this->db->dropTableColumn($this->getTableName(), "export");
356  $this->assertFalse($this->db->tableColumnExists($this->getTableName(), 'export'));
357  }
358 
359 
363  public function testSequences() {
364  if ($this->db->sequenceExists($this->getTableName())) {
365  $this->db->dropSequence($this->getTableName());
366  }
367  $this->db->createSequence($this->getTableName(), 10);
368  $this->assertEquals(10, $this->db->nextId($this->getTableName()));
369  $this->assertEquals(11, $this->db->nextId($this->getTableName()));
370  }
371 
372 
376  public function testReverse() {
380  $reverse = $this->db->loadModule(ilDBConstants::MODULE_REVERSE);
381 
382  // getTableFieldDefinition
383  $this->assertEquals($this->outputs->getTableFieldDefinition(), $reverse->getTableFieldDefinition($this->getTableName(), 'comment_mob_id'));
384 
385  // getTableIndexDefinition
386  $this->db->addIndex($this->getTableName(), array( 'init_mob_id' ), self::INDEX_NAME);
387  $tableIndexDefinition = $reverse->getTableIndexDefinition($this->getTableName(), $this->db->constraintName($this->getTableName(), self::INDEX_NAME));
388  $this->assertEquals(ilDatabaseCommonTestsDataOutputs::$table_index_definition_output, $tableIndexDefinition);
389  $this->db->dropIndex($this->getTableName(), self::INDEX_NAME);
390 
391  // getTableConstraintDefinition
392  $this->assertEquals(ilDatabaseCommonTestsDataOutputs::$table_constraint_definition_output, $reverse->getTableConstraintDefinition($this->getTableName(), $this->db->constraintName($this->getTableName(), strtolower($this->db->getPrimaryKeyIdentifier()))));
393  }
394 
395 
399  public function testManager() {
403  $manager = $this->db->loadModule(ilDBConstants::MODULE_MANAGER);
404 
405  // table fields
406  $this->assertEquals($this->outputs->getTableFields(), $manager->listTableFields($this->getTableName()));
407 
408  // constraints
409  $this->assertEquals($this->outputs->getTableConstraints($this->getTableName()), $manager->listTableConstraints($this->getTableName()));
410 
411  // Indices
412  $this->db->dropIndexByFields($this->getTableName(), array( 'init_mob_id' ));
413  $this->db->addIndex($this->getTableName(), array( 'init_mob_id' ), self::INDEX_NAME);
414  $this->assertEquals($this->outputs->getNativeTableIndices($this->getTableName(), $this->db->supportsFulltext()), $manager->listTableIndexes($this->getTableName()));
415 
416  // listTables
417  $list_tables_output = $this->outputs->getListTables($this->getTableName());
418  sort($list_tables_output);
419  $list_tables_native = $manager->listTables();
420  sort($list_tables_native);
421  $this->assertEquals($list_tables_output, $list_tables_native);
422 
423  // listSequences
424  $table_sequences_output = $this->outputs->getTableSequences($this->getTableName());
425  $this->assertTrue(count(array_diff($table_sequences_output, $manager->listSequences())) < 3);
426  }
427 
428 
432  public function testDBAnalyser() {
433  require_once('./Services/Database/classes/class.ilDBAnalyzer.php');
434  $analyzer = new ilDBAnalyzer($this->db);
435 
436  // Field info
437  // $this->assertEquals(ilDatabaseCommonTestsDataOutputs::$analyzer_field_info, $analyzer_pdo->getFieldInformation($this->getTableName())); // FSX
438 
439  // getBestDefinitionAlternative
440  $def = $this->db->loadModule(ilDBConstants::MODULE_REVERSE)->getTableFieldDefinition($this->getTableName(), 'comment_mob_id');
441  $this->assertEquals(0, $analyzer->getBestDefinitionAlternative($def)); // FSX
442 
443  // getAutoIncrementField
444  $this->assertEquals(false, $analyzer->getAutoIncrementField($this->getTableName()));
445 
446  // getPrimaryKeyInformation
447  $this->assertEquals($this->outputs->getPrimaryInfo($this->getTableName()), $analyzer->getPrimaryKeyInformation($this->getTableName()));
448 
449  // getIndicesInformation
450  if ($this->db->supportsFulltext()) {
451  $this->assertEquals($this->outputs->getIndexInfo(true, $this->getTableName()), $analyzer->getIndicesInformation($this->getTableName()));
452  } else {
453  $this->assertEquals($this->outputs->getIndexInfo(false, $this->getTableName()), $analyzer->getIndicesInformation($this->getTableName()));
454  }
455 
456  // getConstraintsInformation
457  $this->assertEquals(array(), $analyzer->getConstraintsInformation($this->getTableName())); // TODO
458 
459  // hasSequence
460  $this->assertEquals(59, $analyzer->hasSequence($this->getTableName()));
461  }
462 
463 
467  public function testDropSequence() {
468  $this->assertTrue($this->db->sequenceExists($this->getTableName()));
469  if ($this->db->sequenceExists($this->getTableName())) {
470  $this->db->dropSequence($this->getTableName());
471  }
472  $this->assertFalse($this->db->sequenceExists($this->getTableName()));
473  }
474 
475 
476  public function testConstraints() {
477 
478  }
479 
480 
484  public function testChangeTableName() {
485  $this->db->dropTable($this->getTableName() . '_a', false);
486  $this->db->renameTable($this->getTableName(), $this->getTableName() . '_a');
487  $this->assertTrue($this->db->tableExists($this->getTableName() . '_a'));
488  $this->db->renameTable($this->getTableName() . '_a', $this->getTableName());
489  }
490 
491 
495  public function testRenameTableColumn() {
496  $this->changeGlobal($this->db);
497 
498  $this->db->renameTableColumn($this->getTableName(), 'comment_mob_id', 'comment_mob_id_altered');
499  if (in_array($this->type, array( ilDBConstants::TYPE_PDO_POSTGRE, ilDBConstants::TYPE_POSTGRES ))) {
500  return; // SHOW CREATE TABLE CURRENTLY NOT SUPPORTED IN POSTGRES
501  }
502  $res = $this->db->query('SHOW CREATE TABLE ' . $this->getTableName());
503  $data = $this->db->fetchAssoc($res);
504  $data = array_change_key_case($data, CASE_LOWER);
505 
506  $this->assertEquals($this->normalizeSQL($this->mock->getTableCreateSQLAfterRename($this->getTableName(), $this->db->getStorageEngine(), $this->db->supportsFulltext())), $this->normalizeSQL($data[self::CREATE_TABLE_ARRAY_KEY]));
507 
508  $this->changeBack();
509  }
510 
511 
515  public function testModifyTableColumn() {
516  $changes = array(
517  "type" => "text",
518  "length" => 250,
519  "notnull" => false,
520  'fixed' => false,
521  );
522 
523  $this->changeGlobal($this->db);
524 
525  $this->db->modifyTableColumn($this->getTableName(), 'comment_mob_id_altered', $changes);
526  if (in_array($this->type, array( ilDBConstants::TYPE_PDO_POSTGRE, ilDBConstants::TYPE_POSTGRES ))) {
527  return; // SHOW CREATE TABLE CURRENTLY NOT SUPPORTED IN POSTGRES
528  }
529  $res = $this->db->query('SHOW CREATE TABLE ' . $this->getTableName());
530  $data = $this->db->fetchAssoc($res);
531 
532  $data = array_change_key_case($data, CASE_LOWER);
533 
534  $this->changeBack();
535 
536  $this->assertEquals($this->normalizeSQL($this->mock->getTableCreateSQLAfterAlter($this->getTableName(), $this->db->getStorageEngine(), $this->db->supportsFulltext())), $this->normalizeSQL($data[self::CREATE_TABLE_ARRAY_KEY]));
537  }
538 
539 
543  public function testLockTables() {
544  $locks = array(
545  0 => array( 'name' => 'usr_data', 'type' => ilDBConstants::LOCK_WRITE ),
546  // 1 => array( 'name' => 'object_data', 'type' => ilDBConstants::LOCK_READ ),
547  );
548 
549  $this->db->lockTables($locks);
550  $this->db->manipulate('DELETE FROM usr_data WHERE usr_id = -1');
551  $this->db->unlockTables();
552  }
553 
554 
558  public function testTransactions() {
559  // PDO
560  // $this->db->beginTransaction();
561  // $this->db->insert($this->getTableName(), $this->mock->getInputArrayForTransaction());
562  // $this->db->rollback();
563  // $st = $this->db->query('SELECT * FROM ' . $this->getTableName() . ' WHERE id = ' . $this->db->quote(123456, 'integer'));
564  // $this->assertEquals(0, $this->db->numRows($st));
565  }
566 
567 
571  public function testDropTable() {
572  $this->db->dropTable($this->getTableName());
573  $this->assertTrue(!$this->db->tableExists($this->getTableName()));
574  }
575 
576  //
577  // HELPERS
578  //
579 
583  protected function changeGlobal(ilDBInterface $ilDBInterface) {
584  global $ilDB;
585  $this->ildb_backup = $ilDB;
586  $ilDB = $ilDBInterface;
587  }
588 
589 
590  protected function changeBack() {
591  global $ilDB;
592  $ilDB = $this->ildb_backup;
593  }
594 
595 
600  protected function normalizeSQL($sql) {
601  return preg_replace('/[ \t]+/', ' ', preg_replace('/\s*$^\s*/m', " ", preg_replace("/\n/", "", preg_replace("/`/", "", $sql))));
602  }
603 
604 
609  protected function normalizetableName($sql) {
610  return preg_replace("/" . $this->getTableName() . "|" . $this->getTableName() . "/", "table_name_replaced", $sql);
611  }
612 }
initFromIniFile($tmpClientIniFile=null)
$result
TestCase for the ilDatabaseCommonTest.
connect($return_false_on_error=false)
Class ilDatabaseCommonTestMockData.
connect(ilDBInterface $ilDBInterface, $missing_ini=false)
testInstance()
Test instance implements ilDBInterface and is ilDBInnoDB.
Interface ilDBInterface.
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\+" &#(? foreach( $entity_files as $file) $output
Class ilDatabaseCommonTestMockData.
Create styles array
The data for the language used.
Class ilDatabaseCommonTestsDataOutputs.
Create new PHPExcel object
obj_idprivate
global $ilDB
global $DIC
This class gives all kind of DB information using the MDB2 manager and reverse module.
defined( 'APPLICATION_ENV')||define( 'APPLICATION_ENV'
Definition: bootstrap.php:27
INIFile Parser.