4 require_once(
"./Services/Database/classes/PDO/class.ilPDOStatement.php");
5 require_once(
"./Services/Database/classes/QueryUtils/class.ilMySQLQueryUtils.php");
6 require_once(
'./Services/Database/classes/PDO/Manager/class.ilDBPdoManager.php');
7 require_once(
'./Services/Database/classes/PDO/Reverse/class.ilDBPdoReverse.php');
8 require_once(
'./Services/Database/interfaces/interface.ilDBInterface.php');
9 require_once(
'./Services/Database/classes/class.ilDBConstants.php');
10 require_once(
'./Services/Database/interfaces/interface.ilDBLegacyInterface.php');
80 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
101 public function connect($return_false_for_error =
false) {
109 $this->error_code = $e->getCode();
110 if ($return_false_for_error) {
116 return ($this->pdo->errorCode() == PDO::ERR_NONE);
171 public function createDatabase($a_name, $a_charset =
"utf8", $a_collation =
"") {
176 return $this->
query($this->manager->getQueryUtils()->createDatabase($a_name, $a_charset, $a_collation));
177 }
catch (PDOException $e) {
187 if ($this->pdo instanceof PDO) {
188 return $this->pdo->errorCode();
199 global $ilClientIniFile;
200 if ($tmpClientIniFile instanceof
ilIniFile) {
201 $clientIniFile = $tmpClientIniFile;
203 $clientIniFile = $ilClientIniFile;
206 $this->
setUsername($clientIniFile->readVariable(
"db",
"user"));
207 $this->
setHost($clientIniFile->readVariable(
"db",
"host"));
208 $this->
setPort((
int)$clientIniFile->readVariable(
"db",
"port"));
209 $this->
setPassword($clientIniFile->readVariable(
"db",
"pass"));
210 $this->
setDbname($clientIniFile->readVariable(
"db",
"name"));
211 $this->
setDBType($clientIniFile->readVariable(
"db",
"type"));
231 return '`' . $identifier .
'`';
241 $sequence_table_name = $table_name .
'_seq';
243 $last_insert_id = $this->pdo->lastInsertId($table_name);
244 if ($last_insert_id) {
249 $stmt = $this->pdo->prepare(
"SELECT sequence FROM $sequence_table_name");
251 $rows = $stmt->fetch(PDO::FETCH_ASSOC);
252 $stmt->closeCursor();
253 $next_id = $rows[
'sequence'] + 1;
254 $stmt = $this->pdo->prepare(
"DELETE FROM $sequence_table_name");
255 $stmt->execute(
array(
"next_id" => $next_id));
256 $stmt = $this->pdo->prepare(
"INSERT INTO $sequence_table_name (sequence) VALUES (:next_id)");
257 $stmt->execute(
array(
"next_id" => $next_id));
274 public function createTable($table_name, $fields, $drop_table =
false, $ignore_erros =
false) {
289 return $this->manager->createTable($table_name, $fields,
array());
298 foreach ($a_cols as $col => $def) {
332 return $this->field_definition->checkColumnDefinition($a_def);
341 return $this->field_definition->checkColumnName($a_name);
352 assert(is_array($primary_keys));
355 foreach ($primary_keys as $f) {
356 $fields[$f] =
array();
375 foreach ($this->manager->listTableIndexes($table_name) as $idx_name) {
376 $def = $this->reverse->getTableIndexDefinition($table_name, $idx_name);
377 $idx_fields = array_keys((
array)$def[
'fields']);
379 if ($idx_fields === $fields) {
380 return $this->
dropIndex($table_name, $idx_name);
401 $this->manager->createSequence($table_name,
$start);
411 $result = $this->pdo->prepare(
"SHOW TABLES LIKE :table_name");
429 $in_array = in_array($column_name, $fields);
444 throw new ilDatabaseException(
"ilDB Error: addTableColumn(" . $table_name .
", " . $column_name .
")");
447 throw new ilDatabaseException(
"ilDB Error: addTableColumn(" . $table_name .
", " . $column_name .
")");
456 return $this->manager->alterTable($table_name, $changes,
false);
466 public function dropTable($table_name, $error_if_not_existing =
true) {
468 $tables = $ilDBPdoManager->listTables();
469 $table_exists = in_array($table_name, $tables);
470 if (!$table_exists && $error_if_not_existing) {
475 $sequences = $ilDBPdoManager->listSequences();
476 if (in_array($table_name, $sequences)) {
477 $ilDBPdoManager->dropSequence($table_name);
482 $ilDBPdoManager->dropTable($table_name);
502 $ilBench->startDbBench(
$query);
505 if ($ilBench instanceof ilBenchmark) {
506 $ilBench->stopDbBench();
508 }
catch (PDOException $e) {
512 $err = $this->pdo->errorCode();
513 if ($err != PDO::ERR_NONE) {
514 $info = $this->pdo->errorInfo();
515 $info_message =
$info[2];
533 while (
$data = $query_result->fetch($fetch_mode)) {
545 $this->manager->dropSequence($table_name);
558 $column_name =>
array(),
562 return $this->manager->alterTable($table_name, $changes,
false);
576 throw new ilDatabaseException(
"ilDB Error: renameTableColumn(" . $table_name .
"," . $column_old_name .
"," . $column_new_name .
")");
579 $def = $this->reverse->getTableFieldDefinition($table_name, $column_old_name);
582 $best_alt = $analyzer->getBestDefinitionAlternative($def);
583 $def = $def[$best_alt];
584 unset($def[
"nativetype"]);
585 unset($def[
"mdb2type"]);
587 $f[
"definition"] = $def;
588 $f[
"name"] = $column_new_name;
592 $column_old_name => $f,
596 return $this->manager->alterTable($table_name, $changes,
false);
605 public function insert($table_name, $values) {
608 foreach ($values as $key => $val) {
609 $real[] = $this->
quote($val[1], $val[0]);
612 $values = implode(
",", $real);
613 $fields = implode(
",", $fields);
614 $query =
"INSERT INTO " . $table_name .
" (" . $fields .
") VALUES (" . $values .
")";
618 return $this->pdo->exec(
$query);
628 $res = $query_result->fetchObject();
630 $query_result->closeCursor();
647 $field_values =
array();
648 $placeholders =
array();
649 $placeholders_full =
array();
655 $field_value = $col[1];
657 $placeholders[] =
"%s";
658 $placeholders_full[] =
":$k";
661 if ($col[0] ==
"blob" || $col[0] ==
"clob" || $col[0] ==
'text') {
666 if ($col[0] ==
'integer' && !is_null($field_value)) {
667 $field_value = (int)$field_value;
670 $values[] = $field_value;
671 $field_values[$k] = $field_value;
672 if ($col[0] ==
"blob" || $col[0] ==
"clob") {
679 $q =
"UPDATE " . $table_name .
" SET ";
681 foreach ($fields as $k => $field) {
682 $q .= $lim . $field .
" = " . $placeholders_full[$k];
687 foreach ($where as $k => $col) {
688 $q .= $lim . $k .
" = " . $this->
quote($col[1], $col[0]);
696 foreach ($where as $k => $col) {
699 $field_values[$k] = $col;
701 $q =
"UPDATE " . $table_name .
" SET ";
703 foreach ($fields as $k => $field) {
704 $q .= $lim . $this->
quoteIdentifier($field) .
" = " . $placeholders[$k];
709 foreach ($where as $k => $col) {
710 $q .= $lim . $k .
" = %s";
736 if (
$ilBench instanceof ilBenchmark) {
739 }
catch (PDOException $e) {
753 $res = $query_result->fetch(PDO::FETCH_ASSOC);
755 $query_result->closeCursor();
770 return $query_result->rowCount();
780 public function quote($value, $type = null) {
781 if ($value === null) {
785 $pdo_type = PDO::PARAM_STR;
795 $value = (int)$value;
800 $pdo_type = PDO::PARAM_INT;
804 $pdo_type = PDO::PARAM_STR;
808 return $this->pdo->quote($value, $pdo_type);
819 foreach ($this->manager->listTableIndexes($table_name) as $idx_name) {
820 $def = $this->reverse->getTableIndexDefinition($table_name, $idx_name);
821 $idx_fields = array_keys((
array)$def[
'fields']);
823 if ($idx_fields === $fields) {
838 public function addIndex($table_name, $fields, $index_name =
'', $fulltext =
false) {
839 assert(is_array($fields));
840 $this->field_definition->checkIndexName($index_name);
842 $definition_fields =
array();
843 foreach ($fields as $f) {
844 $definition_fields[$f] =
array();
847 'fields' => $definition_fields,
851 $this->manager->createIndex($table_name, $this->
constraintName($table_name, $index_name), $definition);
871 $f_str = implode($a_fields,
",");
872 $q =
"ALTER TABLE $a_table ADD FULLTEXT $i_name ($f_str)";
882 $this->
query(
"ALTER TABLE $a_table DROP FULLTEXT $i_name");
890 $set = $this->
query(
"SHOW INDEX FROM " . $a_table);
892 if ($rec[
"Key_name"] == $a_name && $rec[
"Index_type"] ==
"FULLTEXT") {
925 return $a_constraint;
950 $this->db_type = $type;
964 return $ilDB->getFieldDefinition()->getReservedMysql();
973 assert(is_array($tables));
975 $lock = $this->manager->getQueryUtils()->lock($tables);
977 if ($ilLog instanceof
ilLog) {
978 $ilLog->write(
'ilDB::lockTables(): ' . $lock);
981 $this->pdo->exec($lock);
990 $this->pdo->exec($this->manager->getQueryUtils()->unlock());
1001 public function in($field, $values, $negate =
false, $type =
"") {
1002 return $this->manager->getQueryUtils()->in($field, $values, $negate, $type);
1014 if (!is_array($types) || !is_array($values) || count($types) != count($values)) {
1015 throw new ilDatabaseException(
"ilDB::queryF: Types and values must be arrays of same size. ($query)");
1017 $quoted_values =
array();
1018 foreach ($types as $k =>
$t) {
1019 $quoted_values[] = $this->
quote($values[$k],
$t);
1035 if (!is_array($types) || !is_array($values) || count($types) != count($values)) {
1036 throw new ilDatabaseException(
"ilDB::manipulateF: types and values must be arrays of same size. ($query)");
1038 $quoted_values =
array();
1039 foreach ($types as $k =>
$t) {
1040 $quoted_values[] = $this->
quote($values[$k],
$t);
1079 public function like(
$column, $type, $value =
"?", $case_insensitive =
true) {
1080 return $this->manager->getQueryUtils()->like(
$column, $type, $value, $case_insensitive);
1088 return $this->manager->getQueryUtils()->now();
1100 public function replace($table, $primaryKeys, $otherColumns) {
1101 $a_columns = array_merge($primaryKeys, $otherColumns);
1103 $field_values =
array();
1104 $placeholders =
array();
1108 foreach ($a_columns as $k => $col) {
1110 $placeholders[] =
"%s";
1111 $placeholders2[] =
":$k";
1115 if ($col[0] ==
'integer' && !is_null($col[1])) {
1116 $col[1] = (int)$col[1];
1119 $values[] = $col[1];
1120 $field_values[$k] = $col[1];
1123 $q =
"REPLACE INTO " . $table .
" (" . implode($fields,
",") .
") VALUES (" . implode($placeholders,
",") .
")";
1139 if (!$emptyOrNull || $value !=
"") {
1142 return "(" .
$columns .
" = '' OR $columns IS NULL)";
1159 $this->host =
$host;
1239 $this->port =
$port;
1280 return " UPPER(" . $a_exp .
") ";
1289 return " LOWER(" . $a_exp .
") ";
1299 public function substr($a_exp, $a_pos = 1, $a_len = -1) {
1302 $lenstr =
", " . $a_len;
1305 return " SUBSTR(" . $a_exp .
", " . $a_pos . $lenstr .
") ";
1334 $this->pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, $a_status);
1386 case self::FEATURE_TRANSACTIONS:
1388 case self::FEATURE_FULLTEXT:
1390 case self::FEATURE_SLAVE:
1402 return $this->manager->listTables();
1424 return $this->field_definition->getAllowedAttributes();
1441 return $this->manager->listSequences();
1451 return $this->manager->getQueryUtils()->concat($values, $allow_null);
1460 if ($this->limit !== null && $this->offset !== null) {
1462 $this->limit = null;
1463 $this->offset = null;
1478 public function locate($a_needle, $a_string, $a_start_pos = 1) {
1479 return $this->manager->getQueryUtils()->locate($a_needle, $a_string, $a_start_pos);
1491 $def = $this->reverse->getTableFieldDefinition($table, $a_column);
1494 $best_alt = $analyzer->getBestDefinitionAlternative($def);
1495 $def = $def[$best_alt];
1496 unset($def[
"nativetype"]);
1497 unset($def[
"mdb2type"]);
1502 $type = ($a_attributes[
"type"] !=
"") ? $a_attributes[
"type"] : $def[
"type"];
1503 foreach ($def as $k => $v) {
1504 if ($k !=
"type" && !$ilDBPdoFieldDefinition->isAllowedAttribute($k, $type)) {
1508 $check_array = $def;
1509 foreach ($a_attributes as $k => $v) {
1510 $check_array[$k] = $v;
1513 throw new ilDatabaseException(
"ilDB Error: modifyTableColumn(" . $table .
", " . $a_column .
")");
1516 foreach ($a_attributes as $a => $v) {
1520 $a_attributes[
"definition"] = $def;
1524 $a_column => $a_attributes,
1528 return $this->manager->alterTable($table, $changes,
false);
1536 public function free($a_st) {
1540 return $a_st->closeCursor();
1555 throw new ilDatabaseException(
"ilDB Error: renameTable(" . $a_name .
"," . $a_new_name .
")<br />" . $e->getMessage());
1558 $this->manager->alterTable($a_name,
array(
"name" => $a_new_name),
false);
1575 return $this->field_definition->checkTableName($a_name);
1584 require_once(
'./Services/Database/classes/PDO/FieldDefinition/class.ilDBPdoMySQLFieldDefinition.php');
1588 return $ilDBPdoMySQLFieldDefinition->isReserved($a_word);
1597 if (!$this->
supports(self::FEATURE_TRANSACTIONS)) {
1601 return $this->pdo->beginTransaction();
1610 if (!$this->
supports(self::FEATURE_TRANSACTIONS)) {
1614 return $this->pdo->commit();
1623 if (!$this->
supports(self::FEATURE_TRANSACTIONS)) {
1627 return $this->pdo->rollBack();
1637 return $this->manager->dropIndex($a_table, $a_name);
1666 $type = PDO::FETCH_ASSOC;
1669 $type = PDO::FETCH_OBJ;
1672 $type = PDO::FETCH_ASSOC;
1676 return $this->pdo->query(
$query, PDO::FETCH_ASSOC)->fetchAll(PDO::FETCH_COLUMN, $colnum);
1687 switch ($fetchmode) {
1689 $type = PDO::FETCH_ASSOC;
1692 $type = PDO::FETCH_OBJ;
1695 $type = PDO::FETCH_ASSOC;
1699 return $this->pdo->query(
$query, $type)->fetch();
1708 return $this->pdo->query(
'SELECT VERSION()')->fetchColumn();
1717 public function escape($value, $escape_wildcards =
false) {
1782 assert(is_array($fields));
1787 throw new ilDatabaseException(
"ilDB Error: addUniqueConstraint(" . $table .
"," . $name .
")");
1790 $fields_corrected =
array();
1791 foreach ($fields as $f) {
1792 $fields_corrected[$f] =
array();
1794 $definition =
array(
1796 'fields' => $fields_corrected,
1809 return $this->manager->dropConstraint($a_table, $this->
constraintName($a_table, $a_name),
false);
1820 $cons = $analyzer->getConstraintsInformation($a_table);
1821 foreach ($cons as $c) {
1822 if ($c[
"type"] ==
"unique" && count($a_fields) == count($c[
"fields"])) {
1824 foreach ($a_fields as $f) {
1825 if (!isset($c[
"fields"][$f])) {
1843 return $this->pdo->lastInsertId();
1851 require_once(
'./Services/Database/classes/Atom/class.ilAtomQueryLock.php');
1863 require_once(
'./Services/Database/classes/class.ilDBAnalyzer.php');
1865 $cons = $analyzer->getConstraintsInformation($table);
1866 foreach ($cons as $c) {
1867 if ($c[
"type"] ==
"unique" && count($fields) == count($c[
"fields"])) {
1869 foreach ($fields as $f) {
1870 if (!isset($c[
"fields"][$f])) {
1889 return $this->manager->dropConstraint($table_name,
"PRIMARY",
true);
1898 for ($i = 0, $j = count($a_data); $i < $j; $i++) {
1899 $stmt->execute($a_data[$i]);
1910 return "FROM_UNIXTIME(" . $a_expr .
")";
1918 return "UNIX_TIMESTAMP()";
1938 $fields_values = (
array)$fields;
1940 if (!empty($fields_values)) {
1941 $keys = $fields_values;
1946 $keys = array_keys($fields_values);
1948 $params = array_values($fields_values);
1953 $stmt = $this->
autoPrepare($tablename, $keys, $mode, $where, $types, $result_types);
1987 protected function buildManipSQL($table, $table_fields, $mode, $where =
false) {
1988 if ($this->options[
'quote_identifier']) {
1992 if (!empty($table_fields) && $this->options[
'quote_identifier']) {
1993 foreach ($table_fields as $key => $field) {
1998 if ($where !==
false && !is_null($where)) {
1999 if (is_array($where)) {
2000 $where = implode(
' AND ', $where);
2002 $where =
' WHERE ' . $where;
2007 if (empty($table_fields)) {
2010 $cols = implode(
', ', $table_fields);
2011 $values =
'?' . str_repeat(
', ?', (count($table_fields) - 1));
2013 return 'INSERT INTO ' . $table .
' (' . $cols .
') VALUES (' . $values .
')';
2016 if (empty($table_fields)) {
2019 $set = implode(
' = ?, ', $table_fields) .
' = ?';
2020 $sql =
'UPDATE ' . $table .
' SET ' . $set . $where;
2025 $sql =
'DELETE FROM ' . $table . $where;
2030 $cols = !empty($table_fields) ? implode(
', ', $table_fields) :
'*';
2031 $sql =
'SELECT ' . $cols .
' FROM ' . $table . $where;
2048 return (
$d->version ?
$d->version :
'Unknown');
2058 $query_replaced = preg_replace(
2061 if (!empty($query_replaced)) {
2062 return $query_replaced;
2081 public function groupConcat($a_field_name, $a_seperator =
",", $a_order = NULL) {
2082 return $this->manager->getQueryUtils()->groupConcat($a_field_name, $a_seperator, $a_order);
2088 public function cast($a_field_name, $a_dest_type) {
2089 return $this->manager->getQueryUtils()->cast($a_field_name, $a_dest_type);
sanitizeMB4StringIfNotSupported($query)
string to sanitize, all MB4-Characters like emojis will re replaced with ???string sanitized query ...
addPrimaryKey($table_name, $primary_keys)
setFieldDefinition($field_definition)
addIndex($table_name, $fields, $index_name='', $fulltext=false)
static getReservedWords()
Get reserved words.
getSequenceName($table_name)
doesCollationSupportMB4Strings()
equals($columns, $value, $type, $emptyOrNull=false)
execute($stmt, $data=array())
Class ilPDOStatement is a Wrapper Class for PDOStatement.
like($column, $type, $value="?", $case_insensitive=true)
const MYSQL_COLLATION_UTF8MB4
queryF($query, $types, $values)
getServerVersion($native=false)
escape($value, $escape_wildcards=false)
Interface ilDBPdoInterface.
dropUniqueConstraint($a_table, $a_name="con")
supportsCollationMigration()
dropSequence($table_name)
sequenceExists($sequence)
update($table_name, $columns, $where)
renameTableColumn($table_name, $column_old_name, $column_new_name)
queryCol($query, $type=PDO::FETCH_ASSOC, $colnum=0)
concat(array $values, $allow_null=true)
quote($value, $type=null)
modifyTableColumn($table, $a_column, $a_attributes)
autoPrepare($table, $table_fields, $mode=ilDBConstants::MDB2_AUTOQUERY_INSERT, $where=false, $types=null, $result_types=ilDBConstants::MDB2_PREPARE_MANIP)
Class ilDatabaseException.
executeMultiple($stmt, $a_data)
dropFulltextIndex($a_table, $a_name)
Drop fulltext index.
for($col=0; $col< 50; $col++) $d
indexExistsByFields($table_name, $fields)
migrateAllTablesToCollation($collation=ilDBConstants::MYSQL_COLLATION_UTF8MB4)
manipulateF($query, $types, $values)
addFulltextIndex($a_table, $a_fields, $a_name="in")
getAdditionalAttributes()
const MDB2_AUTOQUERY_UPDATE
dropTable($table_name, $error_if_not_existing=true)
checkTableColumns($a_cols)
queryRow($query, $types=null, $fetchmode=ilDBConstants::FETCHMODE_DEFAULT)
quoteIdentifier($identifier, $check_option=false)
if(!is_array($argv)) $options
dropUniqueConstraintByFields($a_table, $a_fields)
isFulltextIndex($a_table, $a_name)
Is index a fulltext index?
replace($table, $primaryKeys, $otherColumns)
Replace into method.
static isReservedWord($a_word)
createTable($table_name, $fields, $drop_table=false, $ignore_erros=false)
fetchAssoc($query_result)
createDatabase($a_name, $a_charset="utf8", $a_collation="")
autoExecute($tablename, $fields, $mode=ilDBConstants::MDB2_AUTOQUERY_INSERT, $where=false)
Generate an insert, update or delete query and call prepare() and execute() on it.
const MYSQL_ENGINE_INNODB
tableColumnExists($table_name, $column_name)
dropPrimaryKey($table_name)
supportsEngineMigration()
setLimit($limit, $offset=0)
Set the Limit for the next Query.
groupConcat($a_field_name, $a_seperator=",", $a_order=NULL)
string
dropTableColumn($table_name, $column_name)
dropIndexByFields($table_name, $fields)
checkColumn($a_col, $a_def)
Create styles array
The data for the language used.
constraintName($a_table, $a_constraint)
Determine contraint name by table name and constraint name.
prepareManip($query, $types=null)
getPrimaryKeyIdentifier()
Class ilDBPdoMySQLFieldDefinition.
createSequence($table_name, $start=1)
in($field, $values, $negate=false, $type="")
getAllowedAttributes()
array
buildManipSQL($table, $table_fields, $mode, $where=false)
setStorageEngine($storage_engine)
addUniqueConstraint($table, $fields, $name="con")
const FEATURE_TRANSACTIONS
const MDB2_AUTOQUERY_SELECT
addTableColumn($table_name, $column_name, $attributes)
locate($a_needle, $a_string, $a_start_pos=1)
fromUnixtime($a_expr, $a_to_text=true)
enableResultBuffering($a_status)
const MDB2_AUTOQUERY_INSERT
performance measurement class
insert($table_name, $values)
cast($a_field_name, $a_dest_type)
string;
This class gives all kind of DB information using the MDB2 manager and reverse module.
connect($return_false_for_error=false)
uniqueConstraintExists($table, array $fields)
renameTable($a_name, $a_new_name)
dropIndex($a_table, $a_name="i1")
migrateAllTablesToEngine($engine=ilDBConstants::MYSQL_ENGINE_INNODB)
prepare($query, $types=null, $result_types=null)
fetchObject($query_result)
substr($a_exp, $a_pos=1, $a_len=-1)
initFromIniFile($tmpClientIniFile=null)
fetchAll($query_result, $fetch_mode=ilDBConstants::FETCHMODE_ASSOC)
getIndexName($index_name_base)
const MDB2_AUTOQUERY_DELETE
checkColumnDefinition($a_def, $a_modify_mode=false)