update.func.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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: update.func.php 34824 2014-08-12 02:27:09Z nemohou $
  7. */
  8. if(!defined('IN_DISCUZ')) {
  9. exit('Access Denied');
  10. }
  11. include_once libfile('function/plugin');
  12. if(!function_exists('updatetable')) {
  13. function updatetable($sql) {
  14. global $_G;
  15. $config = array(
  16. 'dbcharset' => $_G['config']['db']['1']['dbcharset'],
  17. 'charset' => $_G['config']['output']['charset'],
  18. 'tablepre' => $_G['config']['db']['1']['tablepre']
  19. );
  20. preg_match_all("/CREATE\s+TABLE.+?pre\_(.+?)\s*\((.+?)\)\s*(ENGINE|TYPE)\s*=\s*(\w+)/is", $sql, $matches);
  21. $newtables = empty($matches[1])?array():$matches[1];
  22. $newsqls = empty($matches[0])?array():$matches[0];
  23. if(empty($newtables) || empty($newsqls)) {
  24. return array(1);
  25. }
  26. foreach($newtables as $i => $newtable) {
  27. $newcols = updatetable_getcolumn($newsqls[$i]);
  28. if(!$query = DB::query("SHOW CREATE TABLE ".DB::table($newtable), 'SILENT')) {
  29. preg_match("/(CREATE TABLE .+?)\s*(ENGINE|TYPE)\s*=\s*(\w+)/is", $newsqls[$i], $maths);
  30. $maths[3] = strtoupper($maths[3]);
  31. if($maths[3] == 'MEMORY' || $maths[3] == 'HEAP') {
  32. $type = helper_dbtool::dbversion() > '4.1' ? " ENGINE=MEMORY".(empty($config['dbcharset'])?'':" DEFAULT CHARSET=$config[dbcharset]" ): " TYPE=HEAP";
  33. } else {
  34. $type = helper_dbtool::dbversion() > '4.1' ? " ENGINE=MYISAM".(empty($config['dbcharset'])?'':" DEFAULT CHARSET=$config[dbcharset]" ): " TYPE=MYISAM";
  35. }
  36. $usql = $maths[1].$type;
  37. $usql = str_replace("CREATE TABLE IF NOT EXISTS pre_", 'CREATE TABLE IF NOT EXISTS '.$config['tablepre'], $usql);
  38. $usql = str_replace("CREATE TABLE pre_", 'CREATE TABLE '.$config['tablepre'], $usql);
  39. if(!DB::query($usql, 'SILENT')) {
  40. return array(-1, $newtable);
  41. }
  42. } else {
  43. $value = DB::fetch($query);
  44. $oldcols = updatetable_getcolumn($value['Create Table']);
  45. $updates = array();
  46. $allfileds =array_keys($newcols);
  47. foreach ($newcols as $key => $value) {
  48. if($key == 'PRIMARY') {
  49. if($value != $oldcols[$key]) {
  50. if(!empty($oldcols[$key])) {
  51. $usql = "RENAME TABLE ".DB::table($newtable)." TO ".DB::table($newtable.'_bak');
  52. if(!DB::query($usql, 'SILENT')) {
  53. return array(-1, $newtable);
  54. }
  55. }
  56. $updates[] = "ADD PRIMARY KEY $value";
  57. }
  58. } elseif ($key == 'KEY') {
  59. foreach ($value as $subkey => $subvalue) {
  60. if(!empty($oldcols['KEY'][$subkey])) {
  61. if($subvalue != $oldcols['KEY'][$subkey]) {
  62. $updates[] = "DROP INDEX `$subkey`";
  63. $updates[] = "ADD INDEX `$subkey` $subvalue";
  64. }
  65. } else {
  66. $updates[] = "ADD INDEX `$subkey` $subvalue";
  67. }
  68. }
  69. } elseif ($key == 'UNIQUE') {
  70. foreach ($value as $subkey => $subvalue) {
  71. if(!empty($oldcols['UNIQUE'][$subkey])) {
  72. if($subvalue != $oldcols['UNIQUE'][$subkey]) {
  73. $updates[] = "DROP INDEX `$subkey`";
  74. $updates[] = "ADD UNIQUE INDEX `$subkey` $subvalue";
  75. }
  76. } else {
  77. $usql = "ALTER TABLE ".DB::table($newtable)." DROP INDEX `$subkey`";
  78. DB::query($usql, 'SILENT');
  79. $updates[] = "ADD UNIQUE INDEX `$subkey` $subvalue";
  80. }
  81. }
  82. } else {
  83. if(!empty($oldcols[$key])) {
  84. if(strtolower($value) != strtolower($oldcols[$key])) {
  85. $updates[] = "CHANGE `$key` `$key` $value";
  86. }
  87. } else {
  88. $i = array_search($key, $allfileds);
  89. $fieldposition = $i > 0 ? 'AFTER `'.$allfileds[$i-1].'`' : 'FIRST';
  90. $updates[] = "ADD `$key` $value $fieldposition";
  91. }
  92. }
  93. }
  94. if(!empty($updates)) {
  95. $usql = "ALTER TABLE ".DB::table($newtable)." ".implode(', ', $updates);
  96. if(!DB::query($usql, 'SILENT')) {
  97. return array(-1, $newtable);
  98. }
  99. }
  100. }
  101. }
  102. return array(1);
  103. }
  104. function updatetable_getcolumn($creatsql) {
  105. $creatsql = preg_replace("/ COMMENT '.*?'/i", '', $creatsql);
  106. preg_match("/\((.+)\)\s*(ENGINE|TYPE)\s*\=/is", $creatsql, $matchs);
  107. $cols = explode("\n", $matchs[1]);
  108. $newcols = array();
  109. foreach ($cols as $value) {
  110. $value = trim($value);
  111. if(empty($value)) continue;
  112. $value = updatetable_remakesql($value);
  113. if(substr($value, -1) == ',') $value = substr($value, 0, -1);
  114. $vs = explode(' ', $value);
  115. $cname = $vs[0];
  116. if($cname == 'KEY' || $cname == 'INDEX' || $cname == 'UNIQUE') {
  117. $name_length = strlen($cname);
  118. if($cname == 'UNIQUE') $name_length = $name_length + 4;
  119. $subvalue = trim(substr($value, $name_length));
  120. $subvs = explode(' ', $subvalue);
  121. $subcname = $subvs[0];
  122. $newcols[$cname][$subcname] = trim(substr($value, ($name_length+2+strlen($subcname))));
  123. } elseif($cname == 'PRIMARY') {
  124. $newcols[$cname] = trim(substr($value, 11));
  125. } else {
  126. $newcols[$cname] = trim(substr($value, strlen($cname)));
  127. }
  128. }
  129. return $newcols;
  130. }
  131. function updatetable_remakesql($value) {
  132. $value = trim(preg_replace("/\s+/", ' ', $value));
  133. $value = str_replace(array('`',', ', ' ,', '( ' ,' )', 'mediumtext'), array('', ',', ',','(',')','text'), $value);
  134. return $value;
  135. }
  136. }
  137. ?>