<?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('参数错误!');
}
}
}