| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469 |
- <?php
- class DB_Util {
- /**
- * Compare db structures
- */
- function compare_db($db1, $db2) {
-
- }
- function action_drop_table_to_sql($table_name) {
- $sql = "DROP `" . $table_name . "` ";
- return $sql;
- }
- /**
- * @param $field_params array('type'=>'' [, 'default'=>'', 'not null'=>bool, 'extra'=>''])
- */
- function action_modify_column_to_sql($table_name, $field_name, $field_params) {
- $sql = "ALTER TABLE `" . $table_name . "` MODIFY `" . $field_name . "` ";
- $sql .= $field_params['type'];
- if (!empty($field_params['not null']) && $field_params['not null'] == true) {
- $sql .= " NOT ";
- }
- $sql .= " NULL ";
- if (!empty($field_params['default'])) {
- $sql .= " " . $field_params['default'];
- }
- if (!empty($field_params['extra'])) {
- $sql .= " " . $field_params['extra'];
- }
- return $sql;
- }
- /**
- * @param $field_params array('type'=>'' [, 'default'=>'', 'not null'=>bool, 'extra'=>''])
- */
- function action_add_column_to_sql($table_name, $field_name, $field_params) {
- $sql = "ALTER TABLE `" . $table_name . "` ADD `" . $field_name . "` ";
- $sql .= $field_params['type'];
- if (!empty($field_params['not null']) && $field_params['not null'] == true) {
- $sql .= " NOT ";
- }
- $sql .= " NULL ";
- if (!empty($field_params['default'])) {
- $sql .= " " . $field_params['default'];
- }
- if (!empty($field_params['extra'])) {
- $sql .= " " . $field_params['extra'];
- }
- return $sql;
- }
- function action_drop_column_to_sql($table_name, $field_name) {
- $sql = "ALTER TABLE `" . $table_name . "` DROP `" . $field_name . "` ";
- return $sql;
- }
- /**
- * @param $columns array of column params
- * @param $keys array of key params
- */
- function action_create_table_to_sql($table_name, $columns, $keys) {
- $sql = "DROP `" . $table_name . "` ";
- return $sql;
- }
- function action_add_key_to_sql($table_name, $key_name, $key_params) {
- $sql = "ALTER TABLE `" . $table_name . "` ADD " . $key_params['type'];
- if ($key_params['type'] != 'PRIMARY KEY') $sql .= " " . $key_name;
- $sql .= " (" . implode(", ", $key_params['columns']) . ")";
- return $sql;
- }
- function action_drop_key_to_sql($table_name, $key_name) {
- $sql = "ALTER TABLE `" . $table_name . "` DROP INDEX " . $key_name . " ";
- return $sql;
- }
- /**
- * @returns array(0=>[sql], 1=>[sql]) - array of sql for db1 and db2
- */
- function compare_db_table_to_sql($table_name, &$cmp) {
- $sqls = array();
- if (!empty($cmp['columns'])) {
- foreach ($cmp['columns'] as $k_field => $v_cmp) {
- if (count($v_cmp) == 2) {
- $sqls[0][$k_field] = self::action_modify_column_to_sql($table_name, $k_field, $v_cmp[1]);
- $sqls[1][$k_field] = self::action_modify_column_to_sql($table_name, $k_field, $v_cmp[0]);
- } else if (count($v_cmp) == 1) {
- if (array_key_exists(0, $v_cmp)) {
- $sqls[0][$k_field] = self::action_drop_column_to_sql($table_name, $k_field);
- $sqls[1][$k_field] = self::action_add_column_to_sql($table_name, $k_field, $v_cmp[0]);
- } else {
- $sqls[0][$k_field] = self::action_add_column_to_sql($table_name, $k_field, $v_cmp[1]);
- $sqls[1][$k_field] = self::action_drop_column_to_sql($table_name, $k_field);
- }
- }
- }
- }
- if (!empty($cmp['keys'])) {
- foreach ($cmp['keys'] as $k_key => $v_cmp) {
- if (count($v_cmp) == 2) {
- $sqls[0][$k_key] = self::action_modify_key_to_sql($table_name, $k_key, $v_cmp[0]);
- $sqls[1][$k_key] = self::action_modify_key_to_sql($table_name, $k_key, $v_cmp[0]);
- } else if (count($v_cmp) == 1) {
- if (array_key_exists(0, $v_cmp)) {
- $sqls[0][$k_key] = self::action_drop_key_to_sql($table_name, $k_key);
- $sqls[1][$k_key] = self::action_add_key_to_sql($table_name, $k_key, $v_cmp[0]);
- } else {
- $sqls[0][$k_key] = self::action_add_key_to_sql($table_name, $k_key, $v_cmp[1]);
- $sqls[1][$k_key] = self::action_drop_key_to_sql($table_name, $k_key);
- }
- }
- }
- }
- return $sqls;
- }
- /**
- * Compare db structures.
- * @returns mixed
- * null - table not exists in both db
- * empty array - table are the same
- * array - columns, keys that differs
- * example:
- * array(
- * 'columns' => array(
- * 'ID' => array(
- * 0 => 1-st db column ID info or null if not exists
- * 1 => 2-nd db column ID info or null if not exists
- * )
- * )
- * )
- * array(
- * 'keys' => array(
- * 'KEY X' => array(
- * 0 => 1-st db KEY X info or null if not exists
- * 1 => 2-nd db KEY X info or null if not exists
- * )
- * )
- * )
- */
- function compare_db_table($db1, $db2, $table_name) {
- if (empty($table_name)) {
- return false;
- }
- $dbs = array($db1, $db2);
- $tbl_structs = array();
- // check if table exists in both db
- foreach ($dbs as $k_db_ind => $v_db) {
- $tbl_structs[$k_db_ind] = self::get_table_struct($v_db, $table_name);
- }
- $tbl_keys = array();
- foreach ($dbs as $k_db_ind => $v_db) {
- if (!empty($tbl_structs[$k_db_ind])) {
- $tbl_keys[$k_db_ind] = self::get_table_keys($v_db, $table_name);
- } else {
- $tbl_keys[$k_db_ind] = null;
- }
- }
- $cmp = array();
- if (empty($tbl_structs[0]) && empty($tbl_structs[1])) {
- return null;
- }
- $cmp['columns'] = array();
- $cmp['keys'] = array();
- foreach ($dbs as $k_ind => $v_db) {
- $k_2nd_ind = 1 - $k_ind;
- if (empty($tbl_structs[$k_ind])) {
- continue;
- }
- foreach ($tbl_structs[$k_ind] as $k_field => $v_field) {
- if (!array_key_exists($k_field, $tbl_structs[$k_2nd_ind])) {
- $cmp['columns'][$k_field][$k_ind] = $v_field;
- } else {
- $v_2nd_field = $tbl_structs[$k_2nd_ind][$k_field];
- $column_differ = false;
- if ($v_field['type'] != $v_2nd_field['type']) {
- $column_differ = true;
- }
- $field_add_keys = array('default', 'not null', 'extra');
- foreach ($field_add_keys as $field_key) {
- if (isset($v_field[$field_key]) && isset($v_2nd_field[$field_key])) {
- if ($v_field[$field_key] != $v_2nd_field[$field_key]) {
- $column_differ = true;
- }
- } else if (isset($v_field[$field_key]) != isset($v_2nd_field[$field_key])) {
- $column_differ = true;
- }
- }
- if ($column_differ) {
- $cmp['columns'][$k_field][$k_ind] = $v_field;
- $cmp['columns'][$k_field][$k_2nd_ind] = $v_2nd_field;
- }
- }
- }
- }
- // keys
- foreach ($dbs as $k_ind => $v_db) {
- $k_2nd_ind = 1 - $k_ind;
- if (empty($tbl_structs[$k_ind])) {
- continue;
- }
- if (empty($tbl_keys[$k_ind])) {
- continue;
- }
- foreach ($tbl_keys[$k_ind] as $k_key_name => $v_key) {
- if (!array_key_exists($k_key_name, $tbl_keys[$k_2nd_ind])) {
- $cmp['keys'][$k_key_name][$k_ind] = $v_key;
- } else {
- $v_2nd_key = $tbl_keys[$k_2nd_ind][$k_key_name];
- $column_differ = false;
- if ($v_key['type'] != $v_2nd_key['type']) {
- $column_differ = true;
- }
- $a_diff_1 = array_diff($v_key['columns'], $v_2nd_key['columns']);
- $a_diff_2 = array_diff($v_2nd_key['columns'], $v_key['columns']);
- if (!empty($a_diff_1) || !empty($a_diff_2)) {
- $column_differ = true;
- }
- if ($column_differ) {
- $cmp['keys'][$k_key_name][$k_ind] = $v_key;
- $cmp['keys'][$k_key_name][$k_2nd_ind] = $v_2nd_key;
- }
- }
- }
- }
- if (empty($cmp['columns'])) unset($cmp['columns']);
- if (empty($cmp['keys'])) unset($cmp['keys']);
- return $cmp;
- }
- /**
- * @returns array('field name' => array('type'=>'' [, 'default'=>'', 'not null'=>bool, 'extra'=>''] ))
- */
- function get_table_struct(&$db, $table_name) {
- $tbl_struct = array();
- $sql = sprintf("SHOW FIELDS FROM `%s`", $table_name);
- $res = $db->query($sql);
- if ($db->num_rows($res) == 0) {
- return null;
- }
- else {
- while ($record = $db->fetch_assoc($res)) {
- $tbl_struct[ $record['Field'] ] = array();
- $tbl_struct[ $record['Field'] ]['type'] = $record['Type'];
- if (!empty($record['Default'])) {
- if (substr($record['Default'], 0, strlen('CURRENT_TIMESTAMP')) == 'CURRENT_TIMESTAMP') {
- $tbl_struct[ $record['Field'] ]['default'] = $record['Default'];
- } else {
- $tbl_struct[ $record['Field'] ]['default'] = "'" . $record['Default'] . "'";
- }
- }
- if (@strcmp($record['Null'], 'YES') != 0) {
- $tbl_struct[ $record['Field'] ]['not null'] = true;
- }
- if (!empty($record['Extra'])) {
- $tbl_struct[ $record['Field'] ]['extra'] = $record['Extra'];
- }
- }
- }
- return $tbl_struct;
- }
- /**
- * @returns array('key name' => array('type'=>'', 'columns'=>array of column names))
- */
- function get_table_keys(&$db, $table_name) {
- $tbl_keys = array();
- $sql = sprintf("SHOW KEYS FROM `%s`", $table_name);
- $res = $db->query($sql);
- if ($db->num_rows($res) == 0) {
- return null;
- }
- while ($row = $db->fetch($res)) {
- $key_name = $row->Key_name;
- $key_type = '';
- if ($row->Key_name == 'PRIMARY') {
- if ($row->Index_type == 'BTREE') {
- $key_type = "PRIMARY KEY";
- }
- }
- else {
- if ($row->Non_unique == '0' && $row->Index_type == 'BTREE') {
- $key_type = "UNIQUE KEY";
- $key_name = "`" . $key_name . "`";
- }
- if ($row->Non_unique == '1' && $row->Index_type == 'BTREE') {
- $key_type = "KEY";
- $key_name = "`" . $key_name . "`";
- }
- if ($row->Non_unique == '1' && $row->Index_type == 'FULLTEXT') {
- $key_type = "FULLTEXT";
- $key_name = "`" . $key_name . "`";
- }
- }
- if (!$key_type) {
- // TODO: error - unknown type
- } else {
- if (empty($tbl_keys [$key_name])) {
- $tbl_keys [$key_name] = array('type'=>$key_type, 'columns'=>array());
- }
- $tbl_keys [$key_name]['columns'] []= $row->Column_name;
- }
- }
- return $tbl_keys;
- }
- function get_table_list(&$db, $table_prefix = '',$table_type=null) {
- $tbl_list = array();
- if($table_type) $sql="SHOW FULL TABLES WHERE TABLE_TYPE LIKE '".$table_type."'";
- else $sql="SHOW TABLES";
- $res = $db->query($sql);
- if ($db->num_rows($res) == 0) {
- return $tbl_list;
- }
- while ($record = $db->fetch_row($res)) {
- if ($table_prefix == '' || $table_prefix == '%' || $table_prefix == substr($record[0], 0, strlen($table_prefix))) {
- $tbl_list []= $record[0];
- }
- }
- return $tbl_list;
- }
- function get_db_structure_by_table_prefix( &$db, $table_prefix ) {
- $structure = '';
- $res = $db->query('SHOW TABLES');
- if ($db->num_rows($res) == 0) {
- return false;
- }
- while ($record = $db->fetch_row($res)) {
- if ($table_prefix == '' || $table_prefix == '%' || $table_prefix == substr($record[0], 0, strlen($table_prefix))) {
- $table_struct = self::get_table_structure($db, $record[0]);
- if ($table_struct === false) {
- // TODO: get_table_structure fail
- } else {
- $structure .= $table_struct;
- }
- }
- }
- return $structure;
- }
- function get_db_structure( &$db, $tables = array() ) {
- $structure = '';
- $res = $db->query('SHOW TABLES');
- if ($db->num_rows($res) == 0) {
- return false;
- }
- while ($record = $db->fetch_row($res)) {
- if (empty($tables) || in_array($record[0], $tables)) {
- $table_struct = self::get_table_structure($db, $record[0]);
- if ($table_struct === false) {
- // TODO: get_table_structure fail
- } else {
- $structure .= $table_struct;
- }
- }
- }
- return $structure;
- }
- function get_table_structure( &$db, $table ) {
- // Structure Header
- $structure = "-- \n";
- $structure .= "-- Table structure for table `{$table}` \n";
- $structure .= "-- \n\n";
- // Dump Structure
- //$structure .= 'DROP TABLE IF EXISTS `'.$table.'`;'."\n";
- // Create sql
- $structure .= "CREATE TABLE `".$table."` (\n";
- $sql_table_fields = array();
- $records = $db->query('SHOW FIELDS FROM `'.$table.'`');
- if ($db->num_rows($records) == 0) {
- return false;
- }
- while ($record = $db->fetch_assoc($records)) {
- $curr_sql_field = "";
- $curr_sql_field .= "`" . $record['Field'] . "` " . $record['Type'];
- if (!empty($record['Default'])) {
- if (substr($record['Default'], 0, strlen('CURRENT_TIMESTAMP')) == 'CURRENT_TIMESTAMP') {
- $curr_sql_field .= " DEFAULT " . $record['Default'];
- } else {
- $curr_sql_field .= " DEFAULT '" . $record['Default'] . "'";
- }
- }
- if (@strcmp($record['Null'], 'YES') != 0) {
- $curr_sql_field .= " NOT NULL";
- }
- if (!empty($record['Extra'])) {
- $curr_sql_field .= " " . $record['Extra'];
- }
- $sql_table_fields []= $curr_sql_field;
- }
- $structure .= (!empty($sql_table_fields))? implode(",\n", $sql_table_fields) : "";
- //$structure = @ereg_replace(",\n$", null, $structure);
- // Save all Column Indexes
- $table_keys = self::get_sql_keys_table($db, $table);
- if ($table_keys === false) {
- // TODO: get_sql_keys_table fail
- } else {
- $structure .= ",\n" . $table_keys;
- }
- $structure .= "\n)";
- //Save table engine
- $records = $db->query("SHOW TABLE STATUS LIKE '".$table."'");
- if ($record = $db->fetch_assoc($records)) {
- if (!empty($record['Engine'])) {
- $structure .= ' ENGINE='.$record['Engine'];
- }
- if (!empty($record['Auto_increment'])) {
- $structure .= ' AUTO_INCREMENT='.$record['Auto_increment'];
- }
- }
- $structure .= ";\n\n-- --------------------------------------------------------\n\n";
- return $structure;
- }
- function get_sql_keys_table( &$db, $table ) {
- $ret_keys = array();
- $primary = "";
- $unique = array();
- $index = array();
- $fulltext = array();
- $res = $db->query("SHOW KEYS FROM `" . $table . "`");
- if ($db->num_rows($res) == 0) {
- return false;
- }
- while ($row = $db->fetch($res)) {
- if ($row->Key_name == 'PRIMARY') {
- if ($row->Index_type == 'BTREE') {
- $ret_keys ["PRIMARY KEY"] []= "`" . $row->Column_name . "`";
- }
- }
- else {
- if ($row->Non_unique == '0' && $row->Index_type == 'BTREE') {
- $ret_keys ["UNIQUE KEY `" . $row->Key_name . "`"] []= "`" . $row->Column_name . "`";
- }
- if ($row->Non_unique == '1' && $row->Index_type == 'BTREE') {
- $ret_keys ["KEY `" . $row->Key_name . "`"] []= "`" . $row->Column_name . "`";
- }
- if ($row->Non_unique == '1' && $row->Index_type == 'FULLTEXT') {
- $ret_keys ["FULLTEXT `" . $row->Key_name . "`"] []= "`" . $row->Column_name . "`";
- }
- }
- }
- $out_keys = array();
- if (!empty($ret_keys)) {
- foreach ($ret_keys as $key => $val) {
- $out_keys []= $key . " (" . implode(", ", $val) . ")";
- }
- }
- $out_keys = (!empty($out_keys))? implode(",\n", $out_keys) : '';
- return $out_keys;
- }
- }
|