<?php
/**
* 数据库操作管理
* @author moufer<moufer@163.com>
* @copyright www.modoer.com
* @version $Id 5 2008-09-19 22:31 $
*/
(!defined('IN_ADMIN') || !defined('IN_MUDDER')) && exit('Access Denied');
$backupdir = MUDDER_ROOT.'./data/backupdata/';

if(!check_submit('toolssubmit')) {

    if($op == 'resetdatabase') {

        $tplname = 'resetdatabase';
        $file_i = 0;
        if($doreset == 'confirm') {
            $pathinfo = pathinfo($backupdir.$database_filename);
            if(is_file($backupdir.$database_filename) && strtolower($pathinfo['extension']) == 'sql') {
                $fp = fopen($backupdir.$database_filename, 'rb');
                $identify = explode(',', base64_decode(preg_replace("/^# Identify:\s*(\w+).*/s", "\\1", fgets($fp, 200))));
                fclose($fp);
                if (count($identify) != 3) {
                    cpmsg('SQL文件有可能是当前程序的老版本备份的，为了程序程序正常运作，不允许导入，请返回重新选择。');
                }
                if ($identify[2] != 1) {
                    cpmsg('为了程序正常运作，只允许导入卷号为1的SQL文件，请返回重新选择。');
                }
                if ($identify[1] != $_VERSION['version']) {
                    cpmsg('SQL文件版本信息和当前程序版本不匹配，为了程序程序正常运作，不允许导入。请返回重新选择。');
                }
                $reset_ready = 1;
            } else {
                $reset_ready = 0;
                cpmsg('文件不存在，或者文件不是有效的.sql文件。请返回重新选择。');
            }
        } elseif($doreset == 'yes') {
            $bkfile = $backupdir.$database_filename;
            /*
            if(!is_file($file)) {
                cpmsg("备份文件(".htmlspecialchars($file).")不存在。");
            }
            */
            $path_parts = pathinfo($bkfile);
            if (strtolower($path_parts['extension']) != 'sql') {
                cpmsg('只能恢复SQL文件!');
            }
            if(@$fp = fopen($bkfile, 'rb')) {
                $sqldump = fgets($fp, 256);
                $identify = explode(',', base64_decode(preg_replace("/^# Identify:\s*(\w+).*/s", "\\1", $sqldump)));
                $sqldump .= fread($fp, filesize($bkfile));
                fclose($fp);
            } else {
                if($autoimport) {
                    cache_all();// 重建数据
                    //$cache->Write_All();
                    cpmsg('分卷数据成功导入数据库。');
                } else {
                    cpmsg('分卷数据导入数据库失败。');
                }
            }
            if($identify[0] && $identify[1] == $_VERSION['version'] && $identify[2]) {
                $sqlquery = splitsql($sqldump);
                unset($sqldump);
                foreach($sqlquery as $sql) {
                    if(trim($sql) != '') {
                        $db->query($sql, 'SILENT');
                    }
                }

                $file_next = basename(preg_replace("/_($identify[2])(\..+)$/", "_".($identify[2] + 1)."\\2", $bkfile));

                if($identify[2] == 1) {
                    cpmsg('分卷数据成功导入数据库，程序将自动导入本次其他的备份。','admincp.php?action=modoer&file=database&database_filename='.rawurlencode($file_next).'&doreset=yes&autoimport=yes');
                } elseif($autoimport) {
                    cpmsg('数据文件卷号 '.$identify[2].' 成功导入，程序将自动继续。', 'admincp.php?action=modoer&file=database&database_filename='.rawurlencode($file_next).'&doreset=yes&autoimport=yes');
                } else {
                    cache_all();// 重建数据
                    //$cache->Write_All();
                    cpmsg('数据恢复完毕。');
                }
            } else {
                cpmsg('数据文件非 Modoer 格式或与程序当前版本信息不符，无法导入。');
            }
        } else {
            if(is_dir($backupdir)) {
                $dirs = dir($backupdir);
                $dbfiles = array();
                $today = @date('Y-m-d',$timestamp);
                while ($bkfile = $dirs->read()) {
                    $filepath = $backupdir.'/'.$bkfile;
                    $pathinfo = pathinfo($bkfile);
                    if(is_file($filepath) && $pathinfo['extension'] == 'sql') {
                        $fp = fopen($filepath, 'rb');
                        $identify = explode(',', base64_decode(preg_replace("/^# Identify:\s*(\w+).*/s", "\\1", fgets($fp, 200))));
                        fclose($fp);
                        $moday = @date('Y-m-d',@filemtime($filepath));
                        $mtime = @date('Y-m-d H:i',@filemtime($filepath));
                        $dbfile = array(
                            'filesize' => sizeunit(filesize($filepath)),
                            'mtime' => ($moday == $today) ? '<font color="#FF0000">'.$mtime.'</font>' : $mtime,
                            'bktime' => $identify[0] ? @date('Y-m-d H:i',$identify[0]) : '未知',
                            'version' => $identify[1] ? $identify[1] : '未知',
                            'volume' => $identify[2] ? $identify[2] : '未知',
                            'filepath' => urlencode($bkfile),
                            'filename' => htmlspecialchars($bkfile),
                        );
                        $file_i++;
                        $dbfiles[] = $dbfile;
                    }
                }
                unset($dbfile);
                $dirs->close();
                $noexists = 0;
            } else {
                $noexists = 1;
            }
        }
    
    } elseif($op == 'maintenancedatabase') {

        $tplname = 'maintenancedatabase';
    
    } elseif($op == 'databaseinfo') {

        $tplname = 'databaseinfo';
        $query = $db->query("SHOW TABLE STATUS");
        $mudder_rows_total = $plugin_rows_total = $other_rows_total = $mudder_Index_length = $other_Index_length = $mudder_Data_free = $other_Data_free = $mudder_Data_length = $other_Data_length = 0;
        while($info = $db->fetch_array($query)) {
            $info['Index_length_unit'] += sizeunit(@intval($info['Index_length']));
            $info['Data_free_unit'] += sizeunit(@intval($info['Data_free']));
            $info['Data_length_unit'] += sizeunit(@intval($info['Data_length']));
            if(substr($info['Name'],0,strlen($dbpre)) == $dbpre) {
                $mudder_table_info[] = $info;
                $mudder_rows_total += $info['Rows'];
                $mudder_Index_length += $info['Index_length'];
                $mudder_Data_free += $info['Data_free'];
                $mudder_Data_length += $info['Data_length'];
            } else {
                $other_table_info[] = $info;
                $other_rows_total += $info['Rows'];
                $other_Index_length += $info['Index_length'];
                $other_Data_free += $info['Data_free'];
                $other_Data_length += $info['Data_length'];
            }
        }
    
    } else { 

        $op = 'backupdatabase';
        $tplname = 'backupdatabase';
        if($dobackup == 'yes') {
            $volume = intval($volume) + 1;
            $sqlfilename = $backupdir.$database_filename.'_'.$volume.'.sql';

            if(!$sqlfilename || preg_match("/(\.)(exe|jsp|asp|asa|htr|stm|shtml|php3|aspx|cgi|fcgi|pl|php|bat)(\.|$)/i", $sqlfilename)) {
                cpmsg("您没有输入备份文件名或文件名中使用了敏感的扩展名。", "admincp.php?action=$op");
            }

            $idstring = '# Identify: '.base64_encode("$timestamp,{$_VERSION['version']},$volume")."\n";

            $sqlcompat = in_array($sqlcompat, array('MYSQL40', 'MYSQL41')) ? $sqlcompat : '';
            $dumpcharset = $dbcharset;
            $setnames = intval($addsetnames) || ($db->version() > '4.1' && (!$sqlcompat || $sqlcompat == 'MYSQL41')) ? "SET character_set_connection=".$dumpcharset.", character_set_results=".$dumpcharset.", character_set_client=binary;\n\n" : '';

            if($db->version() > '4.1') {
                $db->query("SET character_set_connection=$dumpcharset, character_set_results=$dumpcharset, character_set_client=binary;");
                if($sqlcompat == 'MYSQL40') {
                    $db->query("SET SQL_MODE='MYSQL40'");
                }
            }
                
            $sqldump = '';
            $tableid = $tableid ? $tableid - 1 : 0;
            $startfrom = intval($startfrom);
            
            $tables = array();
            $query = $db->query("SHOW TABLE STATUS");
            while($myval = $db->fetch_array($query)) {
                if($backlimit == 'all') {
                    $tables[] = $myval['Name'];
                } elseif(substr($myval['Name'], 0, strlen($dbpre)) == $dbpre) {
                    $tables[] = $myval['Name'];
                }
            }
            for($i = $tableid; $i < count($tables) && strlen($sqldump) < $sizelimit * 1000; $i++) {
                $sqldump .= sqldumptable($tables[$i], $startfrom, strlen($sqldump));
                $startfrom = 0;
            }
            $tableid = $i;
            if(trim($sqldump)) {
                $sqldump = "$idstring".
                    "# <?exit();?>\n".
                    "# Modoer bakfile Multi-Volume Data Dump Vol.$volume\n".
                    "# Version: {$_VERSION['version']}\n".
                    "# Time: ".date('Y-m-d H:i',$timestamp)."\n".
                    "# Website: http://www.modoer.com\n".
                    "# --------------------------------------------------------\n\n\n".$setnames.$sqldump;

                @$fp = fopen($sqlfilename, 'wb');
                @flock($fp, 2);
                if(@!fwrite($fp, $sqldump)) {
                    @fclose($fp);
                    cpmsg("数据文件无法备份到服务器，请返回检查目录属性。", "admincp.php?action=modoer&file=database&op=backupdatabase");
                } else {
                    cpmsg('分卷备份:数据文件 '.$volume.' 备份成功，程序将自动继续。', "admincp.php?action=modoer&file=database&op=backupdatabase&dobackup=yes&database_filename=".rawurlencode($database_filename)."&sizelimit=".rawurlencode($sizelimit)."&volume=".rawurlencode($volume)."&tableid=".rawurlencode($tableid)."&startfrom=".rawurlencode($startrow)."&extendins=".rawurlencode($extendins)."&sqlcompat=".rawurlencode($sqlcompat)."&backlimit=".rawurlencode($backlimit));
                }
            } else {
                cpmsg('数据成功备份至服务器指定文件中。', 'admincp.php?action=modoer&file=database&op=resetdatabase');
            }
        } else {
            $backfilename = date('Y-m-d',$timestamp).'_'.random(8);
        }
    
    }

    include cptpl('database_'.$tplname);

} else {

    if($op == 'resetdatabase') {

        if (!$backfiles || !is_array($backfiles)) {
            cpmsg('未选择任何备份文件，请返回至少选择一项。');
        }

        $succ = $fail = 0;
        foreach($backfiles as $backfile) {
            $fullfile = $backupdir.$backfile;
            if (file_exists($fullfile)) {
                @chmod($fullfile, 0777);
                if(@unlink($fullfile)) $succ++; else $fail++;
            } else {
                cpmsg(basename($fullfile).' 文件已不存在。');
            }
        }
        cpmsg('删除数据文件操作完毕,选择删除'.count($backfiles).'个，成功'.$succ.'个，失败'.$fail.'个。','admincp.php?action=modoer&file=database&op=resetdatabase');
    
    } elseif($op == 'maintenancedatabase') {

        $tplname = 'maintenancedatabase';
        if(!$maintenance || !is_array($maintenance)) {
            cpmsg('未选择需要维护项，请返回至少选择一项。');
        }
        $maintenance_arr = array(
            'check' => '检查',
            'repair' => '修复',
            'analyze' => '分析',
            'optimize' => '优化'
        );
        $goodresults = $tables = array();
        $query = $db->query("SHOW TABLE STATUS");
        while($myval = $db->fetch_array($query)) {
            if(substr($myval['Name'], 0, strlen($dbpre)) == $dbpre) {
                $tables[] = $myval['Name'];
            }
        }
        foreach($maintenance as $val) {
            if(array_key_exists($val, $maintenance_arr)) {
                $newtable =& $tables;
                foreach ($newtable as $table) {
                    $result = $db->query($val.' TABLE '.$table) ? '<font color="#339900">成功</font>' : '<font color="#FF0000">失败</font>';
                    $goodresults[] = array('do'=>$maintenance_arr[$val],'table'=>$table,'result'=>$result);
                }
            }
        }

        include cptpl('database_'.$tplname);

    } else {

        cpmsg('未定义操作。');

    }
}
?>
