ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilDBMySQL.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2012 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
5 include_once("./Services/Database/classes/MDB2/class.ilDB.php");
6 
18 class ilDBMySQL extends ilDB
19 {
25  protected $slave_active = false;
26  protected $use_slave = false;
27 
34  function supportsSlave()
35  {
36  return true;
37  }
38 
44  function setDBSlaveActive($a_val)
45  {
46  $this->slave_active = $a_val;
47  }
48 
54  function getDBSlaveActive()
55  {
56  return $this->slave_active;
57  }
58 
64  function setDBSlaveUser($a_user)
65  {
66  $this->slave_user = $a_user;
67  }
68 
74  function getDBSlaveUser()
75  {
76  return $this->slave_user;
77  }
78 
84  function setDBSlavePort($a_port)
85  {
86  $this->slave_port = $a_port;
87  }
88 
94  function getDBSlavePort()
95  {
96  return $this->slave_port;
97  }
98 
104  function setDBSlaveHost($a_host)
105  {
106  $this->slave_host = $a_host;
107  }
108 
114  function getDBSlaveHost()
115  {
116  return $this->slave_host;
117  }
118 
124  function setDBSlavePassword($a_password)
125  {
126  $this->slave_password = $a_password;
127  }
128 
135  {
136  return $this->slave_password;
137  }
138 
144  function setDBSlaveName($a_name)
145  {
146  $this->slave_name = $a_name;
147  }
148 
154  function getDBSlaveName()
155  {
156  return $this->slave_name;
157  }
158 
162  function getDSN()
163  {
164  return $this->__buildDSN($this->getDBHost(), $this->getDBName(),
165  $this->getDBUser(), $this->getDBPassword(), $this->getDBPort());
166  }
167 
171  function getSlaveDSN()
172  {
173  return $this->__buildDSN($this->getDBSlaveHost(), $this->getDBSlaveName(),
174  $this->getDBSlaveUser(), $this->getDBSlavePassword(), $this->getDBSlavePort());
175  }
176 
183  protected function __buildDSN($a_host, $a_name, $a_user, $a_pass, $a_port = "")
184  {
185  $db_port_str = "";
186  if (trim($a_port) != "")
187  {
188  $db_port_str = ":".$a_port;
189  }
190 
191  $driver = $this->isMySQLi() ? "mysqli" : "mysql";
192 
193  return $driver."://".$a_user.":".$a_pass.
194  "@".$a_host.$db_port_str."/".$a_name;
195  }
196 
197  protected function isMySQLi()
198  {
199  return ($this->getSubType() == "mysqli");
200  }
201 
205  function getHostDSN()
206  {
207  $driver = $this->isMySQLi() ? "mysqli" : "mysql";
208 
209  return $driver."://".$this->getDBUser().":".$this->getDBPassword().
210  "@".$this->getdbHost();
211  }
212 
216  function getDBType()
217  {
218  return "mysql";
219  }
220 
224  function setStorageEngine($a_storage_engine) {
225  $storage_engine_var = ($this->isMysql5_6OrHigher()) ? "DEFAULT_STORAGE_ENGINE" : "STORAGE_ENGINE";
226  $this->query("SET SESSION " . $storage_engine_var . " = '" . $a_storage_engine . "'");
227  }
228 
232  static function getReservedWords()
233  {
234  // version: 5.1
235  // url: http://dev.mysql.com/doc/refman/5.1/en/reserved-words.html
236  return array(
237  "ACCESSIBLE", "ADD", "ALL", "ALTER", "ANALYZE", "AND",
238  "AS", "ASC", "ASENSITIVE", "BEFORE", "BETWEEN", "BIGINT",
239  "BINARY", "BLOB", "BOTH", "BY", "CALL", "CASCADE",
240  "CASE", "CHANGE", "CHAR", "CHARACTER", "CHECK", "COLLATE",
241  "COLUMN", "CONDITION", "CONSTRAINT", "CONTINUE", "CONVERT", "CREATE",
242  "CROSS", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR",
243  "DATABASE", "DATABASES", "DAY_HOUR", "DAY_MICROSECOND", "DAY_MINUTE", "DAY_SECOND",
244  "DEC", "DECIMAL", "DECLARE", "DEFAULT", "DELAYED", "DELETE",
245  "DESC", "DESCRIBE", "DETERMINISTIC", "DISTINCT", "DISTINCTROW", "DIV",
246  "DOUBLE", "DROP", "DUAL", "EACH", "ELSE", "ELSEIF",
247  "ENCLOSED", "ESCAPED", "EXISTS", "EXIT", "EXPLAIN", "FALSE",
248  "FETCH", "FLOAT", "FLOAT4", "FLOAT8", "FOR", "FORCE",
249  "FOREIGN", "FROM", "FULLTEXT", "GRANT", "GROUP", "HAVING",
250  "HIGH_PRIORITY", "HOUR_MICROSECOND", "HOUR_MINUTE", "HOUR_SECOND", "IF", "IGNORE",
251  "IN", "INDEX", "INFILE", "INNER", "INOUT", "INSENSITIVE",
252  "INSERT", "INT", "INT1", "INT2", "INT3", "INT4",
253  "INT8", "INTEGER", "INTERVAL", "INTO", "IS", "ITERATE",
254  "JOIN", "KEY", "KEYS", "KILL", "LEADING", "LEAVE",
255  "LEFT", "LIKE", "LIMIT", "LINEAR", "LINES", "LOAD",
256  "LOCALTIME", "LOCALTIMESTAMP", "LOCK", "LONG", "LONGBLOB", "LONGTEXT",
257  "LOOP", "LOW_PRIORITY", "MASTER_SSL_VERIFY_SERVER_CERT", "MATCH", "MEDIUMBLOB", "MEDIUMINT",
258  "MEDIUMTEXT", "MIDDLEINT", "MINUTE_MICROSECOND", "MINUTE_SECOND", "MOD", "MODIFIES",
259  "NATURAL", "NOT", "NO_WRITE_TO_BINLOG", "NULL", "NUMERIC", "ON",
260  "OPTIMIZE", "OPTION", "OPTIONALLY", "OR", "ORDER", "OUT",
261  "OUTER", "OUTFILE", "PRECISION", "PRIMARY", "PROCEDURE", "PURGE",
262  "RANGE", "READ", "READS", "READ_WRITE", "REAL", "REFERENCES",
263  "REGEXP", "RELEASE", "RENAME", "REPEAT", "REPLACE", "REQUIRE",
264  "RESTRICT", "RETURN", "REVOKE", "RIGHT", "RLIKE", "SCHEMA",
265  "SCHEMAS", "SECOND_MICROSECOND", "SELECT", "SENSITIVE", "SEPARATOR", "SET",
266  "SHOW", "SMALLINT", "SPATIAL", "SPECIFIC", "SQL", "SQLEXCEPTION",
267  "SQLSTATE", "SQLWARNING", "SQL_BIG_RESULT", "SQL_CALC_FOUND_ROWS", "SQL_SMALL_RESULT", "SSL",
268  "STARTING", "STRAIGHT_JOIN", "TABLE", "TERMINATED", "THEN", "TINYBLOB",
269  "TINYINT", "TINYTEXT", "TO", "TRAILING", "TRIGGER", "TRUE",
270  "UNDO", "UNION", "UNIQUE", "UNLOCK", "UNSIGNED", "UPDATE",
271  "USAGE", "USE", "USING", "UTC_DATE", "UTC_TIME", "UTC_TIMESTAMP",
272  "VALUES", "VARBINARY", "VARCHAR", "VARCHARACTER", "VARYING", "WHEN",
273  "WHERE", "WHILE", "WITH", "WRITE", "XOR", "YEAR_MONTH",
274  "ZEROFILL"
275  );
276  }
277 
282  function initFromIniFile($tmpClientIniFile = null)
283  {
284  global $ilClientIniFile;
285 
286  parent::initFromIniFile($tmpClientIniFile);
287 
288  //overwrite global client ini file if local parameter is set
289  if (is_object($tmpClientIniFile))
290  $clientIniFile = $tmpClientIniFile;
291  else
292  $clientIniFile = $ilClientIniFile;
293 
294  if (is_object($clientIniFile ))
295  {
296  if ($clientIniFile->readVariable("db", "slave_active") == 1)
297  {
298  $this->setDBSlaveActive(true);
299  $this->setDBSlaveUser($clientIniFile->readVariable("db", "slave_user"));
300  $this->setDBSlaveHost($clientIniFile->readVariable("db", "slave_host"));
301  $this->setDBSlavePort($clientIniFile->readVariable("db", "slave_port"));
302  $this->setDBSlavePassword($clientIniFile->readVariable("db", "slave_pass"));
303  $this->setDBSlaveName($clientIniFile->readVariable("db", "slave_name"));
304  }
305  }
306  }
307 
311  function doConnect()
312  {
313  parent::doConnect();
314  if ($this->getDBSlaveActive())
315  {
316  $this->slave = MDB2::connect($this->getSlaveDSN(),
317  array("use_transactions" => false));
318  }
319  }
320 
321 
325  function initConnection()
326  {
327  // SET 'max_allowed_packet' (only possible for mysql version 4)
328  $this->setMaxAllowedPacket();
329 
330  // NOTE: Two sourcecodes use this or a similar handling:
331  // - classes/class.ilDB.php
332  // - setup/classes/class.ilClient.php
333 
334  $this->query("SET NAMES utf8");
335  if (DEVMODE == 1)
336  {
337  $this->query("SET SESSION SQL_MODE = 'ONLY_FULL_GROUP_BY'");
338  }
339  $this->setStorageEngine('MYISAM');
340  }
341 
346  function now()
347  {
348  return "NOW()";
349  }
350 
351 
355  function getDBVersion()
356  {
357  if(!$this->isMySQLi())
358  {
359  $vers = @mysql_get_server_info();
360  }
361  else
362  {
363  $vers = @mysqli_get_server_info($this->db->connection);
364  }
365  if (trim($vers) == "")
366  {
367  $vers = "Unknown";
368  }
369  return $vers;
370  }
371 
372 
377  {
378  $version = explode(".", $this->getDBVersion());
379  if((int) $version[0] < 4)
380  {
381  return false;
382  }
383  return true;
384  }
385 
389  function isMysql4_1()
390  {
391  $version = explode(".", $this->getDBVersion());
392  if ($version[0] == "4" && $version[1] == "1")
393  {
394  return true;
395  }
396 
397  return false;
398  }
399 
408  {
409  $version = explode(".", $this->getDBVersion());
410  if ((int)$version[0] >= 5 ||
411  ((int)$version[0] == 4 && (int)$version[1] >= 1))
412  {
413  return true;
414  }
415 
416  return false;
417  }
418 
426  public function isMysql5_6OrHigher()
427  {
428  $version = explode(".", $this->getDBVersion());
429  if(
430  (int) $version[0] > 5 ||
431  ((int) $version[0] == 5 && (int) $version[1] >= 6))
432  {
433  return true;
434  }
435  return false;
436  }
437 
441  function checkQuerySize($a_query)
442  {
443  global $lang;
444 
445  if(strlen($a_query) >= $this->max_allowed_packet_size)
446  {
447  return false;
448  }
449  else
450  {
451  return true;
452  }
453  }
454 
460  protected function setMaxAllowedPacket()
461  {
462  $version = $this->getDBVersion();
463 
464  // CHANG VALUE IF MYSQL VERSION > 4.0
465  // Switched back to "SET GLOBAL ..."
466  // @see http://bugs.mysql.com/bug.php?id=22891
467  // smeyer 2009 07 30
468  if (substr($version,0,1) == "4")
469  {
470  ini_get("post_max_size");
471  $query = "SET GLOBAL max_allowed_packet = ".(int) ini_get("post_max_size") * 1024 * 1024;
472 //echo "-".$query."-";
473  $this->query($query);
474  }
475  // STORE NEW max_size in member variable
476  $query = "SHOW VARIABLES LIKE 'max_allowed_packet'";
477  $res = $this->query($query);
478 
479  while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
480  {
481  $this->max_allowed_packet_size = $row->value;
482  }
483 //echo "-".$this->max_allowed_packet_size."-";
484  return true;
485  }
486 
490  function supportsFulltext()
491  {
492  return true;
493  }
494 
498  function addFulltextIndex($a_table, $a_fields, $a_name = "in")
499  {
500  $i_name = $this->constraintName($a_table, $a_name)."_idx";
501  $f_str = implode($a_fields, ",");
502  $q = "ALTER TABLE $a_table ADD FULLTEXT $i_name ($f_str)";
503  $this->query($q);
504  }
505 
509  function dropFulltextIndex($a_table, $a_name)
510  {
511  $i_name = $this->constraintName($a_table, $a_name)."_idx";
512  $this->query("ALTER TABLE $a_table DROP FULLTEXT $i_name");
513  }
514 
518  function isFulltextIndex($a_table, $a_name)
519  {
520  $set = $this->query("SHOW INDEX FROM ".$a_table);
521  while ($rec = $this->fetchAssoc($set))
522  {
523  if ($rec["Key_name"] == $a_name && $rec["Index_type"] == "FULLTEXT")
524  {
525  return true;
526  }
527  }
528  }
529 
540  public function lockTables($a_tables)
541  {
542  global $ilLog;
543 
544  $lock = 'LOCK TABLES ';
545 
546  $counter = 0;
547  foreach($a_tables as $table)
548  {
549  if($counter++)
550  {
551  $lock .= ', ';
552  }
553 
554  if( isset($table['sequence']) && $table['sequence'] )
555  {
556  $tableName = $this->db->getSequenceName($table['name']);
557  }
558  else
559  {
560  $tableName = $table['name'];
561  }
562 
563  $lock .= ($tableName.' ');
564 
565  if($table['alias'])
566  {
567  $lock .= ($table['alias'].' ');
568  }
569 
570  switch($table['type'])
571  {
573  $lock .= ' READ ';
574  break;
575 
577  $lock .= ' WRITE ';
578  break;
579  }
580  }
581  if($ilLog instanceof ilLog) {
582  $ilLog->write(__METHOD__.': '.$lock);
583  }
584 
585  $this->query($lock);
586  }
587 
593  public function unlockTables()
594  {
595  $this->query('UNLOCK TABLES');
596  }
597 
598  protected function getCreateTableOptions()
599  {
600  // InnoDB is default engine for MySQL >= 5.5
601  return array('type' => 'MyISAM');
602  }
603 
604  public function getErrorNo()
605  {
606  if(!$this->isMySQLi())
607  {
608  return mysql_errno();
609  }
610  else
611  {
612  return mysqli_errno($this->db->connection);
613  }
614  }
615 
616  public function getLastError()
617  {
618  if(!$this->isMySQLi())
619  {
620  return mysql_error();
621  }
622  else
623  {
624  return mysqli_error($this->db->connection);
625  }
626  }
627 
628 
632  function query($sql, $a_handle_error = true)
633  {
634  if (!$this->use_slave || !$this->getDBSlaveActive())
635  {
636  return parent::query($sql, $a_handle_error);
637  }
638 
639  $r = $this->slave->query($sql);
640 
641  if ($a_handle_error)
642  {
643  return $this->handleError($r, "query(".$sql.")");
644  }
645 
646  return $r;
647 
648  }
649 
650 
655  public function loadModule($module) {
656  return $this->db->loadModule($module);
657  }
658 
659 
660  public function getStorageEngine() {
661  return 'MyISAM';
662  }
663 
668  public function groupConcat($a_field_name, $a_seperator = ",", $a_order = NULL) {
669  if ($a_order === NULL) {
670  $sql = "GROUP_CONCAT(" . $a_field_name . " SEPARATOR " . $this->quote($a_seperator, "text") . ")";
671  } else {
672  $sql = "GROUP_CONCAT(" . $a_field_name . " ORDER BY " . $a_order . " SEPARATOR " . $this->quote($a_seperator, "text"). ")";
673 
674  }
675  return $sql;
676  }
677 }
678 
setDBSlaveUser($a_user)
Set slave database user.
setDBSlaveActive($a_val)
Set slave active.
getDBSlaveHost()
Get slave database host.
setMaxAllowedPacket()
Set maximum allowed packet size.
getDBSlaveName()
Get slave database name.
getDBSlaveActive()
Get slave active.
isMysql4_0OrHigher()
check wether current MySQL server is version 4.0.x or higher
setDBSlaveHost($a_host)
Set slave database host.
getDBSlavePort()
Get slave database port.
getDBSlaveUser()
Get slave database user.
initConnection()
Initialize the database connection.
getSubType()
Get sub type.
lockTables($a_tables)
Lock table.
supportsSlave()
Supports slave.
initFromIniFile($tmpClientIniFile=null)
Init db parameters from ini file.
setDBSlavePassword($a_password)
Set slave database password.
logging
Definition: class.ilLog.php:18
getDBPort()
Get database port.
Definition: class.ilDB.php:103
getDBSlavePassword()
Get slave database password.
setDBSlavePort($a_port)
Set slave database port.
getHostDSN()
Get Host DSN.
dropFulltextIndex($a_table, $a_name)
Add fulltext index.
getDBName()
Get database name.
Definition: class.ilDB.php:163
$counter
query($sql, $a_handle_error=true)
setStorageEngine($a_storage_engine)
Set the storage engine.
fetchAssoc($a_set)
Fetch row as associative array from result set.
quote($a_query, $a_type=null)
Wrapper for quote method.
$r
Definition: example_031.php:79
getDBHost()
Get database host.
Definition: class.ilDB.php:123
setDBSlaveName($a_name)
Set slave database name.
substr($a_exp, $a_pos=1, $a_len=-1)
Substring.
supportsFulltext()
Is fulltext index supported?
getDBUser()
Get database user.
Definition: class.ilDB.php:83
& connect($dsn, $options=false)
Create a new MDB2 connection object and connect to the specified database.
Definition: MDB2.php:436
static getReservedWords()
Get reserved words.
__buildDSN($a_host, $a_name, $a_user, $a_pass, $a_port="")
Build DSN string.
doConnect()
Standard way to connect to db.
getDBType()
Get DB Type.
handleError($a_res, $a_info="", $a_level="")
Handle MDB2 Errors.
Definition: class.ilDB.php:423
MySQL Database Wrapper.
Create styles array
The data for the language used.
unlockTables()
Unlock tables.
getDSN()
Get DSN.
constraintName($a_table, $a_constraint)
Determine contraint name by table name and constraint name.
isFulltextIndex($a_table, $a_name)
Is index a fulltext index?
Database Wrapper.
Definition: class.ilDB.php:29
isMysql4_1OrHigher()
check wether current MySQL server is version 4.1.x or higher
getSlaveDSN()
Get slave DSN.
for($i=1; $i<=count($kw_cases_sel); $i+=1) $lang
Definition: langwiz.php:349
loadModule($module)
getDBPassword()
Get database password.
Definition: class.ilDB.php:143
checkQuerySize($a_query)
Check query size.
addFulltextIndex($a_table, $a_fields, $a_name="in")
Add fulltext index.
isMysql5_6OrHigher()
check wether current MySQL server is version 5.6.x or higher
getDBVersion()
get mysql version
isMysql4_1()
check wether current MySQL server is version 4.1.x
groupConcat($a_field_name, $a_seperator=",", $a_order=NULL)
string