Leitgedanken/msd/inc/mysqli.php
2023-02-11 15:24:36 +01:00

544 lines
18 KiB
PHP

<?php
/* ----------------------------------------------------------------------
MyOOS [Dumper]
http://www.oos-shop.de/
Copyright (c) 2013 - 2022 by the MyOOS Development Team.
----------------------------------------------------------------------
Based on:
MySqlDumper
http://www.mysqldumper.de
Copyright (C)2004-2011 Daniel Schlichtholz (admin@mysqldumper.de)
----------------------------------------------------------------------
Released under the GNU General Public License
---------------------------------------------------------------------- */
if (!defined('MOD_VERSION')) {
exit('No direct access.');
}
//Feldspezifikationen
$feldtypen = [
'VARCHAR',
'TINYINT',
'TEXT',
'DATE',
'SMALLINT',
'MEDIUMINT',
'INT',
'BIGINT',
'FLOAT',
'DOUBLE',
'DECIMAL',
'DATETIME',
'TIMESTAMP',
'TIME',
'YEAR',
'CHAR',
'TINYBLOB',
'TINYTEXT',
'BLOB',
'MEDIUMBLOB',
'MEDIUMTEXT',
'LONGBLOB',
'LONGTEXT',
'ENUM',
'SET',
];
$feldattribute = [
'',
'BINARY',
'UNSIGNED',
'UNSIGNED ZEROFILL',
];
$feldnulls = [
'NOT NULL',
'NULL',
];
$feldextras = [
'',
'AUTO_INCREMENT',
];
$feldkeys = [
'',
'PRIMARY KEY',
'UNIQUE KEY',
'FULLTEXT',
];
$feldrowformat = [
'',
'FIXED',
'DYNAMIC',
'COMPRESSED',
];
$rechte_daten = [
'SELECT',
'INSERT',
'UPDATE',
'DELETE',
'FILE',
];
$rechte_struktur = [
'CREATE',
'ALTER',
'INDEX',
'DROP',
'CREATE TEMPORARY TABLES',
];
$rechte_admin = [
'GRANT',
'SUPER',
'PROCESS',
'RELOAD',
'SHUTDOWN',
'SHOW DATABASES',
'LOCK TABLES',
'REFERENCES',
'EXECUTE',
'REPLICATION CLIENT',
'REPLICATION SLAVE',
];
$rechte_resourcen = [
'MAX QUERIES PER HOUR',
'MAX UPDATES PER HOUR',
'MAX CONNECTIONS PER HOUR',
];
$sql_keywords = [
'ALTER',
'AND',
'ADD',
'AUTO_INCREMENT',
'BETWEEN',
'BINARY',
'BOTH',
'BY',
'BOOLEAN',
'CHANGE',
'CHARSET',
'CHECK',
'COLLATE',
'COLUMNS',
'COLUMN',
'CROSS',
'CREATE',
'DATABASES',
'DATABASE',
'DATA',
'DELAYED',
'DESCRIBE',
'DESC',
'DISTINCT',
'DELETE',
'DROP',
'DEFAULT',
'ENCLOSED',
'ENGINE',
'ESCAPED',
'EXISTS',
'EXPLAIN',
'FIELDS',
'FIELD',
'FLUSH',
'FOR',
'FOREIGN',
'FUNCTION',
'FROM',
'GROUP',
'GRANT',
'HAVING',
'IGNORE',
'INDEX',
'INFILE',
'INSERT',
'INNER',
'INTO',
'IDENTIFIED',
'JOIN',
'KEYS',
'KILL',
'KEY',
'LEADING',
'LIKE',
'LIMIT',
'LINES',
'LOAD',
'LOCAL',
'LOCK',
'LOW_PRIORITY',
'LEFT',
'LANGUAGE',
'MEDIUMINT',
'MODIFY',
'MyISAM',
'NATURAL',
'NOT',
'NULL',
'NEXTVAL',
'OPTIMIZE',
'OPTION',
'OPTIONALLY',
'ORDER',
'OUTFILE',
'OR',
'OUTER',
'ON',
'PROCEEDURE',
'PROCEDURAL',
'PRIMARY',
'READ',
'REFERENCES',
'REGEXP',
'RENAME',
'REPLACE',
'RETURN',
'REVOKE',
'RLIKE',
'RIGHT',
'SHOW',
'SONAME',
'STATUS',
'STRAIGHT_JOIN',
'SELECT',
'SETVAL',
'TABLES',
'TEMINATED',
'TO',
'TRAILING',
'TRUNCATE',
'TABLE',
'TEMPORARY',
'TRIGGER',
'TRUSTED',
'UNIQUE',
'UNLOCK',
'USE',
'USING',
'UPDATE',
'UNSIGNED',
'VALUES',
'VARIABLES',
'VIEW',
'WITH',
'WRITE',
'WHERE',
'ZEROFILL',
'XOR',
'ALL',
'ASC',
'AS',
'SET',
'IN',
'IS',
'IF',
];
$mysql_doc = [
'Feldtypen' => 'http://dev.mysql.com/doc/mysql/de/Column_types.html',
];
$mysql_string_types = [
'char',
'varchar',
'tinytext',
'text',
'mediumtext',
'longtext',
'binary',
'varbinary',
'tinyblob',
'mediumblob',
'blob',
'longblob',
'enum',
'set',
];
$mysql_SQLhasRecords = [
'SELECT',
'SHOW',
'EXPLAIN',
'DESCRIBE',
'DESC',
];
function mod_mysqli_connect($encoding = 'utf8mb4', $keycheck_off = false, $actual_table = '')
{
global $config, $databases;
if (isset($config['dbconnection']) && is_resource($config['dbconnection'])) {
return $config['dbconnection'];
}
$port = (isset($config['dbport']) && !empty($config['dbport'])) ? ':'.$config['dbport'] : '';
$socket = (isset($config['dbsocket']) && !empty($config['dbsocket'])) ? ':'.$config['dbsocket'] : '';
// Forcing error reporting mode to OFF, which is no longer the default
// starting with PHP 8.1
@mysqli_report(MYSQLI_REPORT_OFF);
$config['dbconnection'] = @mysqli_connect($config['dbhost'].$port.$socket, $config['dbuser'], $config['dbpass']);
if (!$config['dbconnection']) {
exit(SQLError('Error establishing a database connection!', mysqli_connect_error()));
}
if (!defined('MOD_MYSQL_VERSION')) {
GetMySQLVersion();
}
if (!isset($config['mysql_standard_character_set']) || '' == $config['mysql_standard_character_set']) {
get_sql_encodings();
}
if ($config['mysql_standard_character_set'] != $encoding) {
$set_encoding = mysqli_query($config['dbconnection'], 'SET NAMES \''.$encoding.'\'');
if (false === $set_encoding) {
$config['mysql_can_change_encoding'] = false;
} else {
$config['mysql_can_change_encoding'] = true;
}
}
if ($keycheck_off) {
// only called with this param when restoring
mysqli_query($config['dbconnection'], 'SET FOREIGN_KEY_CHECKS=0');
// also set SQL-Mode NO_AUTO_VALUE_ON_ZERO for magento users
mysqli_query($config['dbconnection'], 'SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"');
}
return $config['dbconnection'];
}
function GetMySQLVersion()
{
global $config;
if (!isset($config['dbconnection'])) {
mod_mysqli_connect();
}
$res = mod_query('SELECT VERSION()');
$row = mysqli_fetch_array($res);
$str = $row[0];
$version = str_replace(':', '--', $str);
if (!defined('MOD_MYSQL_VERSION')) {
define('MOD_MYSQL_VERSION', $version);
}
$versions = explode('.', $version);
$new = false;
if (4 == $versions[0] && $versions[1] >= 1) {
$new = true;
}
if ($versions[0] > 4) {
$new = true;
}
if (!defined('MOD_NEW_VERSION')) {
define('MOD_NEW_VERSION', $new);
}
return $version;
}
function mod_query($query, $error_output = true)
{
global $config;
// print_mem();
if (!isset($config['dbconnection'])) {
mod_mysqli_connect();
}
// echo "<br>Query: ".htmlspecialchars($query).'<br>';
$res = mysqli_query($config['dbconnection'], $query);
// print_mem();
if (false === $res && $error_output) {
SQLError($query, mysqli_error($config['dbconnection']));
}
return $res;
}
function print_mem()
{
/* Currently used memory */
$mem_usage = memory_get_usage();
/* Peak memory usage */
$mem_peak = memory_get_peak_usage();
echo 'The script is now using: <strong>'.round($mem_usage / 1024).' KB</strong> of memory.<br>';
echo 'Peak usage: <strong>'.round($mem_peak / 1024).' KB</strong> of memory.<br><br>';
}
function SQLError($sql, $error, $return_output = false)
{
global $lang;
$ret = '<div align="center"><table style="border:1px solid #ff0000" cellspacing="0">
<tr bgcolor="#ff0000"><td style="color:white;font-size:16px;"><strong>MySQL-ERROR</strong></td></tr>
<tr><td style="width:80%;overflow: auto;">'.$lang['L_SQL_ERROR2'].'<br><span style="color:red;">'.$error.'</span></td></tr>
<tr><td width="600"><br>'.$lang['L_SQL_ERROR1'].'<br>'.Highlight_SQL($sql).'</td></tr>
</table></div><br />';
if ($return_output) {
return $ret;
} else {
echo $ret;
}
}
function Highlight_SQL($sql)
{
global $sql_keywords;
$end = '';
$tickstart = false;
if (function_exists('token_get_all')) {
$a = @token_get_all("<?php $sql?>");
} else {
return $sql;
}
foreach ($a as $token) {
if (!is_array($token)) {
if ('`' == $token) {
$tickstart = !$tickstart;
}
$end .= $token;
} else {
if ($tickstart) {
$end .= $token[1];
} else {
switch (token_name($token[0])) {
case 'T_STRING':
case 'T_AS':
case 'T_FOR':
$end .= (in_array(strtoupper($token[1]), $sql_keywords)) ? '<span style="color:#990099;font-weight:bold;">'.$token[1].'</span>' : $token[1];
break;
case 'T_IF':
case 'T_LOGICAL_AND':
case 'T_LOGICAL_OR':
case 'T_LOGICAL_XOR':
$end .= (in_array(strtoupper($token[1]), $sql_keywords)) ? '<span style="color:#0000ff;font-weight:bold;">'.$token[1].'</span>' : $token[1];
break;
case 'T_CLOSE_TAG':
case 'T_OPEN_TAG':
break;
default:
$end .= $token[1];
}
}
}
}
$end = preg_replace('/`(.*?)`/si', '<span style="color:red;">`$1`</span>', $end);
return $end;
}
function Fieldlist($db, $tbl)
{
$fl = '';
$res = mod_query("SHOW FIELDS FROM `$db`.`$tbl`;");
if ($res) {
$fl = '(';
for ($i = 0; $i < mysqli_num_rows($res); ++$i) {
$row = mysqli_fetch_row($res);
$fl .= '`'.$row[0].'`,';
}
$fl = substr($fl, 0, strlen($fl) - 1).')';
}
return $fl;
}
// reads all Tableinfos and place them in $dump-Array
function getDBInfos()
{
global $databases, $dump, $config, $tbl_sel, $flipped;
for ($ii = 0; $ii < count($databases['multi']); ++$ii) {
$dump['dbindex'] = $flipped[$databases['multi'][$ii]];
$tabellen = mysqli_query($config['dbconnection'], 'SHOW TABLE STATUS FROM `'.$databases['Name'][$dump['dbindex']].'`') or exit('getDBInfos: '.mysqli_error($config['dbconnection']));
$num_tables = mysqli_num_rows($tabellen);
// Array mit den gewünschten Tabellen zusammenstellen... wenn Präfix angegeben, werden die anderen einfach nicht übernommen
if ($num_tables > 0) {
for ($i = 0; $i < $num_tables; ++$i) {
$row = mysqli_fetch_array($tabellen);
if (isset($row['Type'])) {
$row['Engine'] = $row['Type'];
}
if (isset($row['Comment']) && 'VIEW' == substr(strtoupper($row['Comment']), 0, 4)) {
$dump['table_types'][] = 'VIEW';
} else {
$dump['table_types'][] = strtoupper($row['Engine']);
}
// check if data needs to be backed up
if ('VIEW' == strtoupper($row['Comment']) || (isset($row['Engine']) && in_array(strtoupper($row['Engine']), [
'MEMORY',
]))) {
$dump['skip_data'][] = $databases['Name'][$dump['dbindex']].'|'.$row['Name'];
}
if ((isset($config['optimize_tables_beforedump']) && (1 == $config['optimize_tables_beforedump'])) && -1 == $dump['table_offset']
&& 'information_schema' != $databases['Name'][$dump['dbindex']]) {
mysqli_select_db($config['dbconnection'], $databases['Name'][$dump['dbindex']]);
$opt = 'OPTIMIZE TABLE `'.$row['Name'].'`';
$res = mysqli_query($config['dbconnection'], 'OPTIMIZE TABLE `'.$row['Name'].'`');
if (false === $res) {
exit('Error in '.$opt.' -> '.mysqli_error($config['dbconnection']));
}
}
if (isset($tbl_sel)) {
if (in_array($row['Name'], $dump['tblArray'])) {
$dump['tables'][] = $databases['Name'][$dump['dbindex']].'|'.$row['Name'];
$dump['records'][] = $databases['Name'][$dump['dbindex']].'|'.$row['Rows'];
$dump['totalrecords'] += $row['Rows'];
}
} elseif ('' != $databases['praefix'][$dump['dbindex']] && !isset($tbl_sel)) {
if (substr($row['Name'], 0, strlen($databases['praefix'][$dump['dbindex']])) == $databases['praefix'][$dump['dbindex']]) {
$dump['tables'][] = $databases['Name'][$dump['dbindex']].'|'.$row['Name'];
$dump['records'][] = $databases['Name'][$dump['dbindex']].'|'.$row['Rows'];
$dump['totalrecords'] += $row['Rows'];
}
} else {
$dump['tables'][] = $databases['Name'][$dump['dbindex']].'|'.$row['Name'];
$dump['records'][] = $databases['Name'][$dump['dbindex']].'|'.$row['Rows'];
// Get nr of records -> need to do it this way because of incorrect returns when using InnoDBs
$sql_2 = 'SELECT count(*) as `count_records` FROM `'.$databases['Name'][$dump['dbindex']].'`.`'.$row['Name'].'`';
$res2 = mysqli_query($config['dbconnection'], $sql_2);
if (false === $res2) {
$read_error = mysqli_error($config['dbconnection']);
SQLError($read_error, $sql_2);
WriteLog($read_error);
if ($config['stop_with_error'] > 0) {
exit($read_error);
}
} else {
$row2 = mysqli_fetch_array($res2);
$row['Rows'] = $row2['count_records'];
$dump['totalrecords'] += $row['Rows'];
}
}
}
// Correct total number of records; substract skipped data
foreach ($dump['skip_data'] as $skip_data) {
$index = false;
$records_to_skip = 0;
//find index of table to get the nr of records
$count = sizeof($dump['tables']);
for ($a = 0; $a < $count; ++$a) {
if ($dump['tables'][$a] == $skip_data) {
$index = $a;
$t = explode('|', $dump['records'][$a]);
$rekords_to_skip = $t[1];
break;
}
}
if ($index) {
$dump['totalrecords'] -= intval($rekords_to_skip);
}
}
}
}
}
// gets the numeric index in dump-array and returns it
function getDBIndex($db, $table)
{
global $dump;
$index = array_keys($dump['tables'], $db.'|'.$table);
return $index[0];
}