discuz_table_archive.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. <?php
  2. /**
  3. * [Discuz!] (C)2001-2099 Discuz! Team
  4. * This is NOT a freeware, use is subject to license terms
  5. * https://license.discuz.vip
  6. */
  7. if(!defined('IN_DISCUZ')) {
  8. exit('Access Denied');
  9. }
  10. class discuz_table_archive extends discuz_table {
  11. public $membersplit = null;
  12. public function __construct($para = []) {
  13. $this->membersplit = getglobal('setting/membersplit');
  14. parent::__construct($para);
  15. }
  16. public $tablestatus = [];
  17. public function fetch($id, $force_from_db = false, $fetch_archive = 0) {
  18. $data = [];
  19. if(!empty($id)) {
  20. $data = parent::fetch($id, $force_from_db);
  21. if(isset($this->membersplit) && $fetch_archive && empty($data)) {
  22. $data = C::t($this->_table.'_archive')->fetch($id);
  23. }
  24. }
  25. return $data;
  26. }
  27. public function fetch_all($ids, $force_from_db = false, $fetch_archive = 1) {
  28. $data = [];
  29. if(!empty($ids)) {
  30. $data = parent::fetch_all($ids, $force_from_db);
  31. if(isset($this->membersplit) && $fetch_archive && count($data) != count($ids)) {
  32. $data = $data + C::t($this->_table.'_archive')->fetch_all(array_diff($ids, array_keys($data)));
  33. }
  34. }
  35. return $data;
  36. }
  37. public function delete($val, $unbuffered = false, $fetch_archive = 0) {
  38. $ret = false;
  39. if($val) {
  40. $ret = parent::delete($val, $unbuffered);
  41. if(isset($this->membersplit) && $fetch_archive) {
  42. $_ret = C::t($this->_table.'_archive')->delete($val, $unbuffered);
  43. if(!$unbuffered) {
  44. $ret = $ret + $_ret;
  45. }
  46. }
  47. }
  48. return $ret;
  49. }
  50. public function split_check($wheresql) {
  51. $status = helper_dbtool::gettablestatus(DB::table($this->_table), false);
  52. if($status && $status['Data_length'] > 100 * 1048576) {//400 * 1048576
  53. if($moverows = DB::result_first('SELECT COUNT(*) FROM %t WHERE '.$wheresql, [$this->_table])) {
  54. $status['Move_rows'] = $moverows;
  55. $this->tablestatus = $status;
  56. return true;
  57. }
  58. }
  59. return false;
  60. }
  61. public function create_relatedtable($relatedtablename) {
  62. if(!helper_dbtool::isexisttable($relatedtablename)) {
  63. DB::query('SET SQL_QUOTE_SHOW_CREATE=0', 'SILENT');
  64. $tableinfo = DB::fetch_first('SHOW CREATE TABLE '.DB::table($this->_table));
  65. $createsql = $tableinfo['Create Table'];
  66. $createsql = str_replace($this->_table, $relatedtablename, $createsql);
  67. DB::query($createsql);
  68. }
  69. return true;
  70. }
  71. public function split_table($wheresql) {
  72. $limit = 2000;
  73. $targettable = helper_dbtool::showtablecloumn($this->_table);
  74. $fieldstr = '`'.implode('`, `', array_keys($targettable)).'`';
  75. if(!$this->_pk && !in_array('split_id', array_keys($targettable))) {
  76. DB::query('ALTER TABLE %t ADD split_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, ADD UNIQUE KEY split_id (split_id)', [$this->_table]);
  77. return 1;
  78. }
  79. $tmptable = $this->_table.'_tmp___';
  80. $archivetable = $this->_table.'_archive';
  81. $key = $this->_pk ? $this->_pk : 'split_id';
  82. $this->create_relatedtable($tmptable);
  83. $this->create_relatedtable($archivetable);
  84. DB::query("INSERT INTO %t ($fieldstr) SELECT $fieldstr FROM %t WHERE $wheresql ".DB::limit($limit), [$tmptable, $this->_table]);
  85. if(DB::result_first('SELECT COUNT(*) FROM %t', [$tmptable])) {
  86. $keylist = DB::fetch_all('SELECT '.$key.' FROM %t', [$tmptable], $key);
  87. $keylist = dimplode(array_keys($keylist));
  88. if(DB::query("INSERT INTO %t ($fieldstr) SELECT $fieldstr FROM %t WHERE $key in ($keylist)", [$archivetable, $this->_table], false, true)) {
  89. DB::query("DELETE FROM %t WHERE $key in ($keylist)", [$this->_table], false, true);
  90. }
  91. DB::query('DROP TABLE %t', [$tmptable]);
  92. return 1;
  93. } else {
  94. DB::query('DROP TABLE %t', [$tmptable]);
  95. $this->optimize();
  96. return 2;
  97. }
  98. }
  99. public function merge_table() {
  100. $limit = 2000;
  101. $tmptable = $this->_table.'_tmp___';
  102. $archivetable = $this->_table.'_archive';
  103. $key = $this->_pk ? $this->_pk : 'split_id';
  104. if(!helper_dbtool::isexisttable($archivetable)) {
  105. return 2;
  106. }
  107. $this->create_relatedtable($tmptable);
  108. $targettable = helper_dbtool::showtablecloumn($this->_table);
  109. $fieldstr = '`'.implode('`, `', array_keys($targettable)).'`';
  110. DB::query("INSERT INTO %t ($fieldstr) SELECT $fieldstr FROM %t ".DB::limit($limit), [$tmptable, $archivetable]);
  111. if(DB::result_first('SELECT COUNT(*) FROM %t', [$tmptable])) {
  112. $keylist = DB::fetch_all('SELECT '.$key.' FROM %t', [$tmptable], $key);
  113. $keylist = dimplode(array_keys($keylist));
  114. if(DB::query("INSERT INTO %t ($fieldstr) SELECT $fieldstr FROM %t WHERE $key in ($keylist)", [$this->_table, $archivetable], false, true)) {
  115. DB::query("DELETE FROM %t WHERE $key in ($keylist)", [$archivetable], false, true);
  116. }
  117. DB::query('DROP TABLE %t', [$tmptable]);
  118. return 1;
  119. } else {
  120. DB::query('DROP TABLE %t', [$tmptable]);
  121. DB::query('DROP TABLE %t', [$archivetable]);
  122. $this->optimize();
  123. return 2;
  124. }
  125. }
  126. }