<?php
namespace application\admin\controller;
use ticky\request;
use ticky\databack;
class database extends auth {
    public $config;
    public function __construct() {
        parent::__construct();
        $this->config = array(
            'path' => RUNTIME_PATH . DIRECTORY_SEPARATOR . 'databack' . DIRECTORY_SEPARATOR,            'part' => 2097152,            'compress' => 1,            'level' => 4,        );
    }
    
    public function index() {
        $ret = $this->db->query('SHOW TABLE STATUS');
        $this->assign('items', $ret);
        $this->display('database/index');
    }
    
    public function backups() {
        if (isset($_POST['dosubmit'])) {
            $tables = request::get('tables', []);
            if (!$tables) {
                showmsg('请指定要备份的表!', '/admin/database');
            }
            $tables = is_array($tables) ? implode(',', $tables) : $tables;
                       if (!is_dir($this->config['path'])) {
                @mkdir($this->config['path'], 0755, true);
                @file_put_contents($this->config['path'] . 'index.html', '');
            }
                       $lock = $this->config['path'] . 'backup.lock';
            if (is_file($lock)) {
                showmsg('检测到有一个备份任务正在执行,请稍后再试!');
            } else {
                $len = @file_put_contents($lock, SYS_TIME);            }
            if (!$len) {
                showmsg($this->config['path'] . '目录不存在或不可写,请检查!', 'stop');
            }
            session('backup_config', $this->config);
                       $file = array(
                'name' => random(6, 'abcdefghigklmzopqrstuvwxyz') . '-' . date('Ymd-His'),
                'part' => 1,
            );
            session('backup_file', $file);
                       session('backup_tables', request::get('tables', []));
                       $database = new databack($file, $this->config);
            if (false !== $database->create()) {
                showmsg('初始化成功!', '/admin/database/backups/?id=0&start=0', 1);
            } else {
                showmsg('初始化失败,备份文件创建失败!');
            }
        } elseif (isset($_GET['id']) && isset($_GET['start'])) {
            $tables = session('backup_tables');
            $id = intval($_GET['id']);
            $start = intval($_GET['start']);
            $database = new databack(session('backup_file'), session('backup_config'));
            $start = $database->backup($tables[$id], $start);
            if (false === $start) {                 showmsg('备份出错!');
            } elseif (0 === $start) {                if (isset($tables[++$id])) {
                    showmsg('表' . $tables[$id] . '备份完成!', '/admin/database/backups/?id=' . $id . '&start=0', 0.1);
                } else {                      @unlink(session('backup_config')['path'] . 'backup.lock');
                    session('backup_tables', null);
                    session('backup_file', null);
                    session('backup_config', null);
                    showmsg('备份全部完成!', '/admin/database/databacklist', 2);
                }
            } else {
                $rate = floor(100 * ($start[0] / $start[1]));
                showmsg('表' . $tables[$id] . '正在备份...(' . $rate . '%)', '/admin/database/backups/?id=' . $id . '&start=' . $start[0], 0.1);
            }
        } else {
            showmsg('参数错误!', '/admin/database');
        }
    }
    
    public function optimize() {
        $tables = request::get('tables', []);
        if (!$tables) {
            showmsg('请指定要优化的表!', '/admin/database');
        }
        $tables = is_array($tables) ? implode(',', $tables) : $tables;
        $this->db->query("OPTIMIZE TABLE $tables");
        showmsg('优化' . $tables . '表成功', '/admin/database');
    }
    
    public function repair() {
        $tables = request::get('tables', []);
        if (!$tables) {
            showmsg('请指定要修复的表!', '/admin/database');
        }
        $tables = is_array($tables) ? implode(',', $tables) : $tables;
        $this->db->query("REPAIR TABLE $tables");
        showmsg('修复' . $tables . '表成功', '/admin/database');
    }
    
    public function databacklist() {
        $data = array();
        $list = glob($this->config['path'] . '*');
                      foreach ($list as $name) {
                       $info['filesize'] = sizecount(filesize($name));
            $info['filename'] = basename($name);
            $name = sscanf($info['filename'], '%6s-%4s%2s%2s-%2s%2s%2s-%d');
            $info['backtime'] = $name[1] . '-' . $name[2] . '-' . $name[3] . ' ' . $name[4] . ':' . $name[5] . ':' . $name[6];
            $info['random'] = $name[0];
            $info['part'] = $name[7];
            $info['time'] = strtotime($info['backtime']);
            $data[] = $info;
                              }
        $this->assign('items', $data);
        $this->display('database/databacklist');
    }
    
    public function databackdel() {
        if (!isset($_GET['filename'])) {
            showmsg('请指定要下载的文件!');
        }
        $filename = $this->config['path'] . $_GET['filename'];
        if (!is_file($filename)) {
            showmsg($filename . '文件不存在!', 'stop');
        }
        array_map('unlink', glob($filename));
        if (count(glob($filename))) {
            showmsg('备份文件删除失败,请检查权限!');
        } else {
            showmsg('备份文件删除成功!', '', 1);
        }
    }
    
    public function databackdown() {
        if (!isset($_GET['filename'])) {
            showmsg('请指定要下载的文件!');
        }
        $filename = $_GET['filename'];
        if (!is_file($this->config['path'] . $filename)) {
            showmsg($filename . '文件不存在!', 'stop');
        }
        file_down($this->config['path'] . $filename);
    }
    
    public function import() {
        if (isset($_GET['time'])) {
            $filename = $_GET['random'] . '-' . date('Ymd-His', intval($_GET['time'])) . '-*.sql*';
            $path = $this->config['path'] . $filename;
            $files = glob($path);
            $list = array();
            foreach ($files as $name) {
                $basename = basename($name);
                $match = sscanf($basename, '%6s-%4s%2s%2s-%2s%2s%2s-%d');
                $gz = preg_match('/^[a-z]{6}-\d{8}-\d{6}-\d+\.sql.gz$/', $basename);
                $list[$match[7]] = array($match[7], $name, $gz);
            }
            ksort($list);
                       $last = end($list);
            if (count($list) === $last[0]) {
                session('backup_list', $list);
                showmsg('初始化成功!', '/admin/database/import/?part=1&start=0', 1);
            } else {
                showmsg('备份文件可能已经损坏,请检查!');
            }
        } elseif (isset($_GET['part']) && isset($_GET['start'])) {
            $part = intval($_GET['part']);
            $start = intval($_GET['start']);
            $list = success('backup_list');
            if (!isset($list) || !is_array($list)) {
                showmsg('非法操作!');
            }
            $databack = new databack($list[$part], array('path' => $this->config['path'], 'compress' => $list[$part][2]));
            $start = $databack->import($start);
            if (false === $start) {
                showmsg('还原数据出错!');
            } elseif (0 === $start) {                if (isset($list[++$part])) {
                    showmsg('正在还原:卷' . $part . '...', '/admin/database/import/?part=' . $part . '&start=0', 1);
                } else {
                    success('backup_list', null);
                    showmsg('还原完成!', '/admin/database/databacklist', 2);
                }
            } else {
                if ($start[1]) {
                    $rate = floor(100 * ($start[0] / $start[1]));
                    showmsg('正在还原:卷' . $part . '...(' . $rate . '%)', '/admin/database/import/?part=' . $part . '&start=' . $start[0], 1);
                } else {
                    showmsg('正在还原:卷' . $part . '...', '/admin/database/import/?part=' . $part . '&start=' . $start[0] . '&gz=1', 1);
                }
            }
        } else {
            showmsg('参数错误!');
        }
    }
}