ILIAS  release_7 Revision v7.30-3-g800a261c036
class.ilDatabasePopulatedObjective.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 2019 Richard Klees <richard.klees@concepts-and-training.de> Extended GPL, see docs/LICENSE */
4 
5 use ILIAS\Setup;
6 
8 {
9  const MIN_NUMBER_OF_ILIAS_TABLES = 200; // educated guess
10 
11  public function getHash() : string
12  {
13  return hash("sha256", implode("-", [
14  self::class,
15  $this->config->getHost(),
16  $this->config->getPort(),
17  $this->config->getDatabase()
18  ]));
19  }
20 
21  public function getLabel() : string
22  {
23  return "The database is populated with ILIAS-tables.";
24  }
25 
26  public function isNotable() : bool
27  {
28  return true;
29  }
30 
31  public function getPreconditions(Setup\Environment $environment) : array
32  {
33  if ($environment->getResource(Setup\Environment::RESOURCE_DATABASE)) {
34  return [];
35  }
36  return [
37  new \ilDatabaseExistsObjective($this->config)
38  ];
39  }
40 
41  public function achieve(Setup\Environment $environment) : Setup\Environment
42  {
47  $db = $environment->getResource(Setup\Environment::RESOURCE_DATABASE);
48  $io = $environment->getResource(Setup\Environment::RESOURCE_ADMIN_INTERACTION);
49 
50  // $this->setDefaultEngine($db); // maybe we could set the default?
51  $default = $this->getDefaultEngine($db);
52 
53  $io->text("Default DB engine is {$default}");
54 
55  switch ($default) {
56  case 'innodb':
57  case 'myisam':
58  $io->text("reading dump file, this may take a while...");
59  $this->readDumpFile($db);
60  break;
61 
62  default:
63  throw new Setup\UnachievableException(
64  "Cannot determine database default engine, must be InnoDB or MyISAM"
65  );
66  }
67 
68  return $environment;
69  }
70 
74  public function isApplicable(Setup\Environment $environment) : bool
75  {
76  $db = $environment->getResource(Setup\Environment::RESOURCE_DATABASE);
77 
78  return !$this->isDatabasePopulated($db);
79  }
80 
81  protected function isDatabasePopulated(ilDBInterface $db) : bool
82  {
83  $probe_tables = ['usr_data', 'object_data', 'object_reference'];
84  $number_of_probe_tables = count($probe_tables);
85  $tables = $db->listTables();
86  $number_of_tables = count($tables);
87 
88  return
89  $number_of_tables > self::MIN_NUMBER_OF_ILIAS_TABLES
90  && count(array_intersect($tables, $probe_tables)) == $number_of_probe_tables;
91  }
92 
97  private function readDumpFile(ilDBInterface $db) : void
98  {
99  $path_to_db_dump = $this->config->getPathToDBDump();
100  if (!is_file(realpath($path_to_db_dump)) ||
101  !is_readable(realpath($path_to_db_dump))) {
102  throw new Setup\UnachievableException(
103  "Cannot read database dump file: $path_to_db_dump"
104  );
105  }
106  foreach ($this->queryReader(realpath($path_to_db_dump)) as $query) {
107  try {
108  $statement = $db->prepareManip($query);
109  $db->execute($statement);
110  } catch (Throwable $e) {
111  throw new Setup\UnachievableException(
112  "Cannot populate database with dump file: $path_to_db_dump. Query failed: $query wih message " . $e->getMessage(
113  )
114  );
115  }
116  }
117  }
118 
119  private function queryReader(string $path_to_db_dump): Generator
120  {
121  $stack = '';
122  $handle = fopen($path_to_db_dump, "r");
123  while (($line = fgets($handle)) !== false) {
124  if (preg_match('/^--/', $line)) { // Skip comments
125  continue;
126  }
127  if (preg_match('/^\/\*/', $line)) { // Run Variables Assignments as single query
128  yield $line;
129  $stack = '';
130  continue;
131  }
132  if (!preg_match('/;$/', trim($line))) { // Break after ; character which indicates end of query
133  $stack .= $line;
134  } else {
135  $stack .= $line;
136  yield $stack;
137  $stack = '';
138  }
139  }
140 
141  fclose($handle);
142  }
143 
147  private function setDefaultEngine(ilDBInterface $db) : void
148  {
149  switch ($db->getDBType()) {
153  $db->manipulate('SET default_storage_engine=InnoDB;');
154  break;
157  $db->manipulate('SET default_storage_engine=MyISAM;');
158  break;
159 
160  }
161  }
162 
167  private function getDefaultEngine(ilDBInterface $db) : string
168  {
169  try {
170  $r = $db->query('SHOW ENGINES ');
171 
172  $default = '';
173  while ($d = $db->fetchObject($r)) {
174  if ($d->Support === 'DEFAULT') {
175  $default = $d->Engine;
176  }
177  }
178  return strtolower($default);
179  } catch (Throwable $e) {
180  return 'unknown';
181  }
182  }
183 }
prepareManip($a_query, $a_types=null)
getPreconditions(Setup\Environment $environment)
execute($stmt, $data=array())
$query
getDBType()
Get DSN.
fetchObject($query_result)
isApplicable(Setup\Environment $environment)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
An environment holds resources to be used in the setup process.
Definition: Environment.php:11
query($query)
Run a (read-only) Query on the database.
manipulate($query)
Run a (write) Query on the database.
for($i=6; $i< 13; $i++) for($i=1; $i< 13; $i++) $d
Definition: date.php:296