| <?php |
| namespace app\admin\controller; |
| use think\Db; |
| use app\common\util\Dir; |
| use app\common\util\Database as dbOper; |
|
|
| class Database extends Base |
| { |
| var $_db_config; |
| public function __construct() |
| { |
| parent::__construct(); |
| } |
|
|
| public function index() |
| { |
| $group = input('group'); |
| if($group=='import'){ |
| |
| $path = trim( $GLOBALS['config']['db']['backup_path'], '/').DS; |
| if (!is_dir($path)) { |
| Dir::create($path); |
| } |
| $flag = \FilesystemIterator::KEY_AS_FILENAME; |
| $glob = new \FilesystemIterator($path, $flag); |
|
|
| $list = []; |
| foreach ($glob as $name => $file) { |
| if(preg_match('/^\d{8,8}-\d{6,6}-\d+\.sql(?:\.gz)?$/', $name)){ |
| $name = sscanf($name, '%4s%2s%2s-%2s%2s%2s-%d'); |
| $date = "{$name[0]}-{$name[1]}-{$name[2]}"; |
| $time = "{$name[3]}:{$name[4]}:{$name[5]}"; |
| $part = $name[6]; |
|
|
| if(isset($list["{$date} {$time}"])){ |
| $info = $list["{$date} {$time}"]; |
| $info['part'] = max($info['part'], $part); |
| $info['size'] = $info['size'] + $file->getSize(); |
| } else { |
| $info['part'] = $part; |
| $info['size'] = $file->getSize(); |
| } |
|
|
| $extension = strtoupper($file->getExtension()); |
| $info['compress'] = ($extension === 'SQL') ? '无' : $extension; |
| $info['time'] = strtotime("{$date} {$time}"); |
|
|
| $list["{$date} {$time}"] = $info; |
| } |
| } |
| } |
| else{ |
| $group='export'; |
| $list = Db::query("SHOW TABLE STATUS"); |
| } |
|
|
| $this->assign('list',$list); |
| $this->assign('title',lang('admin/database/title')); |
| return $this->fetch('admin@database/'.$group); |
| } |
|
|
| public function export($ids = '', $start = 0) |
| { |
| if ($this->request->isPost()) { |
| if (empty($ids)) { |
| return $this->error(lang('admin/database/select_export_table')); |
| } |
|
|
| if (!is_array($ids)) { |
| $tables[] = $ids; |
| } else { |
| $tables = $ids; |
| } |
| $have_admin = false; |
| $admin_table=''; |
| foreach($tables as $k=>$v){ |
| if(strpos($v,'_admin')!==false){ |
| $have_admin=true; |
| $admin_table = $v; |
| unset($tables[$k]); |
| } |
| } |
| if($have_admin){ |
| $tables[] = $admin_table; |
| } |
|
|
| |
| $config = array( |
| 'path' => $GLOBALS['config']['db']['backup_path'] .DS, |
| 'part' => $GLOBALS['config']['db']['part_size'] , |
| 'compress' => $GLOBALS['config']['db']['compress'] , |
| 'level' => $GLOBALS['config']['db']['compress_level'] , |
| ); |
|
|
| |
| $lock = "{$config['path']}backup.lock"; |
| if(is_file($lock)){ |
| return $this->error(lang('admin/database/lock_check')); |
| } else { |
| if (!is_dir($config['path'])) { |
| Dir::create($config['path'], 0755, true); |
| } |
| |
| file_put_contents($lock, $this->request->time()); |
| } |
|
|
| |
| $file = [ |
| 'name' => date('Ymd-His', $this->request->time()), |
| 'part' => 1, |
| ]; |
|
|
| |
| $database = new dbOper($file, $config); |
| if($database->create() !== false) { |
| |
| foreach ($tables as $table) { |
| $start = $database->backup($table, $start); |
| while (0 !== $start) { |
| if (false === $start) { |
| return $this->error(lang('admin/database/backup_err')); |
| } |
| $start = $database->backup($table, $start[0]); |
| } |
| } |
| |
| unlink($lock); |
| } |
| return $this->success(lang('admin/database/backup_ok')); |
| } |
| return $this->error(lang('admin/database/backup_err')); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function import($id = '') |
| { |
| if (empty($id)) { |
| return $this->error(lang('admin/database/select_file')); |
| } |
|
|
| $name = date('Ymd-His', $id) . '-*.sql*'; |
| $path = trim( $GLOBALS['config']['db']['backup_path'] , '/').DS.$name; |
| $files = glob($path); |
| $list = array(); |
| foreach($files as $name){ |
| $basename = basename($name); |
| $match = sscanf($basename, '%4s%2s%2s-%2s%2s%2s-%d'); |
| $gz = preg_match('/^\d{8,8}-\d{6,6}-\d+\.sql.gz$/', $basename); |
| $list[$match[6]] = array($match[6], $name, $gz); |
| } |
| ksort($list); |
|
|
| |
| $last = end($list); |
| if(count($list) === $last[0]){ |
| foreach ($list as $item) { |
| $config = [ |
| 'path' => trim($GLOBALS['config']['db']['backup_path'], '/').DS, |
| 'compress' => $item[2] |
| ]; |
| $database = new dbOper($item, $config); |
| $start = $database->import(0); |
| |
| while (0 !== $start) { |
| if (false === $start) { |
| return $this->error(lang('admin/database/import_err')); |
| } |
| $start = $database->import($start[0]); |
| } |
| } |
| return $this->success(lang('admin/database/import_ok')); |
| } |
| return $this->error(lang('admin/database/file_damage')); |
| } |
|
|
| public function optimize($ids = '') |
| { |
| if (empty($ids)) { |
| return $this->error(lang('admin/database/select_optimize_table')); |
| } |
|
|
| if (!is_array($ids)) { |
| $table[] = $ids; |
| } else { |
| $table = $ids; |
| } |
|
|
| $tables = implode('`,`', $table); |
| $res = Db::query("OPTIMIZE TABLE `{$tables}`"); |
| if ($res) { |
| return $this->success(lang('admin/database/optimize_ok')); |
| } |
| return $this->error(lang('admin/database/optimize_err')); |
| } |
|
|
| public function repair($ids = '') |
| { |
| if (empty($ids)) { |
| return $this->error(lang('admin/database/select_repair_table')); |
| } |
|
|
| if (!is_array($ids)) { |
| $table[] = $ids; |
| } else { |
| $table = $ids; |
| } |
|
|
| $tables = implode('`,`', $table); |
| $res = Db::query("REPAIR TABLE `{$tables}`"); |
| if ($res) { |
| return $this->success(lang('admin/database/repair_ok')); |
| } |
| return $this->error(lang('admin/database/repair_ok')); |
| } |
|
|
| public function del($id = '') |
| { |
| if (empty($id)) { |
| return $this->error(lang('admin/database/select_del_file')); |
| } |
|
|
| $name = date('Ymd-His', $id) . '-*.sql*'; |
| $path = trim($GLOBALS['config']['db']['backup_path']).DS.$name; |
| array_map("unlink", glob($path)); |
| if(count(glob($path)) && glob($path)){ |
| return $this->error(lang('del_err')); |
| } |
| return $this->success(lang('del_ok')); |
| } |
|
|
| public function sql() |
| { |
| if($this->request->isPost()){ |
| $param=input(); |
| $validate = \think\Loader::validate('Token'); |
| if(!$validate->check($param)){ |
| return $this->error($validate->getError()); |
| } |
|
|
| $sql = trim($param['sql']); |
|
|
| if(!empty($sql)){ |
| $sql = str_replace('{pre}',config('database.prefix'),$sql); |
| |
| if( |
| strtolower(substr($sql,0,6))=="select" || |
| stripos($sql, ' outfile') !== false |
| ){ |
|
|
| } |
| else{ |
| Db::execute($sql); |
| } |
| } |
| $this->success(lang('run_ok')); |
| } |
| return $this->fetch('admin@database/sql'); |
| } |
|
|
| public function columns() |
| { |
| $param = input(); |
| $table = $param['table']; |
| if (!empty($table) && !$this->isValidTable($table)) { |
| return $this->error('Table is invalid.'); |
| } |
| if (!empty($table)) { |
| $list = Db::query('SHOW COLUMNS FROM ' . $table); |
| $this->success(lang('obtain_ok'),null, $list); |
| } |
| $this->error(lang('param_err')); |
| } |
|
|
| public function rep() |
| { |
| if($this->request->isPost()){ |
| $param = input(); |
| $table = $param['table']; |
| $field = $param['field']; |
| $findstr = $param['findstr']; |
| $tostr = $param['tostr']; |
| $where = $param['where']; |
|
|
| $validate = \think\Loader::validate('Token'); |
| if(!$validate->check($param)){ |
| return $this->error($validate->getError()); |
| } |
| if (!empty($table) && !$this->isValidTable($table)) { |
| return $this->error('Table is invalid.'); |
| } |
| if(!empty($field) && !empty($findstr) && !empty($tostr)){ |
| $sql = "UPDATE ".$table." set ".$field."=Replace(".$field.",'".$findstr."','".$tostr."') where 1=1 ". $where; |
| Db::execute($sql); |
| return $this->success(lang('run_ok')); |
| } |
|
|
| return $this->error(lang('param_err')); |
| } |
| $list = Db::query("SHOW TABLE STATUS"); |
| $this->assign('list',$list); |
| return $this->fetch('admin@database/rep'); |
| } |
|
|
| private function isValidTable($table) { |
| $list = Db::query("SHOW TABLE STATUS"); |
| foreach ($list as $table_raw) { |
| if ($table_raw['Name'] == $table) { |
| return true; |
| } |
| } |
| return false; |
| } |
| } |
|
|