discuz_table_archive.php 4.9 KB

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