ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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  public function supportsSlave()
35  {
36  return true;
37  }
38 
44  public function setDBSlaveActive($a_val)
45  {
46  $this->slave_active = $a_val;
47  }
48 
54  public function getDBSlaveActive()
55  {
56  return $this->slave_active;
57  }
58 
64  public function setDBSlaveUser($a_user)
65  {
66  $this->slave_user = $a_user;
67  }
68 
74  public function getDBSlaveUser()
75  {
76  return $this->slave_user;
77  }
78 
84  public function setDBSlavePort($a_port)
85  {
86  $this->slave_port = $a_port;
87  }
88 
94  public function getDBSlavePort()
95  {
96  return $this->slave_port;
97  }
98 
104  public function setDBSlaveHost($a_host)
105  {
106  $this->slave_host = $a_host;
107  }
108 
114  public function getDBSlaveHost()
115  {
116  return $this->slave_host;
117  }
118 
124  public function setDBSlavePassword($a_password)
125  {
126  $this->slave_password = $a_password;
127  }
128 
134  public function getDBSlavePassword()
135  {
136  return $this->slave_password;
137  }
138 
144  public function setDBSlaveName($a_name)
145  {
146  $this->slave_name = $a_name;
147  }
148 
154  public function getDBSlaveName()
155  {
156  return $this->slave_name;
157  }
158 
162  public function getDSN()
163  {
164  return $this->__buildDSN(
165  $this->getDBHost(),
166  $this->getDBName(),
167  $this->getDBUser(),
168  $this->getDBPassword(),
169  $this->getDBPort()
170  );
171  }
172 
176  public function getSlaveDSN()
177  {
178  return $this->__buildDSN(
179  $this->getDBSlaveHost(),
180  $this->getDBSlaveName(),
181  $this->getDBSlaveUser(),
182  $this->getDBSlavePassword(),
183  $this->getDBSlavePort()
184  );
185  }
186 
193  protected function __buildDSN($a_host, $a_name, $a_user, $a_pass, $a_port = "")
194  {
195  $db_port_str = "";
196  if (trim($a_port) != "") {
197  $db_port_str = ":" . $a_port;
198  }
199 
200  $driver = $this->isMySQLi() ? "mysqli" : "mysql";
201 
202  return $driver . "://" . $a_user . ":" . $a_pass .
203  "@" . $a_host . $db_port_str . "/" . $a_name;
204  }
205 
206  protected function isMySQLi()
207  {
208  return ($this->getSubType() == "mysqli");
209  }
210 
214  public function getHostDSN()
215  {
216  $driver = $this->isMySQLi() ? "mysqli" : "mysql";
217 
218  return $driver . "://" . $this->getDBUser() . ":" . $this->getDBPassword() .
219  "@" . $this->getdbHost();
220  }
221 
225  public function getDBType()
226  {
227  return "mysql";
228  }
229 
233  public function setStorageEngine($a_storage_engine)
234  {
235  $storage_engine_var = ($this->isMysql5_6OrHigher()) ? "DEFAULT_STORAGE_ENGINE" : "STORAGE_ENGINE";
236  $this->query("SET SESSION " . $storage_engine_var . " = '" . $a_storage_engine . "'");
237  }
238 
242  public static function getReservedWords()
243  {
244  // version: 5.1
245  // url: http://dev.mysql.com/doc/refman/5.1/en/reserved-words.html
246  return array(
247  "ACCESSIBLE", "ADD", "ALL", "ALTER", "ANALYZE", "AND",
248  "AS", "ASC", "ASENSITIVE", "BEFORE", "BETWEEN", "BIGINT",
249  "BINARY", "BLOB", "BOTH", "BY", "CALL", "CASCADE",
250  "CASE", "CHANGE", "CHAR", "CHARACTER", "CHECK", "COLLATE",
251  "COLUMN", "CONDITION", "CONSTRAINT", "CONTINUE", "CONVERT", "CREATE",
252  "CROSS", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR",
253  "DATABASE", "DATABASES", "DAY_HOUR", "DAY_MICROSECOND", "DAY_MINUTE", "DAY_SECOND",
254  "DEC", "DECIMAL", "DECLARE", "DEFAULT", "DELAYED", "DELETE",
255  "DESC", "DESCRIBE", "DETERMINISTIC", "DISTINCT", "DISTINCTROW", "DIV",
256  "DOUBLE", "DROP", "DUAL", "EACH", "ELSE", "ELSEIF",
257  "ENCLOSED", "ESCAPED", "EXISTS", "EXIT", "EXPLAIN", "FALSE",
258  "FETCH", "FLOAT", "FLOAT4", "FLOAT8", "FOR", "FORCE",
259  "FOREIGN", "FROM", "FULLTEXT", "GRANT", "GROUP", "HAVING",
260  "HIGH_PRIORITY", "HOUR_MICROSECOND", "HOUR_MINUTE", "HOUR_SECOND", "IF", "IGNORE",
261  "IN", "INDEX", "INFILE", "INNER", "INOUT", "INSENSITIVE",
262  "INSERT", "INT", "INT1", "INT2", "INT3", "INT4",
263  "INT8", "INTEGER", "INTERVAL", "INTO", "IS", "ITERATE",
264  "JOIN", "KEY", "KEYS", "KILL", "LEADING", "LEAVE",
265  "LEFT", "LIKE", "LIMIT", "LINEAR", "LINES", "LOAD",
266  "LOCALTIME", "LOCALTIMESTAMP", "LOCK", "LONG", "LONGBLOB", "LONGTEXT",
267  "LOOP", "LOW_PRIORITY", "MASTER_SSL_VERIFY_SERVER_CERT", "MATCH", "MEDIUMBLOB", "MEDIUMINT",
268  "MEDIUMTEXT", "MIDDLEINT", "MINUTE_MICROSECOND", "MINUTE_SECOND", "MOD", "MODIFIES",
269  "NATURAL", "NOT", "NO_WRITE_TO_BINLOG", "NULL", "NUMERIC", "ON",
270  "OPTIMIZE", "OPTION", "OPTIONALLY", "OR", "ORDER", "OUT",
271  "OUTER", "OUTFILE", "PRECISION", "PRIMARY", "PROCEDURE", "PURGE",
272  "RANGE", "READ", "READS", "READ_WRITE", "REAL", "REFERENCES",
273  "REGEXP", "RELEASE", "RENAME", "REPEAT", "REPLACE", "REQUIRE",
274  "RESTRICT", "RETURN", "REVOKE", "RIGHT", "RLIKE", "SCHEMA",
275  "SCHEMAS", "SECOND_MICROSECOND", "SELECT", "SENSITIVE", "SEPARATOR", "SET",
276  "SHOW", "SMALLINT", "SPATIAL", "SPECIFIC", "SQL", "SQLEXCEPTION",
277  "SQLSTATE", "SQLWARNING", "SQL_BIG_RESULT", "SQL_CALC_FOUND_ROWS", "SQL_SMALL_RESULT", "SSL",
278  "STARTING", "STRAIGHT_JOIN", "TABLE", "TERMINATED", "THEN", "TINYBLOB",
279  "TINYINT", "TINYTEXT", "TO", "TRAILING", "TRIGGER", "TRUE",
280  "UNDO", "UNION", "UNIQUE", "UNLOCK", "UNSIGNED", "UPDATE",
281  "USAGE", "USE", "USING", "UTC_DATE", "UTC_TIME", "UTC_TIMESTAMP",
282  "VALUES", "VARBINARY", "VARCHAR", "VARCHARACTER", "VARYING", "WHEN",
283  "WHERE", "WHILE", "WITH", "WRITE", "XOR", "YEAR_MONTH",
284  "ZEROFILL"
285  );
286  }
287 
292  public function initFromIniFile($tmpClientIniFile = null)
293  {
294  global $ilClientIniFile;
295 
296  parent::initFromIniFile($tmpClientIniFile);
297 
298  //overwrite global client ini file if local parameter is set
299  if (is_object($tmpClientIniFile)) {
300  $clientIniFile = $tmpClientIniFile;
301  } else {
302  $clientIniFile = $ilClientIniFile;
303  }
304 
305  if (is_object($clientIniFile)) {
306  if ($clientIniFile->readVariable("db", "slave_active") == 1) {
307  $this->setDBSlaveActive(true);
308  $this->setDBSlaveUser($clientIniFile->readVariable("db", "slave_user"));
309  $this->setDBSlaveHost($clientIniFile->readVariable("db", "slave_host"));
310  $this->setDBSlavePort($clientIniFile->readVariable("db", "slave_port"));
311  $this->setDBSlavePassword($clientIniFile->readVariable("db", "slave_pass"));
312  $this->setDBSlaveName($clientIniFile->readVariable("db", "slave_name"));
313  }
314  }
315  }
316 
320  public function doConnect()
321  {
322  parent::doConnect();
323  if ($this->getDBSlaveActive()) {
324  $this->slave = MDB2::connect(
325  $this->getSlaveDSN(),
326  array("use_transactions" => false)
327  );
328  }
329  }
330 
331 
335  public function initConnection()
336  {
337  // SET 'max_allowed_packet' (only possible for mysql version 4)
338  $this->setMaxAllowedPacket();
339 
340  // NOTE: Two sourcecodes use this or a similar handling:
341  // - classes/class.ilDB.php
342  // - setup/classes/class.ilClient.php
343 
344  $this->query("SET NAMES utf8");
345  if (DEVMODE == 1) {
346  $this->query("SET SESSION SQL_MODE = 'ONLY_FULL_GROUP_BY'");
347  }
348  $this->setStorageEngine('MYISAM');
349  }
350 
355  public function now()
356  {
357  return "NOW()";
358  }
359 
360 
364  public function getDBVersion()
365  {
366  if (!$this->isMySQLi()) {
367  $vers = @mysql_get_server_info();
368  } else {
369  $vers = @mysqli_get_server_info($this->db->connection);
370  }
371  if (trim($vers) == "") {
372  $vers = "Unknown";
373  }
374  return $vers;
375  }
376 
377 
381  public function isMysql4_0OrHigher()
382  {
383  $version = explode(".", $this->getDBVersion());
384  if ((int) $version[0] < 4) {
385  return false;
386  }
387  return true;
388  }
389 
393  public function isMysql4_1()
394  {
395  $version = explode(".", $this->getDBVersion());
396  if ($version[0] == "4" && $version[1] == "1") {
397  return true;
398  }
399 
400  return false;
401  }
402 
410  public function isMysql4_1OrHigher()
411  {
412  $version = explode(".", $this->getDBVersion());
413  if ((int) $version[0] >= 5 ||
414  ((int) $version[0] == 4 && (int) $version[1] >= 1)) {
415  return true;
416  }
417 
418  return false;
419  }
420 
428  public function isMysql5_6OrHigher()
429  {
430  $version = explode(".", $this->getDBVersion());
431  if (
432  (int) $version[0] > 5 ||
433  ((int) $version[0] == 5 && (int) $version[1] >= 6)) {
434  return true;
435  }
436  return false;
437  }
438 
442  public function checkQuerySize($a_query)
443  {
444  global $lang;
445 
446  if (strlen($a_query) >= $this->max_allowed_packet_size) {
447  return false;
448  } else {
449  return true;
450  }
451  }
452 
458  protected function setMaxAllowedPacket()
459  {
460  $version = $this->getDBVersion();
461 
462  // CHANG VALUE IF MYSQL VERSION > 4.0
463  // Switched back to "SET GLOBAL ..."
464  // @see http://bugs.mysql.com/bug.php?id=22891
465  // smeyer 2009 07 30
466  if (substr($version, 0, 1) == "4") {
467  ini_get("post_max_size");
468  $query = "SET GLOBAL max_allowed_packet = " . (int) ini_get("post_max_size") * 1024 * 1024;
469  //echo "-".$query."-";
470  $this->query($query);
471  }
472  // STORE NEW max_size in member variable
473  $query = "SHOW VARIABLES LIKE 'max_allowed_packet'";
474  $res = $this->query($query);
475 
476  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
477  $this->max_allowed_packet_size = $row->value;
478  }
479  //echo "-".$this->max_allowed_packet_size."-";
480  return true;
481  }
482 
486  public function supportsFulltext()
487  {
488  return true;
489  }
490 
494  public function addFulltextIndex($a_table, $a_fields, $a_name = "in")
495  {
496  $i_name = $this->constraintName($a_table, $a_name) . "_idx";
497  $f_str = implode($a_fields, ",");
498  $q = "ALTER TABLE $a_table ADD FULLTEXT $i_name ($f_str)";
499  $this->query($q);
500  }
501 
505  public function dropFulltextIndex($a_table, $a_name)
506  {
507  $i_name = $this->constraintName($a_table, $a_name) . "_idx";
508  $this->query("ALTER TABLE $a_table DROP FULLTEXT $i_name");
509  }
510 
514  public function isFulltextIndex($a_table, $a_name)
515  {
516  $set = $this->query("SHOW INDEX FROM " . $a_table);
517  while ($rec = $this->fetchAssoc($set)) {
518  if ($rec["Key_name"] == $a_name && $rec["Index_type"] == "FULLTEXT") {
519  return true;
520  }
521  }
522  }
523 
534  public function lockTables($a_tables)
535  {
536  global $ilLog;
537 
538  $lock = 'LOCK TABLES ';
539 
540  $counter = 0;
541  foreach ($a_tables as $table) {
542  if ($counter++) {
543  $lock .= ', ';
544  }
545 
546  if (isset($table['sequence']) && $table['sequence']) {
547  $tableName = $this->db->getSequenceName($table['name']);
548  } else {
549  $tableName = $table['name'];
550  }
551 
552  $lock .= ($tableName . ' ');
553 
554  if ($table['alias']) {
555  $lock .= ($table['alias'] . ' ');
556  }
557 
558  switch ($table['type']) {
560  $lock .= ' READ ';
561  break;
562 
564  $lock .= ' WRITE ';
565  break;
566  }
567  }
568  if ($ilLog instanceof ilLog) {
569  $ilLog->write(__METHOD__ . ': ' . $lock);
570  }
571 
572  $this->query($lock);
573  }
574 
580  public function unlockTables()
581  {
582  $this->query('UNLOCK TABLES');
583  }
584 
585  protected function getCreateTableOptions()
586  {
587  // InnoDB is default engine for MySQL >= 5.5
588  return array('type' => 'MyISAM');
589  }
590 
591  public function getErrorNo()
592  {
593  if (!$this->isMySQLi()) {
594  return mysql_errno();
595  } else {
596  return mysqli_errno($this->db->connection);
597  }
598  }
599 
600  public function getLastError()
601  {
602  if (!$this->isMySQLi()) {
603  return mysql_error();
604  } else {
605  return mysqli_error($this->db->connection);
606  }
607  }
608 
609 
613  public function query($sql, $a_handle_error = true)
614  {
615  if (!$this->use_slave || !$this->getDBSlaveActive()) {
616  return parent::query($sql, $a_handle_error);
617  }
618 
619  $r = $this->slave->query($sql);
620 
621  if ($a_handle_error) {
622  return $this->handleError($r, "query(" . $sql . ")");
623  }
624 
625  return $r;
626  }
627 
628 
633  public function loadModule($module)
634  {
635  return $this->db->loadModule($module);
636  }
637 
638 
639  public function getStorageEngine()
640  {
641  return 'MyISAM';
642  }
643 
648  public function groupConcat($a_field_name, $a_seperator = ",", $a_order = null)
649  {
650  if ($a_order === null) {
651  $sql = "GROUP_CONCAT(" . $a_field_name . " SEPARATOR " . $this->quote($a_seperator, "text") . ")";
652  } else {
653  $sql = "GROUP_CONCAT(" . $a_field_name . " ORDER BY " . $a_order . " SEPARATOR " . $this->quote($a_seperator, "text") . ")";
654  }
655  return $sql;
656  }
657 }
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.
if($modEnd===false) $module
Definition: module.php:59
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.
foreach($_POST as $key=> $value) $res
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.
$query
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.
groupConcat($a_field_name, $a_seperator=",", $a_order=null)
string
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.
loadModule($module)
getDBPassword()
Get database password.
Definition: class.ilDB.php:143
if(empty($password)) $table
Definition: pwgen.php:24
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