db.func.php 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  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. $GLOBALS['_W']['config']['db']['tablepre'] = empty($GLOBALS['_W']['config']['db']['tablepre']) ? $GLOBALS['_W']['config']['db']['master']['tablepre'] : $GLOBALS['_W']['config']['db']['tablepre'];
  8. function db_table_schema($db, $tablename = '') {
  9. $result = $db->fetch("SHOW TABLE STATUS LIKE '" . trim($db->tablename($tablename), '`') . "'");
  10. if(empty($result)) {
  11. return array();
  12. }
  13. $ret['tablename'] = $result['Name'];
  14. $ret['charset'] = $result['Collation'];
  15. $ret['engine'] = $result['Engine'];
  16. $ret['increment'] = $result['Auto_increment'];
  17. $result = $db->fetchall("SHOW FULL COLUMNS FROM " . $db->tablename($tablename));
  18. foreach($result as $value) {
  19. $temp = array();
  20. $type = explode(" ", $value['Type'], 3);
  21. $temp['name'] = $value['Field'];
  22. $pieces = explode('(', $type[0], 2);
  23. $temp['type'] = $pieces[0];
  24. $temp['length'] = rtrim($pieces[1], ')');
  25. $temp['null'] = $value['Null'] != 'NO';
  26. $temp['signed'] = empty($type[1]);
  27. $temp['increment'] = $value['Extra'] == 'auto_increment';
  28. $temp['default'] = $value['Default'];
  29. $temp['zerofill'] = $type[2];
  30. $ret['fields'][$value['Field']] = $temp;
  31. }
  32. $result = $db->fetchall("SHOW INDEX FROM " . $db->tablename($tablename));
  33. foreach($result as $value) {
  34. $ret['indexes'][$value['Key_name']]['name'] = $value['Key_name'];
  35. $ret['indexes'][$value['Key_name']]['type'] = ($value['Key_name'] == 'PRIMARY') ? 'primary' : ($value['Non_unique'] == 0 ? 'unique' : 'index');
  36. $ret['indexes'][$value['Key_name']]['fields'][] = $value['Column_name'];
  37. }
  38. return $ret;
  39. }
  40. function db_table_serialize($db, $dbname) {
  41. $tables = $db->fetchall('SHOW TABLES');
  42. if (empty($tables)) {
  43. return '';
  44. }
  45. $struct = array();
  46. foreach ($tables as $value) {
  47. $structs[] = db_table_schema($db, substr($value['Tables_in_' . $dbname], strpos($value['Tables_in_' . $dbname], '_') + 1));
  48. }
  49. return iserializer($structs);
  50. }
  51. function db_table_create_sql($schema) {
  52. $pieces = explode('_', $schema['charset']);
  53. $charset = $pieces[0];
  54. $engine = $schema['engine'];
  55. $schema['tablename'] = str_replace('ims_', $GLOBALS['_W']['config']['db']['tablepre'], $schema['tablename']);
  56. $sql = "CREATE TABLE IF NOT EXISTS `{$schema['tablename']}` (\n";
  57. foreach ($schema['fields'] as $value) {
  58. $piece = _db_build_field_sql($value);
  59. $sql .= "`{$value['name']}` {$piece},\n";
  60. }
  61. foreach ($schema['indexes'] as $value) {
  62. $fields = implode('`,`', $value['fields']);
  63. if($value['type'] == 'index') {
  64. $sql .= "KEY `{$value['name']}` (`{$fields}`),\n";
  65. }
  66. if($value['type'] == 'unique') {
  67. $sql .= "UNIQUE KEY `{$value['name']}` (`{$fields}`),\n";
  68. }
  69. if($value['type'] == 'primary') {
  70. $sql .= "PRIMARY KEY (`{$fields}`),\n";
  71. }
  72. }
  73. $sql = rtrim($sql);
  74. $sql = rtrim($sql, ',');
  75. $sql .= "\n) ENGINE=$engine DEFAULT CHARSET=$charset;\n\n";
  76. return $sql;
  77. }
  78. function db_schema_compare($table1, $table2) {
  79. $table1['charset'] == $table2['charset'] ? '' : $ret['diffs']['charset'] = true;
  80. $fields1 = array_keys($table1['fields']);
  81. $fields2 = array_keys($table2['fields']);
  82. $diffs = array_diff($fields1, $fields2);
  83. if(!empty($diffs)) {
  84. $ret['fields']['greater'] = array_values($diffs);
  85. }
  86. $diffs = array_diff($fields2, $fields1);
  87. if(!empty($diffs)) {
  88. $ret['fields']['less'] = array_values($diffs);
  89. }
  90. $diffs = array();
  91. $intersects = array_intersect($fields1, $fields2);
  92. if(!empty($intersects)) {
  93. foreach($intersects as $field) {
  94. if($table1['fields'][$field] != $table2['fields'][$field]) {
  95. $diffs[] = $field;
  96. }
  97. }
  98. }
  99. if(!empty($diffs)) {
  100. $ret['fields']['diff'] = array_values($diffs);
  101. }
  102. $indexes1 = is_array($table1['indexes']) ? array_keys($table1['indexes']) : array();
  103. $indexes2 = is_array($table2['indexes']) ? array_keys($table2['indexes']) : array();
  104. $diffs = array_diff($indexes1, $indexes2);
  105. if(!empty($diffs)) {
  106. $ret['indexes']['greater'] = array_values($diffs);
  107. }
  108. $diffs = array_diff($indexes2, $indexes1);
  109. if(!empty($diffs)) {
  110. $ret['indexes']['less'] = array_values($diffs);
  111. }
  112. $diffs = array();
  113. $intersects = array_intersect($indexes1, $indexes2);
  114. if(!empty($intersects)) {
  115. foreach($intersects as $index) {
  116. if($table1['indexes'][$index] != $table2['indexes'][$index]) {
  117. $diffs[] = $index;
  118. }
  119. }
  120. }
  121. if(!empty($diffs)) {
  122. $ret['indexes']['diff'] = array_values($diffs);
  123. }
  124. return $ret;
  125. }
  126. function db_table_fix_sql($schema1, $schema2, $strict = false) {
  127. if(empty($schema1)) {
  128. return array(db_table_create_sql($schema2));
  129. }
  130. $diff = $result = db_schema_compare($schema1, $schema2);
  131. if(!empty($diff['diffs']['tablename'])) {
  132. return array(db_table_create_sql($schema2));
  133. }
  134. $sqls = array();
  135. if(!empty($diff['diffs']['engine'])) {
  136. $sqls[] = "ALTER TABLE `{$schema1['tablename']}` ENGINE = {$schema2['engine']}";
  137. }
  138. if(!empty($diff['diffs']['charset'])) {
  139. $pieces = explode('_', $schema2['charset']);
  140. $charset = $pieces[0];
  141. $sqls[] = "ALTER TABLE `{$schema1['tablename']}` DEFAULT CHARSET = {$charset}";
  142. }
  143. if(!empty($diff['fields'])) {
  144. if(!empty($diff['fields']['less'])) {
  145. foreach($diff['fields']['less'] as $fieldname) {
  146. $field = $schema2['fields'][$fieldname];
  147. $piece = _db_build_field_sql($field);
  148. if(!empty($field['rename']) && !empty($schema1['fields'][$field['rename']])) {
  149. $sql = "ALTER TABLE `{$schema1['tablename']}` CHANGE `{$field['rename']}` `{$field['name']}` {$piece}";
  150. unset($schema1['fields'][$field['rename']]);
  151. } else {
  152. if($field['position']) {
  153. $pos = ' ' . $field['position'];
  154. }
  155. $sql = "ALTER TABLE `{$schema1['tablename']}` ADD `{$field['name']}` {$piece}{$pos}";
  156. }
  157. $primary = array();
  158. $isincrement = array();
  159. if (strexists($sql, 'AUTO_INCREMENT')) {
  160. $isincrement = $field;
  161. $sql = str_replace('AUTO_INCREMENT', '', $sql);
  162. foreach ($schema1['fields'] as $field) {
  163. if ($field['increment'] == 1) {
  164. $primary = $field;
  165. break;
  166. }
  167. }
  168. if (!empty($primary)) {
  169. $piece = _db_build_field_sql($primary);
  170. if (!empty($piece)) {
  171. $piece = str_replace('AUTO_INCREMENT', '', $piece);
  172. }
  173. $sqls[] = "ALTER TABLE `{$schema1['tablename']}` CHANGE `{$primary['name']}` `{$primary['name']}` {$piece}";
  174. }
  175. }
  176. $sqls[] = $sql;
  177. }
  178. }
  179. if(!empty($diff['fields']['diff'])) {
  180. foreach($diff['fields']['diff'] as $fieldname) {
  181. $field = $schema2['fields'][$fieldname];
  182. $piece = _db_build_field_sql($field);
  183. if(!empty($schema1['fields'][$fieldname])) {
  184. $sqls[] = "ALTER TABLE `{$schema1['tablename']}` CHANGE `{$field['name']}` `{$field['name']}` {$piece}";
  185. }
  186. }
  187. }
  188. if($strict && !empty($diff['fields']['greater'])) {
  189. foreach($diff['fields']['greater'] as $fieldname) {
  190. if(!empty($schema1['fields'][$fieldname])) {
  191. $sqls[] = "ALTER TABLE `{$schema1['tablename']}` DROP `{$fieldname}`";
  192. }
  193. }
  194. }
  195. }
  196. if(!empty($diff['indexes'])) {
  197. if(!empty($diff['indexes']['less'])) {
  198. foreach($diff['indexes']['less'] as $indexname) {
  199. $index = $schema2['indexes'][$indexname];
  200. $piece = _db_build_index_sql($index);
  201. $sqls[] = "ALTER TABLE `{$schema1['tablename']}` ADD {$piece}";
  202. }
  203. }
  204. if(!empty($diff['indexes']['diff'])) {
  205. foreach($diff['indexes']['diff'] as $indexname) {
  206. $index = $schema2['indexes'][$indexname];
  207. $piece = _db_build_index_sql($index);
  208. $sqls[] = "ALTER TABLE `{$schema1['tablename']}` DROP ".($indexname == 'PRIMARY' ? " PRIMARY KEY " : "INDEX {$indexname}").", ADD {$piece}";
  209. }
  210. }
  211. if($strict && !empty($diff['indexes']['greater'])) {
  212. foreach($diff['indexes']['greater'] as $indexname) {
  213. $sqls[] = "ALTER TABLE `{$schema1['tablename']}` DROP `{$indexname}`";
  214. }
  215. }
  216. }
  217. if (!empty($isincrement)) {
  218. $piece = _db_build_field_sql($isincrement);
  219. $sqls[] = "ALTER TABLE `{$schema1['tablename']}` CHANGE `{$isincrement['name']}` `{$isincrement['name']}` {$piece}";
  220. }
  221. return $sqls;
  222. }
  223. function _db_build_index_sql($index) {
  224. $piece = '';
  225. $fields = implode('`,`', $index['fields']);
  226. if($index['type'] == 'index') {
  227. $piece .= " INDEX `{$index['name']}` (`{$fields}`)";
  228. }
  229. if($index['type'] == 'unique') {
  230. $piece .= "UNIQUE `{$index['name']}` (`{$fields}`)";
  231. }
  232. if($index['type'] == 'primary') {
  233. $piece .= "PRIMARY KEY (`{$fields}`)";
  234. }
  235. return $piece;
  236. }
  237. function _db_build_field_sql($field) {
  238. if(!empty($field['length'])) {
  239. $length = "({$field['length']})";
  240. } else {
  241. $length = '';
  242. }
  243. if (strpos(strtolower($field['type']), 'int') !== false || in_array(strtolower($field['type']) , array('decimal', 'float', 'dobule'))) {
  244. $signed = empty($field['signed']) ? ' unsigned' : '';
  245. } else {
  246. $signed = '';
  247. }
  248. if(empty($field['zerofill'])) {
  249. $zerofill = '';
  250. } else {
  251. $zerofill = ' zerofill';
  252. }
  253. if(empty($field['null'])) {
  254. $null = ' NOT NULL';
  255. } else {
  256. $null = '';
  257. }
  258. if(isset($field['default'])) {
  259. $default = " DEFAULT '" . $field['default'] . "'";
  260. } else {
  261. $default = '';
  262. }
  263. if($field['increment']) {
  264. $increment = ' AUTO_INCREMENT';
  265. } else {
  266. $increment = '';
  267. }
  268. return "{$field['type']}{$length}{$signed}{$zerofill}{$null}{$default}{$increment}";
  269. }
  270. function db_table_schemas($table) {
  271. $dump = "DROP TABLE IF EXISTS {$table};\n";
  272. $sql = "SHOW CREATE TABLE {$table}";
  273. $row = pdo_fetch($sql);
  274. $dump .= $row['Create Table'];
  275. $dump .= ";\n\n";
  276. return $dump;
  277. }
  278. function db_table_insert_sql($tablename, $start, $size) {
  279. $data = '';
  280. $tmp = '';
  281. $sql = "SELECT * FROM {$tablename} LIMIT {$start}, {$size}";
  282. $result = pdo_fetchall($sql);
  283. if (!empty($result)) {
  284. foreach($result as $row) {
  285. $tmp .= '(';
  286. foreach($row as $k => $v) {
  287. $value = str_replace(array('\\', "\0", "\n", "\r", "'", '"', "\x1a"), array('\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z'), $v);
  288. $tmp .= "'" . $value . "',";
  289. }
  290. $tmp = rtrim($tmp, ',');
  291. $tmp .= "),\n";
  292. }
  293. $tmp = rtrim($tmp, ",\n");
  294. $data .= "INSERT INTO {$tablename} VALUES \n{$tmp};\n";
  295. $datas = array (
  296. 'data' => $data,
  297. 'result' => $result
  298. );
  299. return $datas;
  300. } else {
  301. return false ;
  302. }
  303. }