2 namespace TYPO3\CMS\Core\Database;
178 'empty' =>
'0000-00-00',
182 'empty' =>
'0000-00-00 00:00:00',
183 'format' =>
'Y-m-d H:i:s'
219 public function exec_INSERTquery($table, $fields_values, $no_quote_fields =
false)
221 $res = $this->
query($this->
INSERTquery($table, $fields_values, $no_quote_fields));
222 if ($this->debugOutput) {
223 $this->
debug(
'exec_INSERTquery');
225 foreach ($this->postProcessHookObjects as $hookObject) {
227 $hookObject->exec_INSERTquery_postProcessAction($table, $fields_values, $no_quote_fields, $this);
241 public function exec_INSERTmultipleRows($table, array $fields, array $rows, $no_quote_fields =
false)
243 $res = $this->
query($this->INSERTmultipleRows($table, $fields, $rows, $no_quote_fields));
244 if ($this->debugOutput) {
245 $this->
debug(
'exec_INSERTmultipleRows');
247 foreach ($this->postProcessHookObjects as $hookObject) {
249 $hookObject->exec_INSERTmultipleRows_postProcessAction($table, $fields, $rows, $no_quote_fields, $this);
264 public function exec_UPDATEquery($table, $where, $fields_values, $no_quote_fields =
false)
266 $res = $this->
query($this->UPDATEquery($table, $where, $fields_values, $no_quote_fields));
267 if ($this->debugOutput) {
268 $this->
debug(
'exec_UPDATEquery');
270 foreach ($this->postProcessHookObjects as $hookObject) {
272 $hookObject->exec_UPDATEquery_postProcessAction($table, $where, $fields_values, $no_quote_fields, $this);
284 public function exec_DELETEquery($table, $where)
286 $res = $this->
query($this->DELETEquery($table, $where));
287 if ($this->debugOutput) {
288 $this->
debug(
'exec_DELETEquery');
290 foreach ($this->postProcessHookObjects as $hookObject) {
292 $hookObject->exec_DELETEquery_postProcessAction($table, $where, $this);
309 public function exec_SELECTquery($select_fields, $from_table, $where_clause, $groupBy =
'', $orderBy =
'', $limit =
'')
311 $query = $this->SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit);
312 $res = $this->
query($query);
313 if ($this->debugOutput) {
314 $this->
debug(
'exec_SELECTquery');
316 if ($this->explainOutput) {
317 $this->
explain($query, $from_table, $res->num_rows);
319 foreach ($this->postProcessHookObjects as $hookObject) {
321 $hookObject->exec_SELECTquery_postProcessAction($select_fields, $from_table, $where_clause, $groupBy =
'', $orderBy =
'', $limit =
'', $this);
343 public function exec_SELECT_mm_query($select, $local_table, $mm_table, $foreign_table, $whereClause =
'', $groupBy =
'', $orderBy =
'', $limit =
'')
345 $queryParts = $this->
getSelectMmQueryParts($select, $local_table, $mm_table, $foreign_table, $whereClause, $groupBy, $orderBy, $limit);
358 return $this->exec_SELECTquery($queryParts[
'SELECT'], $queryParts[
'FROM'], $queryParts[
'WHERE'], $queryParts[
'GROUPBY'], $queryParts[
'ORDERBY'], $queryParts[
'LIMIT']);
375 public function exec_SELECTgetRows($select_fields, $from_table, $where_clause, $groupBy =
'', $orderBy =
'', $limit =
'', $uidIndexField =
'')
377 $res = $this->exec_SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit);
385 if ($uidIndexField) {
387 $firstRecord =
false;
388 if (!array_key_exists($uidIndexField, $record)) {
390 throw new \InvalidArgumentException(
'The given $uidIndexField "' . $uidIndexField .
'" is not available in the result.', 1432933855);
393 $output[$record[$uidIndexField]] = $record;
414 public function exec_SELECTgetSingleRow($select_fields, $from_table, $where_clause, $groupBy =
'', $orderBy =
'', $numIndex =
false)
416 $res = $this->exec_SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy,
'1');
418 if ($res !==
false) {
440 $resultSet = $this->exec_SELECTquery(
'COUNT(' . $field .
')', $table, $where);
441 if ($resultSet !==
false) {
443 $count = (int)$count;
455 public function exec_TRUNCATEquery($table)
457 $res = $this->
query($this->TRUNCATEquery($table));
458 if ($this->debugOutput) {
459 $this->
debug(
'exec_TRUNCATEquery');
461 foreach ($this->postProcessHookObjects as $hookObject) {
463 $hookObject->exec_TRUNCATEquery_postProcessAction($table, $this);
480 return $this->link->query($query);
496 public function INSERTquery($table, $fields_values, $no_quote_fields =
false)
500 if (!is_array($fields_values) || empty($fields_values)) {
503 foreach ($this->preProcessHookObjects as $hookObject) {
504 $hookObject->INSERTquery_preProcessAction($table, $fields_values, $no_quote_fields, $this);
507 $fields_values = $this->
fullQuoteArray($fields_values, $table, $no_quote_fields,
true);
509 $query =
'INSERT INTO ' . $table .
' (' . implode(
',', array_keys($fields_values)) .
') VALUES ' .
'(' . implode(
',', $fields_values) .
')';
511 if ($this->debugOutput || $this->store_lastBuiltQuery) {
512 $this->debug_lastBuiltQuery = $query;
526 public function INSERTmultipleRows($table, array $fields, array $rows, $no_quote_fields =
false)
533 foreach ($this->preProcessHookObjects as $hookObject) {
535 $hookObject->INSERTmultipleRows_preProcessAction($table, $fields, $rows, $no_quote_fields, $this);
538 $query =
'INSERT INTO ' . $table .
' (' . implode(
', ', $fields) .
') VALUES ';
540 foreach ($rows as $row) {
543 $rowSQL[] =
'(' . implode(
', ', $row) .
')';
545 $query .= implode(
', ', $rowSQL);
547 if ($this->debugOutput || $this->store_lastBuiltQuery) {
548 $this->debug_lastBuiltQuery = $query;
564 public function UPDATEquery($table, $where, $fields_values, $no_quote_fields =
false)
568 if (is_string($where)) {
569 foreach ($this->preProcessHookObjects as $hookObject) {
571 $hookObject->UPDATEquery_preProcessAction($table, $where, $fields_values, $no_quote_fields, $this);
574 if (is_array($fields_values) && !empty($fields_values)) {
576 $nArr = $this->
fullQuoteArray($fields_values, $table, $no_quote_fields,
true);
577 foreach ($nArr as $k => $v) {
578 $fields[] = $k .
'=' . $v;
582 $query =
'UPDATE ' . $table .
' SET ' . implode(
',', $fields) . ((string)$where !==
'' ?
' WHERE ' . $where :
'');
583 if ($this->debugOutput || $this->store_lastBuiltQuery) {
584 $this->debug_lastBuiltQuery = $query;
588 throw new \InvalidArgumentException(
'TYPO3 Fatal Error: "Where" clause argument for UPDATE query was not a string in $this->UPDATEquery() !', 1270853880);
600 public function DELETEquery($table, $where)
602 if (is_string($where)) {
603 foreach ($this->preProcessHookObjects as $hookObject) {
605 $hookObject->DELETEquery_preProcessAction($table, $where, $this);
608 $query =
'DELETE FROM ' . $table . ((string)$where !==
'' ?
' WHERE ' . $where :
'');
609 if ($this->debugOutput || $this->store_lastBuiltQuery) {
610 $this->debug_lastBuiltQuery = $query;
614 throw new \InvalidArgumentException(
'TYPO3 Fatal Error: "Where" clause argument for DELETE query was not a string in $this->DELETEquery() !', 1270853881);
629 public function SELECTquery($select_fields, $from_table, $where_clause, $groupBy =
'', $orderBy =
'', $limit =
'')
631 foreach ($this->preProcessHookObjects as $hookObject) {
633 $hookObject->SELECTquery_preProcessAction($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit, $this);
637 $query =
'SELECT ' . $select_fields .
' FROM ' . $from_table . ((string)$where_clause !==
'' ?
' WHERE ' . $where_clause :
'');
639 $query .= (string)$groupBy !==
'' ?
' GROUP BY ' . $groupBy :
'';
641 $query .= (string)$orderBy !==
'' ?
' ORDER BY ' . $orderBy :
'';
643 $query .= (string)$limit !==
'' ?
' LIMIT ' . $limit :
'';
645 if ($this->debugOutput || $this->store_lastBuiltQuery) {
646 $this->debug_lastBuiltQuery = $query;
664 $query =
'SELECT ' . $select_fields .
' FROM ' . $from_table . ((string)$where_clause !==
'' ?
' WHERE ' . $where_clause :
'');
666 if ($this->debugOutput || $this->store_lastBuiltQuery) {
667 $this->debug_lastBuiltQuery = $query;
689 public function SELECT_mm_query($select, $local_table, $mm_table, $foreign_table, $whereClause =
'', $groupBy =
'', $orderBy =
'', $limit =
'')
691 $queryParts = $this->
getSelectMmQueryParts($select, $local_table, $mm_table, $foreign_table, $whereClause, $groupBy, $orderBy, $limit);
692 return $this->SELECTquery($queryParts[
'SELECT'], $queryParts[
'FROM'], $queryParts[
'WHERE'], $queryParts[
'GROUPBY'], $queryParts[
'ORDERBY'], $queryParts[
'LIMIT']);
701 public function TRUNCATEquery($table)
703 foreach ($this->preProcessHookObjects as $hookObject) {
705 $hookObject->TRUNCATEquery_preProcessAction($table, $this);
709 $query =
'TRUNCATE TABLE ' . $table;
711 if ($this->debugOutput || $this->store_lastBuiltQuery) {
712 $this->debug_lastBuiltQuery = $query;
734 $value = (string)$value;
735 if (strpos($value,
',') !==
false) {
736 throw new \InvalidArgumentException(
'$value must not contain a comma (,) in $this->listQuery() !', 1294585862);
738 $pattern = $this->
quoteStr($value, $table);
739 $where =
'FIND_IN_SET(\'' . $pattern .
'\',
' . $field . ')
';
752 public function searchQuery($searchWords, $fields, $table, $constraint = self::AND_Constraint)
754 switch ($constraint) {
755 case self::OR_Constraint:
762 $queryParts = array();
763 foreach ($searchWords as $sw) {
765 $queryParts[] = $table .
'.' . implode(($like .
' OR ' . $table .
'.'), $fields) . $like;
767 $query =
'(' . implode(
') ' . $constraint .
' (', $queryParts) .
')';
789 public function prepare_SELECTquery($select_fields, $from_table, $where_clause, $groupBy =
'', $orderBy =
'', $limit =
'', array $input_parameters = array())
791 $query = $this->SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit);
795 foreach ($input_parameters as $key => $value) {
799 return $preparedStatement;
809 public function prepare_SELECTqueryArray(array $queryParts, array $input_parameters = array())
811 return $this->prepare_SELECTquery($queryParts[
'SELECT'], $queryParts[
'FROM'], $queryParts[
'WHERE'], $queryParts[
'GROUPBY'], $queryParts[
'ORDERBY'], $queryParts[
'LIMIT'], $input_parameters);
822 public function prepare_PREPAREDquery($query, array $queryComponents)
824 if (!$this->isConnected) {
827 $stmt = $this->link->stmt_init();
828 $success = $stmt->prepare($query);
829 if ($this->debugOutput) {
830 $this->
debug(
'stmt_execute', $query);
832 return $success ? $stmt : null;
854 public function fullQuoteStr($str, $table, $allowNull =
false)
856 if (!$this->isConnected) {
859 if ($allowNull && $str === null) {
866 return '\'' . $this->link->real_escape_string($str) .
'\'';
879 public function fullQuoteArray($arr, $table, $noQuote =
false, $allowNull =
false)
881 if (is_string($noQuote)) {
882 $noQuote = explode(
',', $noQuote);
883 }
elseif (!is_array($noQuote)) {
886 foreach ($arr as $k => $v) {
887 if ($noQuote ===
false || !in_array($k, $noQuote)) {
888 $arr[$k] = $this->fullQuoteStr($v, $table, $allowNull);
904 public function quoteStr($str, $table)
906 if (!$this->isConnected) {
909 return $this->link->real_escape_string($str);
920 public function escapeStrForLike($str, $table)
922 return addcslashes($str,
'_%');
933 public function cleanIntArray($arr)
935 return array_map(
'intval', $arr);
960 public function stripOrderBy($str)
962 return preg_replace(
'/^(?:ORDER[[:space:]]*BY[[:space:]]*)+/i',
'', trim($str));
974 public function stripGroupBy($str)
976 return preg_replace(
'/^(?:GROUP[[:space:]]*BY[[:space:]]*)+/i',
'', trim($str));
987 public function splitGroupOrderLimit($str)
1002 if (preg_match(
'/^(.*)[[:space:]]+LIMIT[[:space:]]+([[:alnum:][:space:],._]+)$/i', $str, $reg)) {
1003 $wgolParts[
'LIMIT'] = trim($reg[2]);
1008 if (preg_match(
'/^(.*)[[:space:]]+ORDER[[:space:]]+BY[[:space:]]+([[:alnum:][:space:],._]+)$/i', $str, $reg)) {
1009 $wgolParts[
'ORDERBY'] = trim($reg[2]);
1014 if (preg_match(
'/^(.*)[[:space:]]+GROUP[[:space:]]+BY[[:space:]]+([[:alnum:][:space:],._]+)$/i', $str, $reg)) {
1015 $wgolParts[
'GROUPBY'] = trim($reg[2]);
1019 $wgolParts[
'WHERE'] = $str;
1029 public function getDateTimeFormats($table)
1031 return self::$dateTimeFormats;
1050 protected function getSelectMmQueryParts($select, $local_table, $mm_table, $foreign_table, $whereClause =
'', $groupBy =
'', $orderBy =
'', $limit =
'')
1053 $mmWhere = $local_table ? $local_table .
'.uid=' . $mm_table .
'.uid_local' :
'';
1054 $mmWhere .= ($local_table and $foreign_table) ?
' AND ' :
'';
1055 $tables = ($local_table ? $local_table .
',' :
'') . $mm_table;
1056 if ($foreign_table) {
1057 $mmWhere .= ($foreign_table_as ?: $foreign_table) .
'.uid=' . $mm_table .
'.uid_foreign';
1058 $tables .=
',' . $foreign_table . ($foreign_table_as ?
' AS ' . $foreign_table_as :
'');
1061 'SELECT' => $select,
1063 'WHERE' => $mmWhere .
' ' . $whereClause,
1064 'GROUPBY' => $groupBy,
1065 'ORDERBY' => $orderBy,
1085 public function sql_query($query)
1087 $res = $this->query($query);
1088 if ($this->debugOutput) {
1089 $this->
debug(
'sql_query', $query);
1099 public function sql_error()
1101 return $this->link->error;
1109 public function sql_errno()
1111 return $this->link->errno;
1120 public function sql_num_rows($res)
1122 if ($this->debug_check_recordset($res)) {
1123 return $res->num_rows;
1136 public function sql_fetch_assoc($res)
1138 if ($this->debug_check_recordset($res)) {
1139 $result = $res->fetch_assoc();
1140 if ($result === null) {
1158 public function sql_fetch_row($res)
1160 if ($this->debug_check_recordset($res)) {
1161 $result = $res->fetch_row();
1162 if ($result === null) {
1179 public function sql_free_result($res)
1181 if ($this->debug_check_recordset($res) && is_object($res)) {
1194 public function sql_insert_id()
1196 return $this->link->insert_id;
1204 public function sql_affected_rows()
1206 return $this->link->affected_rows;
1216 public function sql_data_seek($res, $seek)
1218 if ($this->debug_check_recordset($res)) {
1219 return $res->data_seek($seek);
1233 public function sql_field_type($res, $pointer)
1238 $mysql_data_type_hash = array(
1257 if ($this->debug_check_recordset($res)) {
1258 $metaInfo = $res->fetch_field_direct($pointer);
1259 if ($metaInfo ===
false) {
1262 return $mysql_data_type_hash[$metaInfo->type];
1274 public function sql_pconnect()
1276 if ($this->isConnected) {
1280 if (!extension_loaded(
'mysqli')) {
1281 throw new \RuntimeException(
1282 'Database Error: PHP mysqli extension not loaded. This is a must have for TYPO3 CMS!',
1287 $host = $this->persistentDatabaseConnection
1288 ?
'p:' . $this->databaseHost
1289 : $this->databaseHost;
1291 $this->link = mysqli_init();
1292 $connected = $this->link->real_connect(
1294 $this->databaseUsername,
1295 $this->databaseUserPassword,
1297 (
int)$this->databasePort,
1298 $this->databaseSocket,
1299 $this->connectionCompression ? MYSQLI_CLIENT_COMPRESS : 0
1303 $this->isConnected =
true;
1305 if ($this->link->set_charset($this->connectionCharset) ===
false) {
1306 GeneralUtility::sysLog(
1307 'Error setting connection charset to "' . $this->connectionCharset .
'"',
1313 foreach ($this->initializeCommandsAfterConnect as $command) {
1314 if ($this->query($command) ===
false) {
1315 GeneralUtility::sysLog(
1316 'Could not initialize DB connection with query "' . $command .
'": ' . $this->sql_error(),
1322 $this->checkConnectionCharset();
1325 $error_msg = $this->link->connect_error;
1327 GeneralUtility::sysLog(
1328 'Could not connect to MySQL server ' . $host .
' with user ' . $this->databaseUsername .
': ' . $error_msg,
1341 public function sql_select_db()
1343 if (!$this->isConnected) {
1347 $ret = $this->link->select_db($this->databaseName);
1349 GeneralUtility::sysLog(
1350 'Could not select MySQL database ' . $this->databaseName .
': ' . $this->sql_error(),
1373 public function admin_get_dbs()
1376 $db_list = $this->query(
"SELECT SCHEMA_NAME FROM information_schema.SCHEMATA");
1377 if ($db_list ===
false) {
1378 throw new \RuntimeException(
1379 'MySQL Error: Cannot get tablenames: "' . $this->sql_error() .
'"!',
1383 while ($row = $db_list->fetch_object()) {
1385 $this->setDatabaseName($row->SCHEMA_NAME);
1386 if ($this->sql_select_db()) {
1387 $dbArr[] = $row->SCHEMA_NAME;
1389 }
catch (\RuntimeException $exception) {
1406 public function admin_get_tables()
1408 $whichTables = array();
1409 $tables_result = $this->query(
'SHOW TABLE STATUS FROM `' . $this->databaseName .
'`');
1410 if ($tables_result !==
false) {
1411 while ($theTable = $tables_result->fetch_assoc()) {
1412 $whichTables[$theTable[
'Name']] = $theTable;
1414 $tables_result->free();
1416 return $whichTables;
1430 public function admin_get_fields($tableName)
1433 $columns_res = $this->query(
'SHOW FULL COLUMNS FROM `' . $tableName .
'`');
1434 if ($columns_res !==
false) {
1435 while ($fieldRow = $columns_res->fetch_assoc()) {
1436 $output[$fieldRow[
'Field']] = $fieldRow;
1438 $columns_res->free();
1450 public function admin_get_keys($tableName)
1453 $keyRes = $this->query(
'SHOW KEYS FROM `' . $tableName .
'`');
1454 if ($keyRes !==
false) {
1455 while ($keyRow = $keyRes->fetch_assoc()) {
1456 $output[] = $keyRow;
1475 public function admin_get_charsets()
1478 $columns_res = $this->query(
'SHOW CHARACTER SET');
1479 if ($columns_res !==
false) {
1480 while ($row = $columns_res->fetch_assoc()) {
1481 $output[$row[
'Charset']] = $row;
1483 $columns_res->free();
1494 public function admin_query($query)
1496 $res = $this->query($query);
1497 if ($this->debugOutput) {
1498 $this->
debug(
'admin_query', $query);
1514 public function setDatabaseHost($host =
'localhost')
1516 $this->disconnectIfConnected();
1517 $this->databaseHost = $host;
1525 public function setDatabasePort($port = 3306)
1527 $this->disconnectIfConnected();
1528 $this->databasePort = (int)$port;
1536 public function setDatabaseSocket($socket = null)
1538 $this->disconnectIfConnected();
1539 $this->databaseSocket = $socket;
1547 public function setDatabaseName($name)
1549 $this->disconnectIfConnected();
1550 $this->databaseName = $name;
1558 public function setDatabaseUsername($username)
1560 $this->disconnectIfConnected();
1561 $this->databaseUsername = $username;
1569 public function setDatabasePassword($password)
1571 $this->disconnectIfConnected();
1572 $this->databaseUserPassword = $password;
1581 public function setPersistentDatabaseConnection($persistentDatabaseConnection)
1583 $this->disconnectIfConnected();
1584 $this->persistentDatabaseConnection = (bool)$persistentDatabaseConnection;
1592 public function setConnectionCompression($connectionCompression)
1594 $this->disconnectIfConnected();
1595 $this->connectionCompression = (bool)$connectionCompression;
1603 public function setInitializeCommandsAfterConnect(array $commands)
1605 $this->disconnectIfConnected();
1606 $this->initializeCommandsAfterConnect = $commands;
1618 public function setConnectionCharset($connectionCharset =
'utf8')
1620 $this->disconnectIfConnected();
1621 $this->connectionCharset = $connectionCharset;
1631 public function connectDB()
1634 if ($this->isConnected) {
1638 if (!$this->databaseName) {
1639 throw new \RuntimeException(
1640 'TYPO3 Fatal Error: No database selected!',
1645 if ($this->sql_pconnect()) {
1646 if (!$this->sql_select_db()) {
1647 throw new \RuntimeException(
1648 'TYPO3 Fatal Error: Cannot connect to the current database, "' . $this->databaseName .
'"!',
1653 throw new \RuntimeException(
1654 'TYPO3 Fatal Error: The current username, password or host was not accepted when the connection to the database was attempted to be established!',
1660 $this->preProcessHookObjects = array();
1661 $this->postProcessHookObjects = array();
1662 if (is_array(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_db.php'][
'queryProcessors'])) {
1663 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_db.php'][
'queryProcessors'] as $classRef) {
1669 throw new \UnexpectedValueException(
1670 '$hookObject must either implement interface TYPO3\\CMS\\Core\\Database\\PreProcessQueryHookInterface or interface TYPO3\\CMS\\Core\\Database\\PostProcessQueryHookInterface',
1675 $this->preProcessHookObjects[] = $hookObject;
1677 if ($hookObject instanceof PostProcessQueryHookInterface) {
1678 $this->postProcessHookObjects[] = $hookObject;
1689 public function isConnected()
1692 if ($this->isConnected) {
1695 $this->isConnected = $this->link->ping();
1697 return $this->isConnected;
1714 protected function checkConnectionCharset()
1716 $sessionResult = $this->sql_query(
'SHOW SESSION VARIABLES LIKE \'character_set%\'');
1718 if ($sessionResult ===
false) {
1719 GeneralUtility::sysLog(
1720 'Error while retrieving the current charset session variables from the database: ' . $this->sql_error(),
1724 throw new \RuntimeException(
1725 'TYPO3 Fatal Error: Could not determine the current charset of the database.',
1730 $charsetVariables = array();
1731 while (($row = $this->sql_fetch_row($sessionResult)) !==
false) {
1732 $variableName = $row[0];
1733 $variableValue = $row[1];
1734 $charsetVariables[$variableName] = $variableValue;
1736 $this->sql_free_result($sessionResult);
1740 $charsetRequiredVariables = array(
1741 'character_set_client',
1742 'character_set_results',
1743 'character_set_connection',
1746 $hasValidCharset =
true;
1747 foreach ($charsetRequiredVariables as $variableName) {
1748 if (empty($charsetVariables[$variableName])) {
1749 GeneralUtility::sysLog(
1750 'A required session variable is missing in the current MySQL connection: ' . $variableName,
1754 throw new \RuntimeException(
1755 'TYPO3 Fatal Error: Could not determine the value of the database session variable: ' . $variableName,
1760 if ($charsetVariables[$variableName] !== $this->connectionCharset) {
1761 $hasValidCharset =
false;
1766 if (!$hasValidCharset) {
1767 throw new \RuntimeException(
1768 'It looks like the character set ' . $this->connectionCharset .
' is not used for this connection even though it is configured as connection charset. ' .
1769 'This TYPO3 installation is using the $GLOBALS[\'TYPO3_CONF_VARS\'][\'SYS\'][\'setDBinit\'] property with the following value: "' .
1770 $GLOBALS[
'TYPO3_CONF_VARS'][
'SYS'][
'setDBinit'] .
'". Please make sure that this command does not overwrite the configured charset. ' .
1771 'Please note that for the TYPO3 database everything other than utf8 is unsupported since version 4.7.',
1782 protected function disconnectIfConnected()
1784 if ($this->isConnected) {
1785 $this->link->close();
1786 $this->isConnected =
false;
1795 public function getDatabaseHandle()
1805 public function setDatabaseHandle($handle)
1807 $this->link = $handle;
1815 public function getServerVersion()
1817 return $this->link->server_info;
1832 public function debug($func, $query =
'')
1834 $error = $this->sql_error();
1835 if ($error || (
int)$this->debugOutput === 2) {
1838 'caller' => \TYPO3\CMS\Core\Database\DatabaseConnection::class .
'::' . $func,
1840 'lastBuiltQuery' => $query ? $query : $this->debug_lastBuiltQuery,
1841 'debug_backtrace' => \TYPO3\CMS\Core\Utility\DebugUtility::debugTrail()
1844 is_object(
$GLOBALS[
'error']) && @is_callable(array(
$GLOBALS[
'error'],
'debug'))
1857 public function debug_check_recordset($res)
1859 if ($res !==
false) {
1862 $msg =
'Invalid database result detected';
1863 $trace = debug_backtrace();
1864 array_shift($trace);
1865 $cnt = count($trace);
1866 for ($i = 0; $i < $cnt; $i++) {
1868 if (isset($trace[
'object'])) {
1869 unset($trace[
'object']);
1872 $msg .=
': function TYPO3\\CMS\\Core\\Database\\DatabaseConnection->' . $trace[0][
'function'] .
' called from file ' . substr($trace[0][
'file'], (strlen(PATH_site) + 2)) .
' in line ' . $trace[0][
'line'];
1873 GeneralUtility::sysLog(
1874 $msg .
'. Use a devLog extension to get more details.',
1880 $debugLogData = array(
1881 'SQL Error' => $this->sql_error(),
1882 'Backtrace' => $trace
1884 if ($this->debug_lastBuiltQuery) {
1885 $debugLogData = array(
'SQL Query' => $this->debug_lastBuiltQuery) + $debugLogData;
1904 protected function explain($query, $from_table, $row_count)
1908 $GLOBALS[
'TYPO3_CONF_VARS'][
'SYS'][
'devIPmask']
1911 (
int)$this->explainOutput == 1
1912 || ((
int)$this->explainOutput == 2 && $debugAllowedForIp)
1916 }
elseif ((
int)$this->explainOutput == 3 && is_object(
$GLOBALS[
'TT'])) {
1922 $error = $this->sql_error();
1923 $trail = \TYPO3\CMS\Core\Utility\DebugUtility::debugTrail();
1924 $explain_tables = array();
1925 $explain_output = array();
1926 $res = $this->sql_query(
'EXPLAIN ' . $query, $this->link);
1927 if (is_a($res,
'\\mysqli_result')) {
1928 while ($tempRow = $this->sql_fetch_assoc($res)) {
1929 $explain_output[] = $tempRow;
1930 $explain_tables[] = $tempRow[
'table'];
1932 $this->sql_free_result($res);
1934 $indices_output = array();
1937 $explain_output[0][
'rows'] > 1
1942 foreach ($explain_tables as $table) {
1943 $tableRes = $this->sql_query(
'SHOW TABLE STATUS LIKE \'' . $table .
'\'');
1944 $isTable = $this->sql_num_rows($tableRes);
1946 $res = $this->sql_query(
'SHOW INDEX FROM ' . $table, $this->link);
1947 if (is_a($res,
'\\mysqli_result')) {
1948 while ($tempRow = $this->sql_fetch_assoc($res)) {
1949 $indices_output[] = $tempRow;
1951 $this->sql_free_result($res);
1954 $this->sql_free_result($tableRes);
1962 $data[
'query'] = $query;
1963 $data[
'trail'] = $trail;
1964 $data[
'row_count'] = $row_count;
1966 $data[
'error'] = $error;
1968 if (!empty($explain_output)) {
1969 $data[
'explain'] = $explain_output;
1971 if (!empty($indices_output)) {
1972 $data[
'indices'] = $indices_output;
1974 if ($explainMode == 1) {
1976 }
elseif ($explainMode == 2) {
1977 $GLOBALS[
'TT']->setTSselectQuery($data);
1990 public function __sleep()
1992 $this->disconnectIfConnected();
2001 'databaseUserPassword',
2002 'persistentDatabaseConnection',
2003 'connectionCompression',
2004 'initializeCommandsAfterConnect',