db.func.php 10 KB

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