ILIAS  Release_4_1_x_branch Revision 61804
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilDBUpdate.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
13 {
18 
24 
30 
34  function ilDBUpdate($a_db_handler = 0,$tmp_flag = false)
35  {
36  // workaround to allow setup migration
37  if ($a_db_handler)
38  {
39  $this->db =& $a_db_handler;
40 
41  if ($tmp_flag)
42  {
43  $this->PATH = "./";
44  }
45  else
46  {
47  $this->PATH = "./";
48  //$this->PATH = "../";
49  }
50  }
51  else
52  {
53  global $mySetup;
54  $this->db = $mySetup->db;
55  $this->PATH = "./";
56  }
57 
58  $this->getCurrentVersion();
59 
60  // get update file for current version
61  $updatefile = $this->getFileForStep($this->currentVersion + 1);
62 
63  $this->current_file = $updatefile;
64  $this->DB_UPDATE_FILE = $this->PATH."setup/sql/".$updatefile;
65 
66  //
67  // NOTE: IF YOU SET THIS TO THE NEWEST FILE, CHANGE ALSO getFileForStep()
68  //
69  $this->LAST_UPDATE_FILE = $this->PATH."setup/sql/dbupdate_03.php";
70 
71  $this->readDBUpdateFile();
72  $this->readLastUpdateFile();
73  $this->readFileVersion();
74  }
75 
79  function getFileForStep($a_version)
80  {
81  //
82  // NOTE: IF YOU ADD A NEW FILE HERE, CHANGE ALSO THE CONSTRUCTOR
83  //
84  if ((int)$a_version > 2948) // last number in previous file
85  {
86  return "dbupdate_03.php";
87  }
88  else if ((int)$a_version > 864) // last number in previous file
89  {
90  return "dbupdate_02.php";
91  }
92  else
93  {
94  return "dbupdate.php";
95  }
96  }
97 
101  function initStep($i)
102  {
103  //
104  }
105 
111  function _DBUpdate()
112  {
113  $this->db->disconnect();
114  }
115 
116  function readDBUpdateFile()
117  {
118  if (!file_exists($this->DB_UPDATE_FILE))
119  {
120  $this->error = "no_db_update_file";
121  $this->filecontent = array();
122  return false;
123  }
124 
125  $this->filecontent = @file($this->DB_UPDATE_FILE);
126  return true;
127  }
128 
130  {
131  if (!file_exists($this->LAST_UPDATE_FILE))
132  {
133  $this->error = "no_last_update_file";
134  $this->lastfilecontent = array();
135  return false;
136  }
137 
138  $this->lastfilecontent = @file($this->LAST_UPDATE_FILE);
139  return true;
140  }
141 
142  function getCurrentVersion()
143  {
144  $GLOBALS["ilDB"] = $this->db;
145  include_once './Services/Administration/classes/class.ilSetting.php';
146  $set = new ilSetting();
147  $this->currentVersion = (integer) $set->get("db_version");
148 
149  return $this->currentVersion;
150  }
151 
152  function setCurrentVersion ($a_version)
153  {
154  include_once './Services/Administration/classes/class.ilSetting.php';
155  $set = new ilSetting();
156  $set->set("db_version", $a_version);
157  $this->currentVersion = $a_version;
158 
159  return true;
160  }
161 
167  function setRunningStatus($a_nr)
168  {
169  include_once './Services/Administration/classes/class.ilSetting.php';
170  $set = new ilSetting();
171  $set->set("db_update_running", $a_nr);
172  $this->db_update_running = $a_nr;
173  }
174 
180  function getRunningStatus()
181  {
182  include_once './Services/Administration/classes/class.ilSetting.php';
183  $set = new ilSetting();
184  $this->db_update_running = (integer) $set->get("db_update_running");
185 
186  return $this->db_update_running;
187  }
188 
193  {
194  include_once './Services/Administration/classes/class.ilSetting.php';
195  $set = new ilSetting();
196  $set->set("db_update_running", 0);
197  $this->db_update_running = 0;
198  }
199 
200  function readFileVersion()
201  {
202  //go through filecontent and search for last occurence of <#x>
203  reset($this->lastfilecontent);
204  $regs = array();
205  foreach ($this->lastfilecontent as $row)
206  {
207  if (ereg("^<#([0-9]+)>", $row, $regs))
208  {
209  $version = $regs[1];
210  }
211  }
212 
213  $this->fileVersion = (integer) $version;
214  return $this->fileVersion;
215  }
216 
220  function getFileVersion()
221  {
222  return $this->fileVersion;
223  }
224 
231  function execQuery($db,$str)
232  {
233  $sql = explode("\n",trim($str));
234  for ($i=0; $i<count($sql); $i++)
235  {
236  $sql[$i] = trim($sql[$i]);
237  if ($sql[$i] != "" && substr($sql[$i],0,1)!="#")
238  {
239  //take line per line, until last char is ";"
240  if (substr($sql[$i],-1)==";")
241  {
242  //query is complete
243  $q .= " ".substr($sql[$i],0,-1);
244  $check = $this->checkQuery($q);
245  if ($check === true)
246  {
247  $r = $db->query($q);
248  if (MDB2::isError($r))
249  {
250  $this->error = $r->getMessage();
251  return false;
252  }
253  }
254  else
255  {
256  $this->error = $check;
257  return false;
258  }
259  unset($q);
260  } //if
261  else
262  {
263  $q .= " ".$sql[$i];
264  } //else
265  } //if
266  } //for
267  if ($q != "")
268  {
269  echo "incomplete_statement: ".$q."<br>";
270  return false;
271  }
272  return true;
273  }
274 
278  function checkQuery($q)
279  {
280  return true;
281  }
282 
286  function applyUpdate($a_break = 0)
287  {
288  global $ilCtrlStructureReader, $ilMySQLAbstraction;
289 
290  include_once './Services/Database/classes/class.ilMySQLAbstraction.php';
291 
292  $ilMySQLAbstraction = new ilMySQLAbstraction();
293  $GLOBALS['ilMySQLAbstraction'] = $ilMySQLAbstraction;
294 
295  $f = $this->fileVersion;
297 
298  if ($a_break > $this->currentVersion &&
299  $a_break < $this->fileVersion)
300  {
301  $f = $a_break;
302  }
303 
304  if ($c < $f)
305  {
306  $msg = array();
307  for ($i=($c+1); $i<=$f; $i++)
308  {
309  // check wether next update file must be loaded
310  if ($this->current_file != $this->getFileForStep($i))
311  {
312  $this->DB_UPDATE_FILE = $this->PATH."setup/sql/".$this->getFileForStep($i);
313  $this->readDBUpdateFile();
314  }
315 
316  $this->initStep($i);
317 
318  if ($this->applyUpdateNr($i) == false)
319  {
320  $msg[] = array(
321  "msg" => "update_error: ".$this->error,
322  "nr" => $i
323  );
324  $this->updateMsg = $msg;
325  return false;
326  }
327  else
328  {
329  $msg[] = array(
330  "msg" => "update_applied",
331  "nr" => $i
332  );
333  }
334  }
335 
336  $this->updateMsg = $msg;
337  }
338  else
339  {
340  $this->updateMsg = "no_changes";
341  }
342 
343  if ($f < $this->fileVersion)
344  {
345  return true;
346  }
347  else
348  {
349  return $this->loadXMLInfo();
350  }
351  }
352 
353  function loadXMLInfo()
354  {
355  global $ilCtrlStructureReader;
356 
357  // read module and service information into db
358  require_once "./setup/classes/class.ilModuleReader.php";
359  require_once "./setup/classes/class.ilServiceReader.php";
360  require_once "./setup/classes/class.ilCtrlStructureReader.php";
361 
362  require_once "./Services/Component/classes/class.ilModule.php";
363  require_once "./Services/Component/classes/class.ilService.php";
366 
368  foreach($modules as $module)
369  {
370  $mr = new ilModuleReader(ILIAS_ABSOLUTE_PATH."/Modules/".$module["subdir"]."/module.xml",
371  $module["subdir"], "Modules");
372  $mr->getModules();
373  unset($mr);
374  }
375 
377  foreach($services as $service)
378  {
379  $sr = new ilServiceReader(ILIAS_ABSOLUTE_PATH."/Services/".$service["subdir"]."/service.xml",
380  $service["subdir"], "Services");
381  $sr->getServices();
382  unset($sr);
383  }
384 
385  $ilCtrlStructureReader->readStructure();
386 
387  return true;
388  }
389 
396  function applyUpdateNr($nr, $hotfix = false)
397  {
398  global $ilDB,$ilErr,$ilUser,$ilCtrlStructureReader,$ilModuleReader,$ilMySQLAbstraction;
399 
400  //search for desired $nr
401  reset($this->filecontent);
402 
403  if (!$hotfix)
404  {
405  $this->setRunningStatus($nr);
406  }
407 
408  //init
409  $i = 0;
410 
411  //go through filecontent
412  while (!ereg("^<#".$nr.">", $this->filecontent[$i]) && $i<count($this->filecontent))
413  {
414  $i++;
415  }
416 
417  //update not found
418  if ($i == count($this->filecontent))
419  {
420  $this->error = "update_not_found";
421  return false;
422  }
423 
424  $i++;
425 
426  //update found, now extract this update to a new array
427  $update = array();
428  while ($i<count($this->filecontent) && !ereg("^<#".($nr+1).">", $this->filecontent[$i]))
429  {
430  $update[] = trim($this->filecontent[$i]);
431  $i++;
432  }
433 
434  //now you have the update, now process it
435  $sql = array();
436  $php = array();
437  $mode = "sql";
438 
439  foreach ($update as $row)
440  {
441  if (ereg("<\?php", $row))
442  {
443  if (count($sql)>0)
444  {
445  if ($this->execQuery($this->db, implode("\n", $sql)) == false)
446  {
447  $this->error = $this->error;
448  return false;
449  }
450  $sql = array();
451  }
452  $mode = "php";
453  }
454  elseif (ereg("\?>", $row))
455  {
456  if (count($php)>0)
457  {
458  $code = implode("\n", $php);
459  if (eval($code) === false)
460  {
461  $this->error = "Parse error: ".$code;
462  return false;
463  }
464  $php = array();
465  }
466  $mode = "sql";
467 
468  }
469  else
470  {
471  if ($mode == "sql")
472  {
473  $sql[] = $row;
474  }
475 
476  if ($mode == "php")
477  {
478  $php[] = $row;
479  }
480  } //else
481  } //foreach
482 
483  if ($mode == "sql" && count($sql) > 0)
484  {
485  if ($this->execQuery($this->db, implode("\n", $sql)) == false)
486  {
487  $this->error = "dump_error: ".$this->error;
488  return false;
489  }
490  }
491 
492  //increase db_Version number
493  if (!$hotfix)
494  {
495  $this->setCurrentVersion($nr);
496  }
497  else
498  {
499  $this->setHotfixCurrentVersion($nr);
500  }
501 
502  if (!$hotfix)
503  {
504  $this->clearRunningStatus();
505  }
506  //$this->currentVersion = $ilias->getSetting("db_version");
507 
508  return true;
509 
510  }
511 
513  {
514  if ($this->fileVersion > $this->currentVersion)
515  return false;
516  else
517  return true;
518  }
519 
520  function getTables()
521  {
522  $a = array();
523 
524  $query = "SHOW TABLES";
525  $res = $this->db->query($query);
526  while ($row = $res->fetchRow())
527  {
528  $status = $this->getTableStatus($row[0]);
529  $a[] = array(
530  "name" => $status["Table"],
531  "table" => $row[0],
532  "status" => $status["Msg_text"]
533  );
534  }
535  return $a;
536  }
537 
538  function getTableStatus($table)
539  {
540  $a = array();
541 
542  $query = "ANALYZE TABLE ".$table;
543  $res = $this->db->query($query);
544  $row = $res->fetchRow(DB_FETCHMODE_ASSOC);
545  return $row;
546  }
547 
548  function optimizeTables($tables)
549  {
550  $msg = array();
551  foreach ($_POST["tables"] as $key => $value)
552  {
553  $query = "OPTIMIZE TABLE ".$key;
554  $res = $this->db->query($query);
555  $msg[] = "table $key: ok";
556  }
557  return $msg;
558  }
559 
563 
564 
569  {
570  $this->readHotfixInfo();
571  return $this->hotfix_current_version;
572  }
573 
577  function setHotfixCurrentVersion($a_version)
578  {
579  $this->readHotfixInfo();
580  $this->hotfix_setting->set("db_hotfixes_".
581  $this->hotfix_version[0]."_".$this->hotfix_version[1], $a_version);
582  $this->hotfix_current_version = $a_version;
583  return true;
584  }
585 
590  {
591  $this->readHotfixInfo();
592  return $this->hotfix_file_version;
593  }
594 
598  function readHotfixFileVersion($a_file_content)
599  {
600  //go through filecontent and search for last occurence of <#x>
601  reset($a_file_content);
602  $regs = array();
603  foreach ($a_file_content as $row)
604  {
605  if (ereg("^<#([0-9]+)>", $row, $regs))
606  {
607  $version = $regs[1];
608  }
609  }
610 
611  return (integer) $version;
612  }
613 
617  function readHotfixInfo($a_force = false)
618  {
619  if ($this->hotfix_info_read && !$a_force)
620  {
621  return;
622  }
623  include_once './Services/Administration/classes/class.ilSetting.php';
624  $GLOBALS["ilDB"] = $this->db;
625  $this->hotfix_setting = new ilSetting();
626  $ilias_version = ILIAS_VERSION_NUMERIC;
627  $version_array = explode(".", $ilias_version);
628  $this->hotfix_version[0] = $version_array[0];
629  $this->hotfix_version[1] = $version_array[1];
630  $hotfix_file = $this->PATH."setup/sql/".$this->hotfix_version[0]."_".$this->hotfix_version[1]."_hotfixes.php";
631  if (is_file($hotfix_file))
632  {
633  $this->hotfix_content = @file($hotfix_file);
634  $this->hotfix_current_version = (int) $this->hotfix_setting->get("db_hotfixes_".
635  $this->hotfix_version[0]."_".$this->hotfix_version[1]);
636  $this->hotfix_file_version = $this->readHotfixFileVersion($this->hotfix_content);
637  }
638  $this->hotfix_info_read = true;
639  }
640 
644  function hotfixAvailable()
645  {
646  $this->readHotfixInfo();
647  if ($this->hotfix_file_version > $this->hotfix_current_version)
648  {
649  return true;
650  }
651  return false;
652  }
653 
657  function applyHotfix()
658  {
659  global $ilCtrlStructureReader, $ilMySQLAbstraction;
660 
661  include_once './Services/Database/classes/class.ilMySQLAbstraction.php';
662 
663  $ilMySQLAbstraction = new ilMySQLAbstraction();
664  $GLOBALS['ilMySQLAbstraction'] = $ilMySQLAbstraction;
665 
666  $this->readHotfixInfo(true);
667 
668  $f = $this->getHotfixFileVersion();
669  $c = $this->getHotfixCurrentVersion();
670 
671  if ($c < $f)
672  {
673  $msg = array();
674  for ($i=($c+1); $i<=$f; $i++)
675  {
676 // $this->initStep($i); // nothings happens here
677 
678  $this->filecontent = $this->hotfix_content;
679 
680  if ($this->applyUpdateNr($i, true) == false)
681  {
682  $msg[] = array(
683  "msg" => "update_error: ".$this->error,
684  "nr" => $i
685  );
686  $this->updateMsg = $msg;
687  return false;
688  }
689  else
690  {
691  $msg[] = array(
692  "msg" => "hotfix_applied",
693  "nr" => $i
694  );
695  }
696  }
697 
698  $this->updateMsg = $msg;
699  }
700  else
701  {
702  $this->updateMsg = "no_changes";
703  }
704 
705  return $this->loadXMLInfo();
706  }
707 
708 
709 } // END class.DBUdate
710 ?>