database.ctrl.php 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. <?php
  2. /**
  3. * [WeEngine System] Copyright (c) 2014 WE7.CC
  4. * WeEngine is NOT a free software, it under the license terms, visited http://www.we7.cc/ for more details.
  5. */
  6. defined('IN_IA') or exit('Access Denied');
  7. set_time_limit(0);
  8. load()->func('file');
  9. load()->model('cloud');
  10. load()->func('db');
  11. load()->model('system');
  12. $dos = array('backup', 'restore', 'trim', 'optimize', 'run', 'scrap_table', 'delete_scrap_table', 'load_scrap_table_data');
  13. $do = in_array($do, $dos) ? $do : 'backup';
  14. if ($do == 'backup') {
  15. if ($_GPC['status']) {
  16. if (empty($_W['setting']['copyright']['status'])) {
  17. itoast('为了保证备份数据完整请关闭站点后再进行此操作', url('system/site'), 'error');
  18. }
  19. $sql = "SHOW TABLE STATUS LIKE '{$_W['config']['db']['tablepre']}%'";
  20. $tables = pdo_fetchall($sql);
  21. if (empty($tables)) {
  22. itoast('数据已经备份完成', url('system/database/'), 'success');
  23. }
  24. $series = max(1, intval($_GPC['series']));
  25. if (!empty($_GPC['volume_suffix']) && !preg_match('/[^0-9A-Za-z-_]/', $_GPC['volume_suffix'])) {
  26. $volume_suffix = $_GPC['volume_suffix'];
  27. } else {
  28. $volume_suffix = random(10);
  29. }
  30. if (!empty($_GPC['folder_suffix']) && !preg_match('/[^0-9A-Za-z-_]/', $_GPC['folder_suffix'])) {
  31. $folder_suffix = $_GPC['folder_suffix'];
  32. } else {
  33. $folder_suffix = TIMESTAMP . '_' . random(8);
  34. }
  35. $bakdir = IA_ROOT . '/data/backup/' . $folder_suffix;
  36. if (trim($_GPC['start'])) {
  37. $result = mkdirs($bakdir);
  38. }
  39. $size = 300;
  40. $volumn = 1024 * 1024 * 2;
  41. $dump = '';
  42. if (empty($_GPC['last_table'])) {
  43. $last_table ='';
  44. $catch = true;
  45. } else {
  46. $last_table = $_GPC['last_table'];
  47. $catch = false;
  48. }
  49. foreach ($tables as $table) {
  50. $table = array_shift($table);
  51. if (!empty($last_table) && $table == $last_table) {
  52. $catch = true;
  53. }
  54. if (!$catch) {
  55. continue;
  56. }
  57. if (!empty($dump)) {
  58. $dump .= "\n\n";
  59. }
  60. if ($table != $last_table) {
  61. $row = db_table_schemas($table);
  62. $dump .= $row;
  63. }
  64. $index = 0;
  65. if (!empty($_GPC['index'])) {
  66. $index = intval($_GPC['index']);
  67. $_GPC['index'] = 0;
  68. }
  69. while (true) {
  70. $start = $index * $size;
  71. $result = db_table_insert_sql($table, $start, $size);
  72. if (!empty($result)) {
  73. $dump .= $result['data'];
  74. if (strlen($dump) > $volumn) {
  75. $bakfile = $bakdir . "/volume-{$volume_suffix}-{$series}.sql";
  76. $dump .= "\n\n";
  77. file_put_contents($bakfile, $dump);
  78. $series++;
  79. $index++;
  80. $current = array(
  81. 'last_table' => $table,
  82. 'index' => $index,
  83. 'series' => $series,
  84. 'volume_suffix'=>$volume_suffix,
  85. 'folder_suffix'=>$folder_suffix,
  86. 'status'=>1
  87. );
  88. $current_series = $series-1;
  89. message('正在导出数据, 请不要关闭浏览器, 当前第 ' . $current_series . ' 卷.', url('system/database/backup/',$current), 'info');
  90. }
  91. }
  92. if (empty($result) || count($result['result']) < $size) {
  93. break;
  94. }
  95. $index++;
  96. }
  97. }
  98. $bakfile = $bakdir . "/volume-{$volume_suffix}-{$series}.sql";
  99. $dump .= "\n\n----WeEngine MySQL Dump End";
  100. file_put_contents($bakfile, $dump);
  101. itoast('数据已经备份完成', url('system/database/'), 'success');
  102. }
  103. }
  104. if($do == 'restore') {
  105. $reduction = system_database_backup();
  106. if (!empty($_GPC['restore_dirname'])) {
  107. $restore_dirname = $_GPC['restore_dirname'];
  108. $restore_dirname_list = array_keys($reduction);
  109. if (!in_array($restore_dirname, $restore_dirname_list)) {
  110. itoast('非法访问', '','error');
  111. exit;
  112. }
  113. $volume_list = $reduction[$restore_dirname]['volume_list'];
  114. if (empty($_GPC['restore_volume_name'])) {
  115. $restore_volume_name = $volume_list[0];
  116. } else {
  117. $restore_volume_name = $_GPC['restore_volume_name'];
  118. }
  119. $restore_volume_sizes = max(1, intval($_GPC['restore_volume_sizes']));
  120. if ($reduction[$restore_dirname]['volume'] < $restore_volume_sizes) {
  121. itoast('成功恢复数据备份. 可能还需要你更新缓存.', url('system/database/restore'), 'success');
  122. exit;
  123. }
  124. $volume_sizes = $restore_volume_sizes;
  125. system_database_volume_restore($restore_volume_name);
  126. $next_restore_volume_name = system_database_volume_next($restore_volume_name);
  127. $restore_volume_sizes ++;
  128. $restore = array (
  129. 'restore_volume_name' => $next_restore_volume_name,
  130. 'restore_volume_sizes' => $restore_volume_sizes,
  131. 'restore_dirname' => $restore_dirname
  132. );
  133. message('正在恢复数据备份, 请不要关闭浏览器, 当前第 ' . $volume_sizes . ' 卷.', url('system/database/restore',$restore), 'success');
  134. }
  135. if ($_GPC['delete_dirname']) {
  136. $delete_dirname = $_GPC['delete_dirname'];
  137. if(!empty($reduction[$delete_dirname]) && system_database_backup_delete($delete_dirname)) {
  138. itoast('删除备份成功.', url('system/database/restore'), 'success');
  139. }
  140. }
  141. }
  142. if ($do == 'trim') {
  143. if ($_W['ispost']) {
  144. $type = $_GPC['type'];
  145. $data = $_GPC['data'];
  146. $table = $_GPC['table'];
  147. if ($type == 'field') {
  148. $sql = "ALTER TABLE `$table` DROP `$data`";
  149. if (false !== pdo_query($sql, $params)) {
  150. exit('success');
  151. }
  152. } elseif ($type == 'index') {
  153. $sql = "ALTER TABLE `$table` DROP INDEX `$data`";
  154. if (false !== pdo_query($sql, $params)) {
  155. exit('success');
  156. }
  157. }
  158. exit();
  159. }
  160. $r = cloud_prepare();
  161. if(is_error($r)) {
  162. itoast($r['message'], url('cloud/profile'), 'error');
  163. }
  164. $upgrade = cloud_schema();
  165. $schemas = $upgrade['schemas'];
  166. if (!empty($schemas)) {
  167. foreach ($schemas as $key => $value) {
  168. $tablename = substr($value['tablename'], 4);
  169. $struct = db_table_schema(pdo(), $tablename);
  170. if (!empty($struct)) {
  171. $temp = db_schema_compare($schemas[$key],$struct);
  172. if (!empty($temp['fields']['less'])) {
  173. $diff[$tablename]['name'] = $value['tablename'];
  174. foreach ($temp['fields']['less'] as $key => $fields_value) {
  175. $diff[$tablename]['fields'][] = $fields_value;
  176. }
  177. }
  178. if (!empty($temp['indexes']['less'])) {
  179. $diff[$tablename]['name'] = $value['tablename'];
  180. foreach ($temp['indexes']['less'] as $key => $indexes_value) {
  181. $diff[$tablename]['indexes'][] = $indexes_value;
  182. }
  183. }
  184. }
  185. }
  186. }
  187. }
  188. if ($do == 'optimize') {
  189. $optimize_table = array();
  190. $sql = "SHOW TABLE STATUS LIKE '{$_W['config']['db']['tablepre']}%'";
  191. $tables = pdo_fetchall($sql);
  192. foreach ($tables as $tableinfo) {
  193. if ($tableinfo['Engine'] == 'InnoDB') {
  194. continue;
  195. }
  196. if (!empty($tableinfo) && !empty($tableinfo['Data_free'])) {
  197. $row = array(
  198. 'title' => $tableinfo['Name'],
  199. 'type' => $tableinfo['Engine'],
  200. 'rows' => $tableinfo['Rows'],
  201. 'data' => sizecount($tableinfo['Data_length']),
  202. 'index' => sizecount($tableinfo['Index_length']),
  203. 'free' => sizecount($tableinfo['Data_free'])
  204. );
  205. $optimize_table[$row['title']] = $row;
  206. }
  207. }
  208. if (checksubmit()) {
  209. foreach ($_GPC['select'] as $tablename) {
  210. if (!empty($optimize_table[$tablename])) {
  211. $sql = "OPTIMIZE TABLE {$tablename}";
  212. pdo_fetch($sql);
  213. }
  214. }
  215. itoast('数据表优化成功.', 'refresh', 'success');
  216. }
  217. }
  218. if ($do == 'run') {
  219. if (!DEVELOPMENT) {
  220. itoast('请先开启开发模式后再使用此功能', referer(), 'info');
  221. }
  222. if (checksubmit()) {
  223. $sql = $_POST['sql'];
  224. pdo_run($sql);
  225. itoast('查询执行成功.', 'refresh', 'success');
  226. }
  227. }
  228. if (in_array($do, array('scrap_table', 'delete_scrap_table', 'load_scrap_table_data'))) {
  229. $installed_modules = table('modules')->where('issystem !=', MODULE_SYSTEM)->getall('name');
  230. }
  231. if ($do == 'scrap_table') {
  232. $pindex = max(1, intval($_GPC['page']));
  233. $psize = 20;
  234. $modules_cloud_table = table('modules_cloud');
  235. $modules_cloud_table->searchWithUninstall(MODULE_CLOUD_UNINSTALL);
  236. $modules_cloud_table->searchWithPage($pindex, $psize);
  237. $module_cloud = $modules_cloud_table->getall('name');
  238. $total = $modules_cloud_table->getLastQueryTotal();
  239. $pager = pagination($total, $pindex, $psize);
  240. if (empty($module_cloud)) {
  241. $module_upgrade = module_upgrade_info();
  242. cache_build_uninstalled_module();
  243. }
  244. $uninstalled_modules = array_diff(array_keys($module_cloud), $installed_modules);
  245. foreach ($module_cloud as $module_key => $module_value) {
  246. if (!in_array($module_key, $uninstalled_modules)) {
  247. unset($module_cloud[$module_key]);
  248. continue;
  249. }
  250. $module_cloud[$module_key] = array('logo' => $module_value['logo'], 'title' => $module_value['title'], 'name' => $module_value['name']);
  251. }
  252. }
  253. if ($do == 'delete_scrap_table') {
  254. $module_name = safe_gpc_string($_GPC['module_name']);
  255. $tables = safe_gpc_string($_GPC['tables']);
  256. if (!empty($installed_modules[$module_name])) {
  257. iajax(-1, '模块已安装并使用,不可删除!');
  258. }
  259. if (!is_array($tables)) {
  260. iajax(-1, '要删除的表数据错误!');
  261. }
  262. $drop_table = array();
  263. foreach ($tables as $table) {
  264. if (pdo_tableexists(ltrim($table, 'ims_'))) {
  265. $drop_table[] = '`' . $table . '`';
  266. }
  267. }
  268. if (empty($drop_table)) {
  269. iajax(0, '系统已不存在这些表,无需删除!');
  270. }
  271. $result = pdo_run("DROP TABLE " . implode(',', $drop_table) . ";");
  272. if ($result) {
  273. iajax(0, '删除成功!');
  274. } else {
  275. iajax(-1, '删除失败!');
  276. }
  277. }
  278. if ($do == 'load_scrap_table_data') {
  279. $module_name = safe_gpc_string($_GPC['module_name']);
  280. if (!empty($installed_modules[$module_name])) {
  281. iajax(0, '');
  282. }
  283. $buildinfo = cloud_m_build($module_name);
  284. if (is_error($buildinfo) || empty($buildinfo['sql'])) {
  285. iajax(0, '');
  286. }
  287. if (!empty($buildinfo['sql'])) {
  288. preg_match_all('/\`ims_[a-zA-Z0-9\-\_]{1,50}\`/', $buildinfo['sql'], $tables);
  289. $tables = array_map(function($item) {return trim($item, '`');}, $tables[0]);
  290. foreach ($tables as $key => $value) {
  291. $value = ltrim($value, 'ims_');
  292. if (!pdo_tableexists($value)) {
  293. unset($tables[$key]);
  294. }
  295. }
  296. }
  297. iajax(0, !empty($tables) ? $tables : '');
  298. }
  299. template('system/database');