bug#3212720 Show error message on error.
[phpmyadmin/ayax.git] / libraries / server_synchronize.lib.php
blobc7d81211a8dc4f0b265e9940c05d368b1cc81aab
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 /**
5 * PMA_getMatchingTables places matching tables in source
6 * and target databases in $matching_tables array whereas
7 * $uncommon_source_tables array gets the tables present in
8 * source database but are absent from target database.
9 * Criterion for matching tables is just comparing their names.
11 * @param $trg_tables array of target database table names,
12 * @param $src_tables array of source database table names,
14 * @param &$matching_tables empty array passed by reference to save names of matching tables,
15 * @param &$uncommon_source_tables empty array passed by reference to save names of tables present in
16 * source database but absent from target database
19 function PMA_getMatchingTables($trg_tables, $src_tables, &$matching_tables, &$uncommon_source_tables)
21 for($k=0; $k< sizeof($src_tables); $k++) {
22 $present_in_target = false;
23 for($l=0; $l < sizeof($trg_tables); $l++) {
24 if ($src_tables[$k] === $trg_tables[$l]) {
25 $present_in_target = true;
26 $matching_tables[] = $src_tables[$k];
29 if ($present_in_target === false) {
30 $uncommon_source_tables[] = $src_tables[$k];
35 /**
36 * PMA_getNonMatchingTargetTables() places tables present
37 * in target database but are absent from source database
39 * @param $trg_tables array of target database table names,
41 * @param $matching_tables $matching tables array containing names of matching tables,
42 * @param &$uncommon_target_tables empty array passed by reference to save names of tables presnet in
43 * target database but absent from source database
46 function PMA_getNonMatchingTargetTables($trg_tables, $matching_tables, &$uncommon_target_tables)
48 for($c=0; $c<sizeof($trg_tables) ;$c++) {
49 $match = false;
50 for($d=0; $d < sizeof($matching_tables); $d++)
52 if ($trg_tables[$c] === $matching_tables[$d]) {
53 $match=true;
56 if ($match === false) {
57 $uncommon_target_tables[] = $trg_tables[$c];
62 /**
63 * PMA_dataDiffInTables() finds the difference in source and target matching tables by
64 * first comparing source table's primary key entries with target table enteries.
65 * It gets the field names for the matching table also for comparisons.
66 * If the entry is found in target table also then it is checked for the remaining
67 * field values also, in order to check whether update is required or not.
68 * If update is required, it is placed in $update_array
69 * Otherwise that entry is placed in the $insert_array.
71 * @uses PMA_DBI_get_fields()
72 * @uses PMA_DBI_get_column_values()
73 * @uses PMA_DBI_fetch_result()
75 * @param $src_db name of source database
76 * @param $trg_db name of target database
77 * @param $src_link connection established with source server
78 * @param $trg_link connection established with target server
79 * @param $index Index of a table from $matching_table array
81 * @param $update_array A three dimensional array passed by reference to
82 * contain updates required for each matching table
83 * @param $insert_array A three dimensional array passed by reference to
84 * contain inserts required for each matching table
85 * @param $fields_num A two dimensional array passed by reference to
86 * contain number of fields for each matching table
87 * @param $matching_table array containing matching table names
89 * @param $matching_tables_fields A two dimensional array passed by reference to contain names of fields for each matching table
91 * @param $matching_tables_keys A two dimensional array passed by reference to contain names of keys for each matching table
92 */
93 function PMA_dataDiffInTables($src_db, $trg_db, $src_link, $trg_link, &$matching_table, &$matching_tables_fields,
94 &$update_array, &$insert_array, &$delete_array, &$fields_num, $matching_table_index, &$matching_tables_keys)
96 if (isset($matching_table[$matching_table_index])) {
97 $fld = array();
98 $fld_results = PMA_DBI_get_fields($src_db, $matching_table[$matching_table_index], $src_link);
99 $is_key = array();
100 if (isset($fld_results)) {
101 foreach ($fld_results as $each_field) {
102 $field_name = $each_field['Field'];
103 if ($each_field['Key'] == 'PRI') {
104 $is_key[] = $field_name;
106 $fld[] = $field_name;
109 $matching_tables_fields[$matching_table_index] = $fld;
110 $fields_num[$matching_table_index] = sizeof($fld);
111 $matching_tables_keys[$matching_table_index] = $is_key;
113 $source_result_set = PMA_DBI_get_column_values($src_db, $matching_table[$matching_table_index], $is_key, $src_link);
114 $source_size = sizeof($source_result_set);
116 $trg_fld_results = PMA_DBI_get_fields($trg_db, $matching_table[$matching_table_index], $trg_link);
117 $all_keys_match = true;
118 $trg_keys = array();
120 if (isset($trg_fld_results)) {
121 foreach ($trg_fld_results as $each_field) {
122 if ($each_field['Key'] == 'PRI') {
123 $trg_keys[] = $each_field['Field'];
124 if (! (in_array($each_field['Field'], $is_key))) {
125 $all_keys_match = false;
130 $update_row = 0;
131 $insert_row = 0;
132 $update_field = 0;
133 $insert_field = 0;
134 $starting_index = 0;
136 for ($j = 0; $j < $source_size; $j++) {
137 $starting_index = 0;
138 $update_field = 0;
140 if (isset($source_result_set[$j]) && ($all_keys_match)) {
142 // Query the target server to see which rows already exist
143 $trg_select_query = "SELECT * FROM " . PMA_backquote($trg_db) . "."
144 . PMA_backquote($matching_table[$matching_table_index]) . " WHERE ";
146 if (sizeof($is_key) == 1) {
147 $trg_select_query .= $is_key[0]. "='" . $source_result_set[$j] . "'";
148 } elseif (sizeof($is_key) > 1){
149 for ($k=0; $k < sizeof($is_key); $k++) {
150 $trg_select_query .= $is_key[$k] . "='" . $source_result_set[$j][$is_key[$k]] . "'";
151 if ($k < (sizeof($is_key)-1)){
152 $trg_select_query .= " AND ";
157 $target_result_set = PMA_DBI_fetch_result($trg_select_query, null, null, $trg_link);
158 if ($target_result_set) {
160 // Fetch the row from the source server to do a comparison
161 $src_select_query = "SELECT * FROM " . PMA_backquote($src_db) . "."
162 . PMA_backquote($matching_table[$matching_table_index]) . " WHERE ";
164 if (sizeof($is_key) == 1) {
165 $src_select_query .= $is_key[0] . "='" . $source_result_set[$j] . "'";
166 } else if(sizeof($is_key) > 1){
167 for ($k=0; $k< sizeof($is_key); $k++) {
168 $src_select_query .= $is_key[$k] . "='" . $source_result_set[$j][$is_key[$k]] . "'";
169 if ($k < (sizeof($is_key) - 1)){
170 $src_select_query .= " AND ";
175 $src_result_set = PMA_DBI_fetch_result($src_select_query, null, null, $src_link);
178 * Comparing each corresponding field of the source and target matching rows.
179 * Placing the primary key, value of primary key, field to be updated, and the
180 * new value of field to be updated in each row of the update array.
182 for ($m = 0; ($m < $fields_num[$matching_table_index]) && ($starting_index == 0) ; $m++) {
183 if (isset($src_result_set[0][$fld[$m]])) {
184 if (isset($target_result_set[0][$fld[$m]])) {
185 if (($src_result_set[0][$fld[$m]] != $target_result_set[0][$fld[$m]]) && (! (in_array($fld[$m], $is_key)))) {
186 if (sizeof($is_key) == 1) {
187 if ($source_result_set[$j]) {
188 $update_array[$matching_table_index][$update_row][$is_key[0]] = $source_result_set[$j];
190 } elseif (sizeof($is_key) > 1) {
191 for ($n=0; $n < sizeof($is_key); $n++) {
192 if (isset($src_result_set[0][$is_key[$n]])) {
193 $update_array[$matching_table_index][$update_row][$is_key[$n]] = $src_result_set[0][$is_key[$n]];
198 $update_array[$matching_table_index][$update_row][$update_field] = $fld[$m];
200 $update_field++;
201 if (isset($src_result_set[0][$fld[$m]])) {
202 $update_array[$matching_table_index][$update_row][$update_field] = $src_result_set[0][$fld[$m]];
203 $update_field++;
205 $starting_index = $m;
206 $update_row++;
208 } else {
209 if (sizeof($is_key) == 1) {
210 if ($source_result_set[$j]) {
211 $update_array[$matching_table_index][$update_row][$is_key[0]] = $source_result_set[$j];
214 } elseif (sizeof($is_key) > 1) {
215 for ($n = 0; $n < sizeof($is_key); $n++) {
216 if (isset($src_result_set[0][$is_key[$n]])) {
217 $update_array[$matching_table_index][$update_row][$is_key[$n]] = $src_result_set[0][$is_key[$n]];
222 $update_array[$matching_table_index][$update_row][$update_field] = $fld[$m];
224 $update_field++;
225 if (isset($src_result_set[0][$fld[$m]])) {
226 $update_array[$matching_table_index][$update_row][$update_field] = $src_result_set[0][$fld[$m]];
227 $update_field++;
229 $starting_index = $m;
230 $update_row++;
234 for ($m = $starting_index + 1; $m < $fields_num[$matching_table_index] ; $m++)
236 if (isset($src_result_set[0][$fld[$m]])) {
237 if (isset($target_result_set[0][$fld[$m]])) {
238 if (($src_result_set[0][$fld[$m]] != $target_result_set[0][$fld[$m]]) && (!(in_array($fld[$m], $is_key)))) {
239 $update_row--;
240 $update_array[$matching_table_index][$update_row][$update_field] = $fld[$m];
241 $update_field++;
242 if ($src_result_set[0][$fld[$m]]) {
243 $update_array[$matching_table_index][$update_row][$update_field] = $src_result_set[0][$fld[$m]];
244 $update_field++;
246 $update_row++;
248 } else {
249 $update_row--;
250 $update_array[$matching_table_index][$update_row][$update_field] = $fld[$m];
251 $update_field++;
252 if ($src_result_set[0][$fld[$m]]) {
253 $update_array[$matching_table_index][$update_row][$update_field] = $src_result_set[0][$fld[$m]];
254 $update_field++;
256 $update_row++;
260 } else {
262 * Placing the primary key, and the value of primary key of the row that is to be inserted in the target table
264 if (sizeof($is_key) == 1) {
265 if (isset($source_result_set[$j])) {
266 $insert_array[$matching_table_index][$insert_row][$is_key[0]] = $source_result_set[$j];
268 } elseif (sizeof($is_key) > 1) {
269 for($l = 0; $l < sizeof($is_key); $l++) {
270 if (isset($source_result_set[$j][$matching_tables_fields[$matching_table_index][$l]])) {
271 $insert_array[$matching_table_index][$insert_row][$is_key[$l]] = $source_result_set[$j][$matching_tables_fields[$matching_table_index][$l]];
275 $insert_row++;
277 } else {
279 * Placing the primary key, and the value of primary key of the row that is to be inserted in the target table
280 * This condition is met when there is an additional column in the source table
282 if (sizeof($is_key) == 1) {
283 if (isset($source_result_set[$j])) {
284 $insert_array[$matching_table_index][$insert_row][$is_key[0]] = $source_result_set[$j];
286 } elseif (sizeof($is_key) > 1) {
287 for ($l = 0; $l < sizeof($is_key); $l++) {
288 if (isset($source_result_set[$j][$matching_tables_fields[$matching_table_index][$l]])) {
289 $insert_array[$matching_table_index][$insert_row][$is_key[$l]] = $source_result_set[$j][$matching_tables_fields[$matching_table_index][$l]];
293 $insert_row++;
295 } // for loop ends
299 * PMA_findDeleteRowsFromTargetTables finds the rows which are to be deleted from target table.
300 * @uses sizeof()
301 * @uses PMA_DBI_get_column_values()
302 * @uses in_array()
304 * @param $delete_array array containing rows that are to be deleted
305 * @param $matching_table array containing matching table names
306 * @param $matching_table_index index of a table from $matching_table array
307 * @param $trg_keys array of target table keys
308 * @param $src_keys array of source table keys
309 * @param $trg_db name of target database
310 * @param $trg_link connection established with target server
311 * @param $src_db name of source database
312 * @param $src_link connection established with source server
315 function PMA_findDeleteRowsFromTargetTables(&$delete_array, $matching_table, $matching_table_index, $trg_keys, $src_keys, $trg_db, $trg_link,$src_db, $src_link)
317 if (isset($trg_keys[$matching_table_index])) {
318 $target_key_values = PMA_DBI_get_column_values($trg_db, $matching_table[$matching_table_index], $trg_keys[$matching_table_index], $trg_link);
319 $target_row_size = sizeof($target_key_values);
321 if (isset($src_keys[$matching_table_index])) {
322 $source_key_values = PMA_DBI_get_column_values($src_db, $matching_table[$matching_table_index], $src_keys[$matching_table_index], $src_link);
323 $source_size = sizeof($source_key_values);
325 $all_keys_match = 1;
326 for ($a = 0; $a < sizeof($trg_keys[$matching_table_index]); $a++) {
327 if (isset($trg_keys[$matching_table_index][$a])) {
328 if (! (in_array($trg_keys[$matching_table_index][$a], $src_keys[$matching_table_index]))) {
329 $all_keys_match = 0;
333 if (! ($all_keys_match)) {
334 if (isset($target_key_values)) {
335 $delete_array[$matching_table_index] = $target_key_values;
338 if (isset($trg_keys[$matching_table_index])) {
339 if ((sizeof($trg_keys[$matching_table_index]) == 1) && $all_keys_match) {
340 $row = 0;
341 if (isset($target_key_values)) {
342 for ($i = 0; $i < sizeof($target_key_values); $i++) {
343 if (! (in_array($target_key_values[$i], $source_key_values))) {
344 $delete_array[$matching_table_index][$row] = $target_key_values[$i];
345 $row++;
349 } elseif ((sizeof($trg_keys[$matching_table_index]) > 1) && $all_keys_match) {
350 $row = 0;
351 if (isset($target_key_values)) {
352 for ($i = 0; $i < sizeof($target_key_values); $i++) {
353 $is_present = false;
354 for ($j = 0; $j < sizeof($source_key_values) && ($is_present == false) ; $j++) {
355 $check = true;
356 for ($k = 0; $k < sizeof($trg_keys[$matching_table_index]); $k++) {
357 if ($target_key_values[$i][$trg_keys[$matching_table_index][$k]] != $source_key_values[$j][$trg_keys[$matching_table_index][$k]]) {
358 $check = false;
361 if ($check) {
362 $is_present = true;
365 if (! ($is_present)) {
366 for ($l = 0; $l < sizeof($trg_keys[$matching_table_index]); $l++) {
367 $delete_array[$matching_table_index][$row][$trg_keys[$matching_table_index][$l]] = $target_key_values[$i][$trg_keys[$matching_table_index][$l]];
369 $row++;
378 * PMA_dataDiffInUncommonTables() finds the data difference in $source_tables_uncommon
379 * @uses PMA_DBI_fetch_result()
381 * @param $source_tables_uncommon array of table names; containing table names that are in source db and not in target db
382 * @param $src_db name of source database
383 * @param $src_link connection established with source server
384 * @param $index index of a table from $matching_table array
385 * @param $row_count number of rows
388 function PMA_dataDiffInUncommonTables($source_tables_uncommon, $src_db, $src_link, $index, &$row_count)
390 $query = "SELECT COUNT(*) FROM " . PMA_backquote($src_db) . "." . PMA_backquote($source_tables_uncommon[$index]);
391 $rows = PMA_DBI_fetch_result($query, null, null, $src_link);
392 $row_count[$index] = $rows[0];
396 * PMA_updateTargetTables() sets the updated field values to target table rows using $update_array[$matching_table_index]
398 * @uses PMA_DBI_fetch_result()
399 * @uses PMA_backquote()
401 * @param $table Array containing matching tables' names
402 * @param $update_array A three dimensional array containing field
403 * value updates required for each matching table
404 * @param $src_db Name of source database
405 * @param $trg_db Name of target database
406 * @param $trg_link Connection established with target server
407 * @param $matching_table_index index of matching table in matching_table_array
408 * @param $display true/false value
411 function PMA_updateTargetTables($table, $update_array, $src_db, $trg_db, $trg_link, $matching_table_index, $matching_table_keys, $display)
413 if (isset($update_array[$matching_table_index])) {
414 if (sizeof($update_array[$matching_table_index])) {
416 for ($update_row = 0; $update_row < sizeof($update_array[$matching_table_index]); $update_row++) {
418 if (isset($update_array[$matching_table_index][$update_row])) {
419 $update_fields_num = sizeof($update_array[$matching_table_index][$update_row])-sizeof($matching_table_keys[$matching_table_index]);
420 if ($update_fields_num > 0) {
421 $query = "UPDATE " . PMA_backquote($trg_db) . "." .PMA_backquote($table[$matching_table_index]) . " SET ";
423 for ($update_field = 0; $update_field < $update_fields_num; $update_field = $update_field+2) {
424 if (isset($update_array[$matching_table_index][$update_row][$update_field]) && isset($update_array[$matching_table_index][$update_row][$update_field+1])) {
425 $query .= $update_array[$matching_table_index][$update_row][$update_field] . "='" . $update_array[$matching_table_index][$update_row][$update_field+1] . "'";
427 if ($update_field < ($update_fields_num - 2)) {
428 $query .= ", ";
431 $query .= " WHERE ";
432 if (isset($matching_table_keys[$matching_table_index])) {
433 for ($key = 0; $key < sizeof($matching_table_keys[$matching_table_index]); $key++)
435 if (isset($matching_table_keys[$matching_table_index][$key])) {
437 $query .= $matching_table_keys[$matching_table_index][$key] . "='" . $update_array[$matching_table_index][$update_row][$matching_table_keys[$matching_table_index][$key]] . "'";
439 if ($key < (sizeof($matching_table_keys[$matching_table_index]) - 1)) {
440 $query .= " AND ";
444 if ($display == true) {
445 echo "<p>" . $query . "</p>";
447 PMA_DBI_try_query($query, $trg_link, 0);
455 * PMA_insertIntoTargetTable() inserts missing rows in the target table using $array_insert[$matching_table_index]
457 * @uses PMA_DBI_fetch_result()
458 * @uses PMA_backquote()
461 * @param $matching_table array containing matching table names
462 * @param $src_db name of source database
463 * @param $trg_db name of target database
464 * @param $src_link connection established with source server
465 * @param $trg_link connection established with target server
466 * @param $table_fields array containing field names of a table
467 * @param $array_insert
468 * @param $matching_table_index index of matching table in matching_table_array
469 * @param $matching_tables_keys array containing field names that are keys in the matching table
470 * @param $source_columns array containing source column information
471 * @param $add_column_array array containing column names that are to be added in target table
472 * @param $criteria array containing criterias like type, null, collation, default etc
473 * @param $target_tables_keys array containing field names that are keys in the target table
474 * @param $uncommon_tables array containing table names that are present in source db but not in targt db
475 * @param $uncommon_tables_fields array containing field names of the uncommon tables
476 * @param $uncommon_cols column names that are present in target table and not in source table
477 * @param $alter_str_array array containing column names that are to be altered
478 * @param $source_indexes column names on which indexes are made in source table
479 * @param $target_indexes column names on which indexes are made in target table
480 * @param $add_indexes_array array containing column names on which index is to be added in target table
481 * @param $alter_indexes_array array containing column names whose indexes are to be altered. Only index name and uniqueness of an index can be changed
482 * @param $delete_array array containing rows that are to be deleted
483 * @param $update_array array containing rows that are to be updated in target
484 * @param $display true/false value
487 function PMA_insertIntoTargetTable($matching_table, $src_db, $trg_db, $src_link, $trg_link, $table_fields, &$array_insert, $matching_table_index,
488 $matching_tables_keys, $source_columns, &$add_column_array, $criteria, $target_tables_keys, $uncommon_tables, &$uncommon_tables_fields,$uncommon_cols,
489 &$alter_str_array,&$source_indexes, &$target_indexes, &$add_indexes_array, &$alter_indexes_array, &$delete_array, &$update_array, $display)
491 if(isset($array_insert[$matching_table_index])) {
492 if (sizeof($array_insert[$matching_table_index])) {
493 for ($insert_row = 0; $insert_row< sizeof($array_insert[$matching_table_index]); $insert_row++) {
494 if (isset($array_insert[$matching_table_index][$insert_row][$matching_tables_keys[$matching_table_index][0]])) {
496 $select_query = "SELECT * FROM " . PMA_backquote($src_db) . "." . PMA_backquote($matching_table[$matching_table_index]) . " WHERE ";
497 for ($i = 0; $i < sizeof($matching_tables_keys[$matching_table_index]); $i++) {
498 $select_query .= $matching_tables_keys[$matching_table_index][$i] . "='";
499 $select_query .= $array_insert[$matching_table_index][$insert_row][$matching_tables_keys[$matching_table_index][$i]] . "'" ;
501 if ($i < (sizeof($matching_tables_keys[$matching_table_index]) - 1)) {
502 $select_query.= " AND ";
505 $select_query .= "; ";
506 $result = PMA_DBI_fetch_result ($select_query, null, null, $src_link);
507 $insert_query = "INSERT INTO " . PMA_backquote($trg_db) . "." . PMA_backquote($matching_table[$matching_table_index]) ." (";
509 for ($field_index = 0; $field_index < sizeof($table_fields[$matching_table_index]); $field_index++)
511 $insert_query .= $table_fields[$matching_table_index][$field_index];
513 $is_fk_query = "SELECT * FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = '" . $trg_db ."'
514 AND TABLE_NAME = '" . $matching_table[$matching_table_index]. "'AND COLUMN_NAME = '" .
515 $table_fields[$matching_table_index][$field_index] . "' AND TABLE_NAME <> REFERENCED_TABLE_NAME;" ;
517 $is_fk_result = PMA_DBI_fetch_result($is_fk_query, null, null, $trg_link);
518 if (sizeof($is_fk_result) > 0) {
519 for ($j = 0; $j < sizeof($is_fk_result); $j++)
521 $table_index = array_keys($matching_table, $is_fk_result[$j]['REFERENCED_TABLE_NAME']);
523 if (isset($alter_str_array[$table_index[0]])) {
524 PMA_alterTargetTableStructure($trg_db, $trg_link, $matching_tables, $source_columns, $alter_str_array, $matching_tables_fields,
525 $criteria, $matching_tables_keys, $target_tables_keys, $table_index[0], $display);
526 unset($alter_str_array[$table_index[0]]);
528 if (isset($uncommon_columns[$table_index[0]])) {
529 PMA_removeColumnsFromTargetTable($trg_db, $trg_link, $matching_tables, $uncommon_columns, $table_index[0], $display);
530 unset($uncommon_columns[$table_index[0]]);
532 if (isset($add_column_array[$table_index[0]])) {
533 PMA_findDeleteRowsFromTargetTables($delete_array, $matching_tables, $table_index[0], $target_tables_keys, $matching_tables_keys,
534 $trg_db, $trg_link, $src_db, $src_link);
536 if (isset($delete_array[$table_index[0]])) {
537 PMA_deleteFromTargetTable($trg_db, $trg_link, $matching_tables, $table_index[0], $target_tables_keys, $delete_array, $display);
538 unset($delete_array[$table_index[0]]);
540 PMA_addColumnsInTargetTable($src_db, $trg_db, $src_link, $trg_link, $matching_tables, $source_columns, $add_column_array,
541 $matching_tables_fields, $criteria, $matching_tables_keys, $target_tables_keys, $uncommon_tables,$uncommon_tables_fields,
542 $table_index[0], $uncommon_cols, $display);
543 unset($add_column_array[$table_index[0]]);
545 if (isset($add_indexes_array[$table_index[0]]) || isset($remove_indexes_array[$table_index[0]])
546 || isset($alter_indexes_array[$table_index[0]])) {
547 PMA_applyIndexesDiff ($trg_db, $trg_link, $matching_tables, $source_indexes, $target_indexes, $add_indexes_array, $alter_indexes_array,
548 $remove_indexes_array, $table_index[0], $display);
550 unset($add_indexes_array[$table_index[0]]);
551 unset($alter_indexes_array[$table_index[0]]);
552 unset($remove_indexes_array[$table_index[0]]);
554 if (isset($update_array[$table_index[0]])) {
555 PMA_updateTargetTables($matching_tables, $update_array, $src_db, $trg_db, $trg_link, $table_index[0], $matching_table_keys,
556 $display);
557 unset($update_array[$table_index[0]]);
559 if (isset($array_insert[$table_index[0]])) {
560 PMA_insertIntoTargetTable($matching_table, $src_db, $trg_db, $src_link, $trg_link, $table_fields, $array_insert,
561 $table_index[0], $matching_tables_keys, $source_columns, $add_column_array, $criteria, $target_tables_keys, $uncommon_tables,
562 $uncommon_tables_fields, $uncommon_cols, $alter_str_array, $source_indexes, $target_indexes, $add_indexes_array,
563 $alter_indexes_array, $delete_array, $update_array, $display);
564 unset($array_insert[$table_index[0]]);
568 if ($field_index < sizeof($table_fields[$matching_table_index])-1) {
569 $insert_query .= ", ";
572 $insert_query .= ") VALUES(";
573 if (sizeof($table_fields[$matching_table_index]) == 1) {
574 $insert_query .= "'" . $result[0] . "'";
575 } else {
576 for ($field_index = 0; $field_index < sizeof($table_fields[$matching_table_index]); $field_index++) {
577 if (isset($result[0][$table_fields[$matching_table_index][$field_index]])) {
578 $insert_query .= "'" . $result[0][$table_fields[$matching_table_index][$field_index]] . "'";
579 } else {
580 $insert_query .= "'NULL'";
582 if ($field_index < (sizeof($table_fields[$matching_table_index])) - 1) {
583 $insert_query .= " ," ;
587 $insert_query .= ");";
588 if ($display == true) {
589 PMA_displayQuery($insert_query);
591 PMA_DBI_try_query($insert_query, $trg_link, 0);
598 * PMA_createTargetTables() Create the missing table $uncommon_table in target database
600 * @uses PMA_DBI_get_fields()
601 * @uses PMA_backquote()
602 * @uses PMA_DBI_fetch_result()
604 * @param $src_db name of source database
605 * @param $trg_db name of target database
606 * @param $trg_link connection established with target server
607 * @param $src_link connection established with source server
608 * @param $uncommon_table name of table present in source but not in target
609 * @param $table_index index of table in matching_table_array
610 * @param $uncommon_tables_fields field names of the uncommon table
611 * @param $display true/false value
613 function PMA_createTargetTables($src_db, $trg_db, $src_link, $trg_link, &$uncommon_tables, $table_index, &$uncommon_tables_fields, $display)
615 if (isset($uncommon_tables[$table_index])) {
616 $fields_result = PMA_DBI_get_fields($src_db, $uncommon_tables[$table_index], $src_link);
617 $fields = array();
618 foreach ($fields_result as $each_field) {
619 $field_name = $each_field['Field'];
620 $fields[] = $field_name;
622 $uncommon_tables_fields[$table_index] = $fields;
624 $Create_Query = PMA_DBI_fetch_value("SHOW CREATE TABLE " . PMA_backquote($src_db) . '.' . PMA_backquote($uncommon_tables[$table_index]), 0, 1, $src_link);
626 // Replace the src table name with a `dbname`.`tablename`
627 $Create_Table_Query = preg_replace('/' . PMA_backquote($uncommon_tables[$table_index]) . '/',
628 PMA_backquote($trg_db) . '.' .PMA_backquote($uncommon_tables[$table_index]),
629 $Create_Query,
630 $limit = 1
633 $is_fk_query = "SELECT * FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = '" . $src_db . "'
634 AND TABLE_NAME = '" . $uncommon_tables[$table_index] . "' AND TABLE_NAME <> REFERENCED_TABLE_NAME;" ;
636 $is_fk_result = PMA_DBI_fetch_result($is_fk_query, null, null, $src_link);
637 if (sizeof($is_fk_result) > 0) {
638 for ($j = 0; $j < sizeof($is_fk_result); $j++)
640 if (in_array($is_fk_result[$j]['REFERENCED_TABLE_NAME'], $uncommon_tables)) {
641 $table_index = array_keys($uncommon_tables, $is_fk_result[$j]['REFERENCED_TABLE_NAME']);
642 PMA_createTargetTables($src_db, $trg_db, $trg_link, $src_link, $uncommon_tables, $table_index[0], $uncommon_tables_fields, $display);
643 unset($uncommon_tables[$table_index[0]]);
647 if ($display == true) {
648 echo '<p>' . $Create_Table_Query . '</p>';
650 PMA_DBI_try_query($Create_Table_Query, $trg_link, 0);
654 * PMA_populateTargetTables() inserts data into uncommon tables after they have been created
655 * @uses PMA_DBI_fetch_result()
656 * @uses PMA_backquote()
657 * @uses sizeof()
658 * @uses PMA_DBI_try_query()
660 * @param $src_db name of source database
661 * @param $trg_db name of target database
662 * @param $src_link connection established with source server
663 * @param $trg_link connection established with target server
664 * @param $uncommon_tables array containing uncommon table names (table names that are present in source but not in target db)
665 * @param $table_index index of table in matching_table_array
666 * @param $uncommon_tables_fields field names of the uncommon table
667 * @param $display true/false value
669 * FIXME: This turns NULL values into '' (empty string)
671 function PMA_populateTargetTables($src_db, $trg_db, $src_link, $trg_link, $uncommon_tables, $table_index, $uncommon_tables_fields, $display)
673 $display = false; // todo: maybe display some of the queries if they are not too numerous
674 $unbuffered_result = PMA_DBI_try_query('SELECT * FROM ' . PMA_backquote($src_db) . '.' . PMA_backquote($uncommon_tables[$table_index]), $src_link, PMA_DBI_QUERY_UNBUFFERED);
675 if (false !== $unbuffered_result) {
676 $insert_query = 'INSERT INTO ' . PMA_backquote($trg_db) . '.' .PMA_backquote($uncommon_tables[$table_index]) . ' VALUES';
677 while ($one_row = PMA_DBI_fetch_row($unbuffered_result)) {
678 $insert_query .= '(';
679 $key_of_last_value = count($one_row) - 1;
680 foreach($one_row as $key => $value) {
681 $insert_query .= "'" . PMA_sqlAddslashes($value) . "'";
682 if ($key < $key_of_last_value) {
683 $insert_query .= ",";
686 $insert_query .= '),';
688 $insert_query = substr($insert_query, 0, -1);
689 $insert_query .= ';';
690 if ($display == true) {
691 PMA_displayQuery($insert_query);
693 PMA_DBI_try_query($insert_query, $trg_link, 0);
697 * PMA_deleteFromTargetTable() delete rows from target table
698 * @uses sizeof()
699 * @uses PMA_backquote()
700 * @uses PMA_DBI_try_query()
703 * @param $trg_db name of target database
704 * @param $trg_link connection established with target server
705 * @param $matching_tables array containing matching table names
706 * @param $table_index index of table in matching_table_array
707 * @param $target_table_keys primary key names of the target tables
708 * @param $delete array array containing the key values of rows that are to be deleted
709 * @param $display true/false value
711 function PMA_deleteFromTargetTable($trg_db, $trg_link, $matching_tables, $table_index, $target_tables_keys, $delete_array, $display)
713 for($i = 0; $i < sizeof($delete_array[$table_index]); $i++) {
714 if (isset($target_tables_keys[$table_index])) {
715 $delete_query = 'DELETE FROM ' . PMA_backquote($trg_db) . '.' .PMA_backquote($matching_tables[$table_index]) . ' WHERE ';
716 for($y = 0; $y < sizeof($target_tables_keys[$table_index]); $y++) {
717 $delete_query .= $target_tables_keys[$table_index][$y] . " = '";
719 if (sizeof($target_tables_keys[$table_index]) == 1) {
720 $delete_query .= $delete_array[$table_index][$i] . "'";
721 } elseif (sizeof($target_tables_keys[$table_index]) > 1) {
722 $delete_query .= $delete_array[$table_index][$i][$target_tables_keys[$table_index][$y]] . "'";
724 if ($y < (sizeof($target_tables_keys[$table_index]) - 1)) {
725 $delete_query .= ' AND ';
727 $pk_query = "SELECT * FROM information_schema.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_SCHEMA = '" . $trg_db . "'
728 AND REFERENCED_TABLE_NAME = '" . $matching_tables[$table_index]."' AND REFERENCED_COLUMN_NAME = '"
729 . $target_tables_keys[$table_index][$y] . "' AND TABLE_NAME <> REFERENCED_TABLE_NAME;";
731 $pk_query_result = PMA_DBI_fetch_result($pk_query, null, null, $trg_link);
732 $result_size = sizeof($pk_query_result);
734 if ($result_size > 0) {
735 for ($b = 0; $b < $result_size; $b++) {
736 $drop_pk_query = "DELETE FROM " . PMA_backquote($pk_query_result[$b]['TABLE_SCHEMA']) . "." . PMA_backquote($pk_query_result[$b]['TABLE_NAME']) . " WHERE " . $pk_query_result[$b]['COLUMN_NAME'] . " = " . $target_tables_keys[$table_index][$y] . ";";
737 PMA_DBI_try_query($drop_pk_query, $trg_link, 0);
742 if ($display == true) {
743 echo '<p>' . $delete_query . '</p>';
745 PMA_DBI_try_query($delete_query, $trg_link, 0);
749 * PMA_structureDiffInTables() Gets all the column information for source and target table.
750 * Compare columns on their names.
751 * If column exists in target then compare Type, Null, Collation, Key, Default and Comment for that column.
752 * If column does not exist in target table then it is placed in $add_column_array.
753 * If column exists in target table but criteria is different then it is palced in $alter_str_array.
754 * If column does not exist in source table but is present in target table then it is placed in $uncommon_columns.
755 * Keys for all the source tables that have a corresponding target table are placed in $matching_tables_keys.
756 * Keys for all the target tables that have a corresponding source table are placed in $target_tables_keys.
758 * @uses PMA_DBI_get_columns_full()
759 * @uses sizeof()
761 * @param $src_db name of source database
762 * @param $trg_db name of target database
763 * @param $src_link connection established with source server
764 * @param $trg_link connection established with target server
765 * @param $matching_tables array containing names of matching tables
766 * @param $source_columns array containing columns information of the source tables
767 * @param $target_columns array containing columns information of the target tables
768 * @param $alter_str_array three dimensional associative array first index being the matching table index, second index being column name for which target
769 * column have some criteria different and third index containing the criteria which is different.
770 * @param $add_column_array two dimensional associative array, first index of the array contain the matching table number and second index contain the
771 * column name which is to be added in the target table
772 * @param $uncommon_columns array containing the columns that are present in the target table but not in the source table
773 * @param $criteria array containing the criterias which are to be checked for field that is present in source table and target table
774 * @param $target_tables_keys array containing the field names which is key in the target table
775 * @param $matching_table_index integer number of the matching table
778 function PMA_structureDiffInTables($src_db, $trg_db, $src_link, $trg_link, $matching_tables, &$source_columns, &$target_columns, &$alter_str_array,
779 &$add_column_array, &$uncommon_columns, $criteria, &$target_tables_keys, $matching_table_index)
781 //Gets column information for source and target table
782 $source_columns[$matching_table_index] = PMA_DBI_get_columns_full($src_db, $matching_tables[$matching_table_index], null, $src_link);
783 $target_columns[$matching_table_index] = PMA_DBI_get_columns_full($trg_db, $matching_tables[$matching_table_index], null, $trg_link);
784 foreach ($source_columns[$matching_table_index] as $column_name => $each_column) {
785 if (isset($target_columns[$matching_table_index][$column_name]['Field'])) {
786 //If column exists in target table then matches criterias like type, null, collation, key, default, comment of the column
787 for ($i = 0; $i < sizeof($criteria); $i++) {
788 if ($source_columns[$matching_table_index][$column_name][$criteria[$i]] != $target_columns[$matching_table_index][$column_name][$criteria[$i]]) {
789 if (($criteria[$i] == 'Default') && ($source_columns[$matching_table_index][$column_name][$criteria[$i]] == '' )) {
790 $alter_str_array[$matching_table_index][$column_name][$criteria[$i]] = 'None';
791 } else {
792 if (! (($criteria[$i] == 'Key') && (($source_columns[$matching_table_index][$column_name][$criteria[$i]] == 'MUL')
793 || ($target_columns[$matching_table_index][$column_name][$criteria[$i]] == 'MUL')
794 || ($source_columns[$matching_table_index][$column_name][$criteria[$i]] == 'UNI')
795 || ($target_columns[$matching_table_index][$column_name][$criteria[$i]] == 'UNI')))) {
796 $alter_str_array[$matching_table_index][$column_name][$criteria[$i]] = $source_columns[$matching_table_index][$column_name][$criteria[$i]];
801 } else {
802 $add_column_array[$matching_table_index][$column_name]= $column_name;
805 //Finds column names that are present in target table but not in source table
806 foreach ($target_columns[$matching_table_index] as $fld_name => $each_column) {
807 if (! (isset($source_columns[$matching_table_index][$fld_name]['Field']))) {
808 $fields_uncommon[] = $fld_name;
810 if ($target_columns[$matching_table_index][$fld_name]['Key'] == 'PRI') {
811 $keys[] = $fld_name;
814 if (isset($fields_uncommon)) {
815 $uncommon_columns[$matching_table_index] = $fields_uncommon;
817 if (isset($keys)) {
818 $target_tables_keys[$matching_table_index] = $keys;
822 * PMA_addColumnsInTargetTable() adds column that are present in source table but not in target table
823 * @uses sizeof()
824 * @uses in_array()
825 * @uses array_keys()
826 * @uses PMA_checkForeignKeys()
827 * @uses PMA_createTargetTables()
828 * @uses PMA_DBI_try_query()
829 * @uses PMA_DBI_fetch_result()
831 * @param $src_db name of source database
832 * @param $trg_db name of target database
833 * @param $src_link connection established with source server
834 * @param $trg_link connection established with target server
835 * @param $matching_tables array containing names of matching tables
836 * @param $source_columns array containing columns information of the source tables
837 * @param $add_column_array array containing the names of the column(field) that are to be added in the target
838 * @param $matching_tables_fields
839 * @param $criteria array containing the criterias
840 * @param $matching_tables_keys array containing the field names which is key in the source table
841 * @param $target_tables_keys array containing the field names which is key in the target table
842 * @param $uncommon_tables array containing the table names that are present in source db and not in target db
843 * @param $uncommon_tables_fields array containing the names of the fields of the uncommon tables
844 * @param $table_counter integer number of the matching table
845 * @param $uncommon_cols
846 * @param $display true/false value
848 function PMA_addColumnsInTargetTable($src_db, $trg_db, $src_link, $trg_link, $matching_tables, $source_columns, &$add_column_array, $matching_tables_fields,
849 $criteria, $matching_tables_keys, $target_tables_keys, $uncommon_tables, &$uncommon_tables_fields, $table_counter, $uncommon_cols, $display)
851 for ($i = 0; $i < sizeof($matching_tables_fields[$table_counter]); $i++) {
852 if (isset($add_column_array[$table_counter][$matching_tables_fields[$table_counter][$i]])) {
853 $query = "ALTER TABLE " . PMA_backquote($trg_db) . '.' . PMA_backquote($matching_tables[$table_counter]). " ADD COLUMN " .
854 $add_column_array[$table_counter][$matching_tables_fields[$table_counter][$i]] . " " . $source_columns[$table_counter][$matching_tables_fields[$table_counter][$i]]['Type'];
856 if($source_columns[$table_counter][$matching_tables_fields[$table_counter][$i]]['Null'] == 'NO') {
857 $query .= ' Not Null ';
858 } elseif ($source_columns[$table_counter][$matching_tables_fields[$table_counter][$i]]['Null'] == 'YES') {
859 $query .= ' Null ';
861 if ($source_columns[$table_counter][$matching_tables_fields[$table_counter][$i]]['Collation'] != '') {
862 $query .= ' COLLATE ' . $source_columns[$table_counter][$matching_tables_fields[$table_counter][$i]]['Collation'];
864 if ($source_columns[$table_counter][$matching_tables_fields[$table_counter][$i]]['Default'] != '') {
865 $query .= " DEFAULT " . $source_columns[$table_counter][$matching_tables_fields[$table_counter][$i]]['Default'];
867 if ($source_columns[$table_counter][$matching_tables_fields[$table_counter][$i]]['Comment'] != '') {
868 $query .= " COMMENT " . $source_columns[$table_counter][$matching_tables_fields[$table_counter][$i]]['Comment'];
870 if ($source_columns[$table_counter][$matching_tables_fields[$table_counter][$i]]['Key'] == 'PRI' ) {
871 $trg_key_size = sizeof($target_tables_keys[$table_counter]);
872 if ($trg_key_size) {
873 $check = true;
874 for ($a = 0; ($a < $trg_key_size) && ($check); $a++) {
875 if (! (in_array($target_tables_keys[$table_counter], $uncommon_cols))) {
876 $check = false;
879 if (! $check) {
880 $query .= " ,DROP PRIMARY KEY " ;
883 $query .= " , ADD PRIMARY KEY (";
884 for ($t = 0; $t < sizeof($matching_tables_keys[$table_counter]); $t++) {
885 $query .= $matching_tables_keys[$table_counter][$t];
886 if ($t < (sizeof($matching_tables_keys[$table_counter]) - 1)) {
887 $query .= " , " ;
890 $query .= ")";
893 $query .= ";";
894 if ($display == true) {
895 echo '<p>' . $query . '</p>';
897 PMA_DBI_try_query($query, $trg_link, 0);
899 //Checks if column to be added is a foreign key or not
900 $is_fk_query = "SELECT * FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = '" . $trg_db . "' AND TABLE_NAME = '"
901 . $matching_tables[$table_counter] . "' AND COLUMN_NAME ='" . $add_column_array[$table_counter][$matching_tables_fields[$table_counter][$i]] .
902 "' AND TABLE_NAME <> REFERENCED_TABLE_NAME;";
904 $is_fk_result = PMA_DBI_fetch_result($is_fk_query, null, null, $src_link);
906 //If column is a foreign key then it is checked that referenced table exist in target db. If referenced table does not exist in target db then
907 //it is created first.
908 if (isset($is_fk_result)) {
909 if (in_array($is_fk_result[0]['REFERENCED_TABLE_NAME'], $uncommon_tables)) {
910 $table_index = array_keys($uncommon_tables, $is_fk_result[0]['REFERENCED_TABLE_NAME']);
911 PMA_checkForeignKeys($src_db, $src_link, $trg_db, $trg_link, $is_fk_result[0]['REFERENCED_TABLE_NAME'], $uncommon_tables, $uncommon_tables_fields);
912 PMA_createTargetTables($src_db, $trg_db, $trg_link, $src_link, $uncommon_tables, $table_index[0], $uncommon_tables_fields);
913 unset($uncommon_tables[$table_index[0]]);
915 $fk_query = "ALTER TABLE " . PMA_backquote($trg_db) . '.' . PMA_backquote($matching_tables[$table_counter]) .
916 "ADD CONSTRAINT FOREIGN KEY " . $add_column_array[$table_counter][$matching_tables_fields[$table_counter][$i]] . "
917 (" . $add_column_array[$table_counter][$matching_tables_fields[$table_counter][$i]] . ") REFERENCES " . PMA_backquote($trg_db) .
918 '.' . PMA_backquote($is_fk_result[0]['REFERENCED_TABLE_NAME']) . " (" . $is_fk_result[0]['REFERENCED_COLUMN_NAME'] . ");";
920 PMA_DBI_try_query($fk_query, $trg_link, null);
926 * PMA_checkForeignKeys() checks if the referenced table have foreign keys.
927 * @uses sizeof()
928 * @uses in_array()
929 * @uses array_keys()
930 * @uses PMA_checkForeignKeys()
931 * uses PMA_createTargetTables()
933 * @param $src_db name of source database
934 * @param $src_link connection established with source server
935 * @param $trg_db name of target database
936 * @param $trg_link connection established with target server
937 * @param $referenced_table table whose column is a foreign key in another table
938 * @param $uncommon_tables array containing names that are uncommon
939 * @param $uncommon_tables_fields field names of the uncommon table
940 * @param $display true/false value
942 function PMA_checkForeignKeys($src_db, $src_link, $trg_db, $trg_link ,$referenced_table, &$uncommon_tables, &$uncommon_tables_fields, $display)
944 $is_fk_query = "SELECT * FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = '" . $src_db . "'
945 AND TABLE_NAME = '" . $referenced_table . "' AND TABLE_NAME <> REFERENCED_TABLE_NAME;";
947 $is_fk_result = PMA_DBI_fetch_result($is_fk_query, null, null, $src_link);
948 if (sizeof($is_fk_result) > 0) {
949 for ($j = 0; $j < sizeof($is_fk_result); $j++) {
950 if (in_array($is_fk_result[$j]['REFERENCED_TABLE_NAME'], $uncommon_tables)) {
951 $table_index = array_keys($uncommon_tables, $is_fk_result[$j]['REFERENCED_TABLE_NAME']);
952 PMA_checkForeignKeys($src_db, $src_link, $trg_db, $trg_link, $is_fk_result[$j]['REFERENCED_TABLE_NAME'], $uncommon_tables,
953 $uncommon_tables_fields, $display);
954 PMA_createTargetTables($src_db, $trg_db, $trg_link, $src_link, $uncommon_tables, $table_index[0], $uncommon_tables_fields, $display);
955 unset($uncommon_tables[$table_index[0]]);
961 * PMA_alterTargetTableStructure() alters structure of the target table using $alter_str_array
962 * @uses sizeof()
963 * @uses PMA_DBI_fetch_result()
964 * @uses is_string()
965 * @uses is_numeric()
966 * @uses PMA_DBI_try_query()
969 * @param $trg_db name of target database
970 * @param $trg_link connection established with target server
971 * @param $matching_tables array containing names of matching tables
972 * @param $source_columns array containing columns information of the source table
973 * @param $alter_str_array array containing the column name and criteria which is to be altered for the targert table
974 * @param $matching_tables_fields array containing the name of the fields for the matching table
975 * @param $criteria array containing the criterias
976 * @param $matching_tables_keys array containing the field names which is key in the source table
977 * @param $target_tables_keys array containing the field names which is key in the target table
978 * @param $matching_table_index integer number of the matching table
979 * @param $display true/false value
981 function PMA_alterTargetTableStructure($trg_db, $trg_link, $matching_tables, &$source_columns, &$alter_str_array, $matching_tables_fields, $criteria,
982 &$matching_tables_keys, &$target_tables_keys, $matching_table_index, $display)
984 $check = true;
985 $sql_query = '';
986 $found = false;
988 //Checks if the criteria to be altered is primary key
989 for ($v = 0; $v < sizeof($matching_tables_fields[$matching_table_index]); $v++) {
990 if (isset($alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$v]]['Key'])) {
991 if ($alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$v]]['Key'] == 'PRI' ) {
992 $check = false;
996 $pri_query;
997 if (! $check) {
998 $pri_query = "ALTER TABLE " . PMA_backquote($trg_db) . '.' . PMA_backquote($matching_tables[$matching_table_index]);
999 if (sizeof($target_tables_keys[$matching_table_index]) > 0) {
1000 $pri_query .= " DROP PRIMARY KEY ," ;
1002 $pri_query .= " ADD PRIMARY KEY (";
1003 for ($z = 0; $z < sizeof($matching_tables_keys[$matching_table_index]); $z++) {
1004 $pri_query .= $matching_tables_keys[$matching_table_index][$z];
1005 if ($z < (sizeof($matching_tables_keys[$matching_table_index]) - 1)) {
1006 $pri_query .= " , " ;
1009 $pri_query .= ");";
1012 if (isset($pri_query)) {
1013 if ($display == true) {
1014 echo '<p>' . $pri_query . '</p>';
1016 PMA_DBI_try_query($pri_query, $trg_link, 0);
1018 for ($t = 0; $t < sizeof($matching_tables_fields[$matching_table_index]); $t++) {
1019 if ((isset($alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]])) && (sizeof($alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]]) > 0)) {
1020 $sql_query = 'ALTER TABLE ' . PMA_backquote($trg_db) . '.' . PMA_backquote($matching_tables[$matching_table_index]) . ' MODIFY ' .
1021 $matching_tables_fields[$matching_table_index][$t] . ' ' . $source_columns[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]]['Type'];
1022 $found = false;
1023 for ($i = 0; $i < sizeof($criteria); $i++)
1025 if (isset($alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]][$criteria[$i]]) && $criteria[$i] != 'Key') {
1026 $found = true;
1027 if (($criteria[$i] == 'Type') && (! isset($alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]][$criteria[$i+1]]))) {
1028 if ($source_columns[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]][$criteria[$i + 1]] == 'NO') {
1029 $sql_query .= " Not Null" ;
1030 } elseif ($source_columns[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]][$criteria[$i + 1]] == 'YES') {
1031 $sql_query .= " Null" ;
1034 if (($criteria[$i] == 'Null') && ( $alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]][$criteria[$i]] == 'NO')) {
1035 $sql_query .= " Not Null " ;
1036 } elseif (($criteria[$i] == 'Null') && ($alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]][$criteria[$i]] == 'YES')) {
1037 $sql_query .= " Null " ;
1039 if ($criteria[$i] == 'Collation') {
1040 if( !(isset($alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]][$criteria[2]]))) {
1041 $sql_query .= " Not Null " ;
1043 $sql_query .= " COLLATE " . $alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]][$criteria[$i]] ;
1045 if (($criteria[$i] == 'Default') && ($alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]][$criteria[$i]] == 'None')) {
1046 if( !(isset($alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]][$criteria[2]]))) {
1047 $sql_query .= " Not Null " ;
1049 } elseif($criteria[$i] == 'Default') {
1050 if(! (isset($alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]][$criteria[2]]))) {
1051 $sql_query .= " Not Null " ;
1053 if (is_string($alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]][$criteria[$i]])) {
1054 if ($source_columns[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]]['Type'] != 'timestamp') {
1055 $sql_query .= " DEFAULT '" . $alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]][$criteria[$i]] . "'";
1056 } elseif($source_columns[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]]['Type'] == 'timestamp') {
1057 $sql_query .= " DEFAULT " . $alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]][$criteria[$i]];
1059 } elseif (is_numeric($alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]][$criteria[$i]])) {
1060 $sql_query .= " DEFAULT " . $alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]][$criteria[$i]];
1063 if ($criteria[$i] == 'Comment') {
1064 if( !(isset($alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]][$criteria[2]]))) {
1065 $sql_query .= " Not Null " ;
1067 $sql_query .= " COMMENT '" . $alter_str_array[$matching_table_index][$matching_tables_fields[$matching_table_index][$t]][$criteria[$i]] . "'" ;
1072 $sql_query .= ";";
1073 if ($found) {
1074 if ($display == true) {
1075 echo '<p>' . $sql_query . '</p>';
1077 PMA_DBI_try_query($sql_query, $trg_link, 0);
1080 $check = false;
1081 $query = "ALTER TABLE " . PMA_backquote($trg_db) . '.' . PMA_backquote($matching_tables[$matching_table_index]);
1082 for($p = 0; $p < sizeof($matching_tables_keys[$matching_table_index]); $p++) {
1083 if ((isset($alter_str_array[$matching_table_index][$matching_tables_keys[$matching_table_index][$p]]['Key']))) {
1084 $check = true;
1085 $query .= ' MODIFY ' . $matching_tables_keys[$matching_table_index][$p] . ' '
1086 . $source_columns[$matching_table_index][$matching_tables_fields[$matching_table_index][$p]]['Type'] . ' Not Null ';
1087 if ($p < (sizeof($matching_tables_keys[$matching_table_index]) - 1)) {
1088 $query .= ', ';
1092 if ($check) {
1093 if ($display == true) {
1094 echo '<p>' . $query . '</p>';
1096 PMA_DBI_try_query($query, $trg_link, 0);
1101 * PMA_removeColumnsFromTargetTable() removes the columns which are present in target table but not in source table.
1102 * @uses sizeof()
1103 * @uses PMA_DBI_try_query()
1104 * @uses PMA_DBI_fetch_result()
1106 * @param $trg_db name of target database
1107 * @param $trg_link connection established with target server
1108 * @param $matching_tables array containing names of matching tables
1109 * @param $uncommon_columns array containing the names of the column which are to be dropped from the target table
1110 * @param $table_counter index of the matching table as in $matchiing_tables array
1111 * @param $display true/false value
1113 function PMA_removeColumnsFromTargetTable($trg_db, $trg_link, $matching_tables, $uncommon_columns, $table_counter, $display)
1115 if (isset($uncommon_columns[$table_counter])) {
1116 $drop_query = "ALTER TABLE " . PMA_backquote($trg_db) . "." . PMA_backquote($matching_tables[$table_counter]);
1117 for ($a = 0; $a < sizeof($uncommon_columns[$table_counter]); $a++) {
1118 //Checks if column to be removed is a foreign key in any table
1119 $pk_query = "SELECT * FROM information_schema.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_SCHEMA = '" . $trg_db . "'
1120 AND REFERENCED_TABLE_NAME = '" . $matching_tables[$table_counter]."' AND REFERENCED_COLUMN_NAME = '"
1121 . $uncommon_columns[$table_counter][$a] . "' AND TABLE_NAME <> REFERENCED_TABLE_NAME;";
1123 $pk_query_result = PMA_DBI_fetch_result($pk_query, null, null, $trg_link);
1124 $result_size = sizeof($pk_query_result);
1126 if ($result_size > 0) {
1127 for ($b = 0; $b < $result_size; $b++) {
1128 $drop_pk_query = "ALTER TABLE " . PMA_backquote($pk_query_result[$b]['TABLE_SCHEMA']) . "." . PMA_backquote($pk_query_result[$b]['TABLE_NAME']) . "
1129 DROP FOREIGN KEY " . $pk_query_result[$b]['CONSTRAINT_NAME'] . ", DROP COLUMN " . $pk_query_result[$b]['COLUMN_NAME'] . ";";
1130 PMA_DBI_try_query($drop_pk_query, $trg_link, 0);
1133 $query = "SELECT * FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = '" . $trg_db . "' AND TABLE_NAME = '"
1134 . $matching_tables[$table_counter]. "' AND COLUMN_NAME = '" . $uncommon_columns[$table_counter][$a] . "'
1135 AND TABLE_NAME <> REFERENCED_TABLE_NAME;";
1137 $result = PMA_DBI_fetch_result($query, null, null, $trg_link);
1139 if (sizeof($result) > 0) {
1140 $drop_query .= " DROP FOREIGN KEY " . $result[0]['CONSTRAINT_NAME'] . ",";
1142 $drop_query .= " DROP COLUMN " . $uncommon_columns[$table_counter][$a];
1143 if ($a < (sizeof($uncommon_columns[$table_counter]) - 1)) {
1144 $drop_query .= " , " ;
1147 $drop_query .= ";" ;
1149 if ($display == true) {
1150 echo '<p>' . $drop_query . '</p>';
1152 PMA_DBI_try_query($drop_query, $trg_link, 0);
1156 * PMA_indexesDiffInTables() compares the source table indexes with target table indexes and keep the indexes to be added in target table in $add_indexes_array
1157 * indexes to be altered in $alter_indexes_array and indexes to be removed from target table in $remove_indexes_array.
1158 * Only keyname and uniqueness characteristic of the indexes are altered.
1159 * @uses sizeof()
1160 * @uses PMA_DBI_get_table_indexes()
1162 * @param $src_db name of source database
1163 * @param $trg_db name of target database
1164 * @param $src_link connection established with source server
1165 * @param $trg_link connection established with target server
1166 * @param $matching_tables array containing the matching tables name
1167 * @param $source_indexes array containing the indexes of the source table
1168 * @param $target_indexes array containing the indexes of the target table
1169 * @param $add_indexes_array array containing the name of the column on which the index is to be added in the target table
1170 * @param $alter_indexes_array array containing the key name which needs to be altered
1171 * @param $remove_indexes_array array containing the key name of the index which is to be removed from the target table
1172 * @param $table_counter number of the matching table
1174 function PMA_indexesDiffInTables($src_db, $trg_db, $src_link, $trg_link, $matching_tables, &$source_indexes, &$target_indexes, &$add_indexes_array,
1175 &$alter_indexes_array, &$remove_indexes_array, $table_counter)
1177 //Gets indexes information for source and target table
1178 $source_indexes[$table_counter] = PMA_DBI_get_table_indexes($src_db, $matching_tables[$table_counter],$src_link);
1179 $target_indexes[$table_counter] = PMA_DBI_get_table_indexes($trg_db, $matching_tables[$table_counter],$trg_link);
1180 for ($a = 0; $a < sizeof($source_indexes[$table_counter]); $a++) {
1181 $found = false;
1182 $z = 0;
1183 //Compares key name and non_unique characteristic of source indexes with target indexes
1185 * @todo compare the length of each sub part
1187 while (($z <= sizeof($target_indexes[$table_counter])) && ($found == false))
1189 if (isset($source_indexes[$table_counter][$a]) && isset($target_indexes[$table_counter][$z]) && $source_indexes[$table_counter][$a]['Key_name'] == $target_indexes[$table_counter][$z]['Key_name']) {
1190 $found = true;
1191 if (($source_indexes[$table_counter][$a]['Column_name'] != $target_indexes[$table_counter][$z]['Column_name']) || ($source_indexes[$table_counter][$a]['Non_unique'] != $target_indexes[$table_counter][$z]['Non_unique'])) {
1192 if (! (($source_indexes[$table_counter][$a]['Key_name'] == "PRIMARY") || ($target_indexes[$table_counter][$z]['Key_name'] == 'PRIMARY'))) {
1193 $alter_indexes_array[$table_counter][] = $source_indexes[$table_counter][$a]['Key_name'];
1197 $z++;
1199 if ($found === false) {
1200 if(! ($source_indexes[$table_counter][$a]['Key_name'] == 'PRIMARY')) {
1201 $add_indexes_array [$table_counter][] = $source_indexes[$table_counter][$a]['Column_name'];
1206 //Finds indexes that exist on target table but not on source table
1207 for ($b = 0; $b < sizeof($target_indexes[$table_counter]); $b++) {
1208 $found = false;
1209 $c = 0;
1210 while (($c <= sizeof($source_indexes[$table_counter])) && ($found == false))
1212 if ($target_indexes[$table_counter][$b]['Column_name'] == $source_indexes[$table_counter][$c]['Column_name']) {
1213 $found = true;
1215 $c++;
1217 if ($found === false) {
1218 $remove_indexes_array[$table_counter][] = $target_indexes[$table_counter][$b]['Key_name'];
1224 * PMA_applyIndexesDiff() create indexes, alters indexes and remove indexes.
1225 * @uses sizeof()
1226 * @uses PMA_DBI_try_query()
1228 * @param $trg_db name of target database
1229 * @param $trg_link connection established with target server
1230 * @param $matching_tables array containing the matching tables name
1231 * @param $source_indexes array containing the indexes of the source table
1232 * @param $target_indexes array containing the indexes of the target table
1233 * @param $add_indexes_array array containing the column names on which indexes are to be created in target table
1234 * @param $alter_indexes_array array containing the column names for which indexes are to be altered
1235 * @param $remove_indexes_array array containing the key name of the indexes which are to be removed from the target table
1236 * @param $table_counter number of the matching table
1237 * @param $display true/false value
1239 function PMA_applyIndexesDiff ($trg_db, $trg_link, $matching_tables, $source_indexes, $target_indexes, $add_indexes_array, $alter_indexes_array,
1240 $remove_indexes_array, $table_counter, $display)
1242 //Adds indexes on target table
1243 if (isset($add_indexes_array[$table_counter])) {
1244 $sql = "ALTER TABLE " . PMA_backquote($trg_db) . "." . PMA_backquote($matching_tables[$table_counter]) . " ADD" ;
1245 for ($a = 0; $a < sizeof($source_indexes[$table_counter]); $a++) {
1246 if (isset($add_indexes_array[$table_counter][$a])) {
1247 for ($b = 0; $b < sizeof($source_indexes[$table_counter]); $b++) {
1248 if ($source_indexes[$table_counter][$b]['Column_name'] == $add_indexes_array[$table_counter][$a]) {
1249 if ($source_indexes[$table_counter][$b]['Non_unique'] == '0') {
1250 $sql .= " UNIQUE ";
1252 $sql .= " INDEX " . $source_indexes[$table_counter][$b]['Key_name'] . " (" . $add_indexes_array[$table_counter][$a] . " );";
1253 if ($display == true) {
1254 echo '<p>' . $sql . '</p>';
1256 PMA_DBI_try_query($sql, $trg_link, 0);
1262 //Alter indexes of target table
1264 if (isset($alter_indexes_array[$table_counter])) {
1265 $query = "ALTER TABLE " . PMA_backquote($trg_db) . "." . PMA_backquote($matching_tables[$table_counter]);
1266 for ($a = 0; $a < sizeof($alter_indexes_array[$table_counter]); $a++) {
1267 if (isset($alter_indexes_array[$table_counter][$a])) {
1268 $query .= ' DROP INDEX ' . PMA_backquote($alter_indexes_array[$table_counter][$a]) . " , ADD ";
1269 $got_first_index_column = false;
1270 for ($z = 0; $z < sizeof($source_indexes[$table_counter]); $z++) {
1271 if ($source_indexes[$table_counter][$z]['Key_name'] == $alter_indexes_array[$table_counter][$a]) {
1272 if (! $got_first_index_column) {
1273 if ($source_indexes[$table_counter][$z]['Non_unique'] == '0') {
1274 $query .= " UNIQUE ";
1276 $query .= " INDEX " . PMA_backquote($source_indexes[$table_counter][$z]['Key_name']) . " (" . PMA_backquote($source_indexes[$table_counter][$z]['Column_name']);
1277 $got_first_index_column = true;
1278 } else {
1279 // another column for this index
1280 $query .= ', ' . PMA_backquote($source_indexes[$table_counter][$z]['Column_name']);
1284 $query .= " )";
1287 if ($display == true) {
1288 echo '<p>' . $query . '</p>';
1290 PMA_DBI_try_query($query, $trg_link, 0);
1292 //Removes indexes from target table
1293 if (isset($remove_indexes_array[$table_counter])) {
1294 $drop_index_query = "ALTER TABLE " . PMA_backquote($trg_db) . "." . PMA_backquote($matching_tables[$table_counter]);
1295 for ($a = 0; $a < sizeof($target_indexes[$table_counter]); $a++) {
1296 if (isset($remove_indexes_array[$table_counter][$a])) {
1297 $drop_index_query .= " DROP INDEX " . $remove_indexes_array[$table_counter][$a];
1299 if ($a < (sizeof($remove_indexes_array[$table_counter]) - 1)) {
1300 $drop_index_query .= " , " ;
1303 $drop_index_query .= " ; " ;
1304 if ($display == true) {
1305 echo '<p>' . $drop_index_query . '</p>';
1307 PMA_DBI_try_query($drop_index_query, $trg_link, 0);
1312 * PMA_displayQuery() displays a query, taking the maximum display size
1313 * into account
1314 * @uses $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']
1316 * @param $query the query to display
1318 function PMA_displayQuery($query) {
1319 if (strlen($query) > $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) {
1320 $query = substr($query, 0, $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) . '[...]';
1322 echo '<p>' . htmlspecialchars($query) . '</p>';
1326 * PMA_syncDisplayHeaderSource() shows the header for source database
1327 * @uses $_SESSION['src_type']
1328 * @uses $_SESSION['src_server']['host']
1330 * @param string $src_db source db name
1332 function PMA_syncDisplayHeaderSource($src_db) {
1333 echo '<div id="serverstatus" style = "overflow: auto; width: 1020px; height: 220px; border-left: 1px gray solid; border-bottom: 1px gray solid; padding:0px; margin-bottom: 1em "> ';
1335 echo '<table id="serverstatusconnections" class="data" width="55%">';
1336 echo '<tr>';
1337 echo '<th>' . __('Source database') . ': ' . $src_db . '<br />(';
1338 if ('cur' == $_SESSION['src_type']) {
1339 echo __('Current server');
1340 } else {
1341 echo __('Remote server') . ' ' . $_SESSION['src_server']['host'];
1343 echo ')</th>';
1344 echo '<th>' . __('Difference') . '</th>';
1345 echo '</tr>';
1349 * PMA_syncDisplayHeaderTargetAndMatchingTables() shows the header for target database and the matching tables
1350 * @uses $_SESSION['trg_type']
1351 * @uses $_SESSION['trg_server']['host']
1353 * @param string $trg_db target db name
1354 * @param array $matching_tables
1355 * @return boolean $odd_row current value of this toggle
1357 function PMA_syncDisplayHeaderTargetAndMatchingTables($trg_db, $matching_tables) {
1358 echo '<table id="serverstatusconnections" class="data" width="43%">';
1359 echo '<tr>';
1360 echo '<th>' . __('Target database') . ': '. $trg_db . '<br />(';
1361 if ('cur' == $_SESSION['trg_type']) {
1362 echo __('Current server');
1363 } else {
1364 echo __('Remote server') . ' ' . $_SESSION['trg_server']['host'];
1366 echo ')</th>';
1367 echo '</tr>';
1368 $odd_row = false;
1369 foreach ($matching_tables as $tbl_name) {
1370 $odd_row = PMA_syncDisplayBeginTableRow($odd_row);
1371 echo '<td> ' . htmlspecialchars($tbl_name) . '</td>';
1372 echo '</tr>';
1374 return $odd_row;
1378 * PMA_syncDisplayBeginTableRow() displays the TR tag for alternating colors
1380 * @param boolean $odd_row current status of the toggle
1381 * @return boolean $odd_row final status of the toggle
1383 function PMA_syncDisplayBeginTableRow($odd_row) {
1384 $odd_row = ! $odd_row;
1385 echo '<tr height="32" class=" ';
1386 echo $odd_row ? 'odd' : 'even';
1387 echo '">';
1388 return $odd_row;