ILIAS  Release_3_10_x_branch Revision 61812
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilDBUpdate.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2008 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 
24 
25 // include pear
26 //require_once("DB.php");
27 
35 {
40 
46 
52 
56  function ilDBUpdate($a_db_handler = 0,$tmp_flag = false)
57  {
58  // workaround to allow setup migration
59  if ($a_db_handler)
60  {
61  $this->db =& $a_db_handler;
62 
63  if ($tmp_flag)
64  {
65  $this->PATH = "./";
66  }
67  else
68  {
69  $this->PATH = "../";
70  }
71  }
72  else
73  {
74  global $mySetup;
75  $this->db = $mySetup->db;
76  $this->PATH = "./";
77  }
78 
79  $this->getCurrentVersion();
80 
81  // get update file for current version
82  $updatefile = $this->getFileForStep($this->currentVersion + 1);
83 
84  $this->current_file = $updatefile;
85  $this->DB_UPDATE_FILE = $this->PATH."setup/sql/".$updatefile;
86 
87  //
88  // NOTE: IF YOU SET THIS TO THE NEWEST FILE, CHANGE ALSO getFileForStep()
89  //
90  $this->LAST_UPDATE_FILE = $this->PATH."setup/sql/dbupdate_02.php";
91 
92  $this->readDBUpdateFile();
93  $this->readLastUpdateFile();
94  $this->readFileVersion();
95  }
96 
100  function getFileForStep($a_version)
101  {
102  //
103  // NOTE: IF YOU ADD A NEW FILE HERE, CHANGE ALSO THE CONSTRUCTOR
104  //
105  if ((int)$a_version > 864) // last number in previous file
106  {
107  return "dbupdate_02.php";
108  }
109  else
110  {
111  return "dbupdate.php";
112  }
113  }
114 
120  function _DBUpdate()
121  {
122  $this->db->disconnect();
123  }
124 
125  function readDBUpdateFile()
126  {
127  if (!file_exists($this->DB_UPDATE_FILE))
128  {
129  $this->error = "no_db_update_file";
130  $this->filecontent = array();
131  return false;
132  }
133 
134  $this->filecontent = @file($this->DB_UPDATE_FILE);
135  return true;
136  }
137 
139  {
140  if (!file_exists($this->LAST_UPDATE_FILE))
141  {
142  $this->error = "no_last_update_file";
143  $this->lastfilecontent = array();
144  return false;
145  }
146 
147  $this->lastfilecontent = @file($this->LAST_UPDATE_FILE);
148  return true;
149  }
150 
151  function getCurrentVersion()
152  {
153  $q = "SELECT value FROM settings ".
154  "WHERE keyword = 'db_version'";
155  $r = $this->db->query($q);
156 
157  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
158 
159  $this->currentVersion = (integer) $row->value;
160 
161  return $this->currentVersion;
162  }
163 
164  function setCurrentVersion ($a_version)
165  {
166  {
167  $q = "UPDATE settings SET ".
168  "value = ".$this->db->quote($a_version)." ".
169  "WHERE keyword = 'db_version'";
170  }
171 
172  $this->db->query($q);
173  $this->currentVersion = $a_version;
174 
175  return true;
176  }
177 
178  function readFileVersion()
179  {
180  //go through filecontent and search for last occurence of <#x>
181  reset($this->lastfilecontent);
182  $regs = array();
183  foreach ($this->lastfilecontent as $row)
184  {
185  if (ereg("^<#([0-9]+)>", $row, $regs))
186  {
187  $version = $regs[1];
188  }
189  }
190 
191  $this->fileVersion = (integer) $version;
192  return $this->fileVersion;
193  }
194 
198  function getFileVersion()
199  {
200  return $this->fileVersion;
201  }
202 
209  function execQuery($db,$str)
210  {
211  $sql = explode("\n",trim($str));
212  for ($i=0; $i<count($sql); $i++)
213  {
214  $sql[$i] = trim($sql[$i]);
215  if ($sql[$i] != "" && substr($sql[$i],0,1)!="#")
216  {
217  //take line per line, until last char is ";"
218  if (substr($sql[$i],-1)==";")
219  {
220  //query is complete
221  $q .= " ".substr($sql[$i],0,-1);
222  $check = $this->checkQuery($q);
223  if ($check === true)
224  {
225  $r = $db->query($q);
226  if (MDB2::isError($r))
227  {
228  $this->error = $r->getMessage();
229  return false;
230  }
231  }
232  else
233  {
234  $this->error = $check;
235  return false;
236  }
237  unset($q);
238  } //if
239  else
240  {
241  $q .= " ".$sql[$i];
242  } //else
243  } //if
244  } //for
245  if ($q != "")
246  {
247  echo "incomplete_statement: ".$q."<br>";
248  return false;
249  }
250  return true;
251  }
252 
256  function checkQuery($q)
257  {
258  return true;
259  }
260 
264  function applyUpdate()
265  {
266  global $ilCtrlStructureReader;
267 
268  $f = $this->fileVersion;
270 
271  if ($c < $f)
272  {
273  $msg = array();
274  for ($i=($c+1); $i<=$f; $i++)
275  {
276  // check wether next update file must be loaded
277  if ($this->current_file != $this->getFileForStep($i))
278  {
279  $this->DB_UPDATE_FILE = $this->PATH."setup/sql/".$this->getFileForStep($i);
280  $this->readDBUpdateFile();
281  }
282 
283  if ($this->applyUpdateNr($i) == false)
284  {
285  $msg[] = array(
286  "msg" => "update_error: ".$this->error,
287  "nr" => $i
288  );
289  $this->updateMsg = $msg;
290  return false;
291  }
292  else
293  {
294  $msg[] = array(
295  "msg" => "update_applied",
296  "nr" => $i
297  );
298  }
299  }
300 
301  $this->updateMsg = $msg;
302  }
303  else
304  {
305  $this->updateMsg = "no_changes";
306  }
307 //global $ilDB; $ilDB->query("UPDATE settings SET value='1146' WHERE keyword='db_version'");
308 
309  return $this->loadXMLInfo();
310  }
311 
312  function loadXMLInfo()
313  {
314  global $ilCtrlStructureReader;
315 
316  // read module and service information into db
317  require_once "./classes/class.ilModuleReader.php";
318  require_once "./classes/class.ilServiceReader.php";
319  require_once "./classes/class.ilCtrlStructureReader.php";
320 
321  chdir("..");
322  require_once "./Services/Component/classes/class.ilModule.php";
323  require_once "./Services/Component/classes/class.ilService.php";
326  chdir("./setup");
327 
329  foreach($modules as $module)
330  {
331  $mr = new ilModuleReader(ILIAS_ABSOLUTE_PATH."/Modules/".$module["subdir"]."/module.xml",
332  $module["subdir"], "Modules");
333  $mr->getModules();
334  unset($mr);
335  }
336 
338  foreach($services as $service)
339  {
340  $sr = new ilServiceReader(ILIAS_ABSOLUTE_PATH."/Services/".$service["subdir"]."/service.xml",
341  $service["subdir"], "Services");
342  $sr->getServices();
343  unset($sr);
344  }
345 
346  $ilCtrlStructureReader->readStructure();
347 
348  return true;
349  }
350 
357  function applyUpdateNr($nr)
358  {
359  global $ilDB,$ilErr,$ilUser,$ilCtrlStructureReader,$ilModuleReader;
360 
361  //search for desired $nr
362  reset($this->filecontent);
363 
364  //init
365  $i = 0;
366 
367  //go through filecontent
368  while (!ereg("^<#".$nr.">", $this->filecontent[$i]) && $i<count($this->filecontent))
369  {
370  $i++;
371  }
372 
373  //update not found
374  if ($i == count($this->filecontent))
375  {
376  $this->error = "update_not_found";
377  return false;
378  }
379 
380  $i++;
381 
382  //update found, now extract this update to a new array
383  $update = array();
384  while ($i<count($this->filecontent) && !ereg("^<#".($nr+1).">", $this->filecontent[$i]))
385  {
386  $update[] = trim($this->filecontent[$i]);
387  $i++;
388  }
389 
390  //now you have the update, now process it
391  $sql = array();
392  $php = array();
393  $mode = "sql";
394 
395  foreach ($update as $row)
396  {
397  if (ereg("<\?php", $row))
398  {
399  if (count($sql)>0)
400  {
401  if ($this->execQuery($this->db, implode("\n", $sql)) == false)
402  {
403  $this->error = $this->error;
404  return false;
405  }
406  $sql = array();
407  }
408  $mode = "php";
409  }
410  elseif (ereg("\?>", $row))
411  {
412  if (count($php)>0)
413  {
414  eval(implode("\n", $php));
415  $php = array();
416  }
417  $mode = "sql";
418 
419  }
420  else
421  {
422  if ($mode == "sql")
423  {
424  $sql[] = $row;
425  }
426 
427  if ($mode == "php")
428  {
429  $php[] = $row;
430  }
431  } //else
432  } //foreach
433 
434  if ($mode == "sql" && count($sql) > 0)
435  {
436  if ($this->execQuery($this->db, implode("\n", $sql)) == false)
437  {
438  $this->error = "dump_error: ".$this->error;
439  return false;
440  }
441  }
442 
443  //increase db_Version number
444  $this->setCurrentVersion($nr);
445  //$this->currentVersion = $ilias->getSetting("db_version");
446 
447  return true;
448 
449  }
450 
452  {
453  if ($this->fileVersion > $this->currentVersion)
454  return false;
455  else
456  return true;
457  }
458 
459  function getTables()
460  {
461  $a = array();
462 
463  $query = "SHOW TABLES";
464  $res = $this->db->query($query);
465  while ($row = $res->fetchRow())
466  {
467  $status = $this->getTableStatus($row[0]);
468  $a[] = array(
469  "name" => $status["Table"],
470  "table" => $row[0],
471  "status" => $status["Msg_text"]
472  );
473  }
474  return $a;
475  }
476 
477  function getTableStatus($table)
478  {
479  $a = array();
480 
481  $query = "ANALYZE TABLE ".$table;
482  $res = $this->db->query($query);
483  $row = $res->fetchRow(DB_FETCHMODE_ASSOC);
484  return $row;
485  }
486 
487  function optimizeTables($tables)
488  {
489  $msg = array();
490  foreach ($_POST["tables"] as $key => $value)
491  {
492  $query = "OPTIMIZE TABLE ".$key;
493  $res = $this->db->query($query);
494  $msg[] = "table $key: ok";
495  }
496  return $msg;
497  }
498 
499 } // END class.DBUdate
500 ?>