ImportController.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: NODELOG
  5. * Date: 16/3/2
  6. * Time: 下午8:05
  7. */
  8. namespace backup\controllers;
  9. use backup\models\Database;
  10. use yii\base\Exception;
  11. use yii\data\ArrayDataProvider;
  12. use yii\web\Controller;
  13. use yii\web\Response;
  14. class ImportController extends Controller
  15. {
  16. public function actionIndex()
  17. {
  18. //列出备份文件列表
  19. $path = \Yii::$app->controller->module->params['DATA_BACKUP_PATH'];
  20. if(!is_dir($path)){
  21. mkdir($path, 0755, true);
  22. }
  23. $path = realpath($path);
  24. $flag = \FilesystemIterator::KEY_AS_FILENAME;
  25. $glob = new \FilesystemIterator($path, $flag);
  26. $list = array();
  27. foreach ($glob as $name => $file) {
  28. if(preg_match('/^\d{8,8}-\d{6,6}-\d+\.sql(?:\.gz)?$/', $name)){
  29. $name = sscanf($name, '%4s%2s%2s-%2s%2s%2s-%d');
  30. $date = "{$name[0]}-{$name[1]}-{$name[2]}";
  31. $time = "{$name[3]}:{$name[4]}:{$name[5]}";
  32. $part = $name[6];
  33. if(isset($list["{$date} {$time}"])){
  34. $info = $list["{$date} {$time}"];
  35. $info['part'] = max($info['part'], $part);
  36. $info['size'] = $info['size'] + $file->getSize();
  37. } else {
  38. $info['part'] = $part;
  39. $info['size'] = $file->getSize();
  40. }
  41. $extension = strtoupper(pathinfo($file->getFilename(), PATHINFO_EXTENSION));
  42. $info['compress'] = ($extension === 'SQL') ? '-' : $extension;
  43. $info['time'] = strtotime("{$date} {$time}");
  44. $list["{$date} {$time}"] = $info;
  45. }
  46. }
  47. $dataProvider = new ArrayDataProvider([
  48. 'allModels' => $list
  49. ]);
  50. return $this->render('index', [
  51. 'dataProvider' => $dataProvider
  52. ]);
  53. }
  54. /**
  55. * 还原数据库初始化
  56. * @param int $time
  57. * @return mixed
  58. */
  59. public function actionInit($time = 0)
  60. {
  61. \Yii::$app->response->format = Response::FORMAT_JSON;
  62. //获取备份文件信息
  63. $name = date('Ymd-His', $time) . '-*.sql*';
  64. $path = realpath(\Yii::$app->controller->module->params['DATA_BACKUP_PATH']) . DIRECTORY_SEPARATOR . $name;
  65. $files = glob($path);
  66. $list = array();
  67. foreach($files as $name){
  68. $basename = basename($name);
  69. $match = sscanf($basename, '%4s%2s%2s-%2s%2s%2s-%d');
  70. $gz = preg_match('/^\d{8,8}-\d{6,6}-\d+\.sql.gz$/', $basename);
  71. $list[$match[6]] = array($match[6], $name, $gz);
  72. }
  73. ksort($list);
  74. //检测文件正确性
  75. $last = end($list);
  76. if(count($list) === $last[0]){
  77. \Yii::$app->session->set('backup_list', $list); //缓存备份列表
  78. return [
  79. 'status' => 1,
  80. 'part' => 1,
  81. 'start' =>0,
  82. 'info' => '初始化完成!'
  83. ];
  84. } else {
  85. return [
  86. 'status' => 0,
  87. 'info' => '备份文件可能已经损坏,请检查!'
  88. ];
  89. }
  90. }
  91. public function actionStart()
  92. {
  93. $part = \Yii::$app->request->post('part');
  94. $start = \Yii::$app->request->post('start');
  95. \Yii::$app->response->format = Response::FORMAT_JSON;
  96. $list = \Yii::$app->session->get('backup_list');
  97. $db = new Database($list[$part], array(
  98. 'path' => realpath(\Yii::$app->controller->module->params['DATA_BACKUP_PATH']) . DIRECTORY_SEPARATOR,
  99. 'compress' => $list[$part][2]));
  100. $start = $db->import($start);
  101. if (false === $start) {
  102. return ['status' => 0, 'info' => '还原数据出错'];
  103. } elseif(0 === $start) { //下一卷
  104. if(isset($list[++$part])){
  105. return [
  106. 'status' => 1,
  107. 'info' => "正在还原...#{$part}",
  108. 'part' => $part,
  109. 'start' => 0
  110. ];
  111. } else {
  112. \Yii::$app->session->set('backup_list', null);
  113. return ['status' => 1, 'info' => '还原完成!'];
  114. }
  115. } else {
  116. if($start[1]){
  117. $rate = floor(100 * ($start[0] / $start[1]));
  118. return [
  119. 'status' => 1,
  120. 'info' => "正在还原...#{$part} ({$rate}%)",
  121. 'part' => $part,
  122. 'start' => $start[0],
  123. ];
  124. } else {
  125. return [
  126. 'status' => 1,
  127. 'info' => "正在还原...#{$part}",
  128. 'part' => $part,
  129. 'start' => $start[0],
  130. 'gz' => 1
  131. ];
  132. }
  133. }
  134. }
  135. public function actionDel()
  136. {
  137. \Yii::$app->response->format = 'json';
  138. $time = \Yii::$app->request->post('time');
  139. if($time){
  140. $name = date('Ymd-His', $time) . '-*.sql*';
  141. $path = realpath(\Yii::$app->controller->module->params['DATA_BACKUP_PATH']) . DIRECTORY_SEPARATOR . $name;
  142. array_map("unlink", glob($path));
  143. if(count(glob($path))){
  144. throw new Exception('备份文件删除失败,请检查权限!');
  145. } else {
  146. return ['message' => '备份文件删除成功!'];
  147. }
  148. } else {
  149. throw new Exception('参数错误!');
  150. }
  151. }
  152. }