[ Index ] |
|
Code source de phpMyAdmin 2.10.3 |
1 <?php 2 /* $Id: Table.class.php 10401 2007-05-17 21:57:15Z lem9 $ */ 3 // vim: expandtab sw=4 ts=4 sts=4: 4 5 class PMA_Table { 6 7 /** 8 * @var string table name 9 */ 10 var $name = ''; 11 12 /** 13 * @var string database name 14 */ 15 var $db_name = ''; 16 17 /** 18 * @var string engine (innodb, myisam, bdb, ...) 19 */ 20 var $engine = ''; 21 22 /** 23 * @var string type (view, base table, system view) 24 */ 25 var $type = ''; 26 27 /** 28 * @var array settings 29 */ 30 var $settings = array(); 31 32 /** 33 * @var array errors occured 34 */ 35 var $errors = array(); 36 37 /** 38 * @var array messages 39 */ 40 var $messages = array(); 41 42 /** 43 * Constructor 44 * 45 * @param string $table_name table name 46 * @param string $db_name database name 47 */ 48 function __construct($table_name, $db_name) 49 { 50 $this->setName($table_name); 51 $this->setDbName($db_name); 52 } 53 54 /** 55 * @see PMA_Table::getName() 56 */ 57 function __toString() 58 { 59 return $this->getName(); 60 } 61 62 function getLastError() 63 { 64 return end($this->errors); 65 } 66 67 function getLastMessage() 68 { 69 return end($this->messages); 70 } 71 72 /** 73 * sets table anme 74 * 75 * @uses $this->name to set it 76 * @param string $table_name new table name 77 */ 78 function setName($table_name) 79 { 80 $this->name = $table_name; 81 } 82 83 /** 84 * returns table name 85 * 86 * @uses $this->name as return value 87 * @param boolean wether to quote name with backticks `` 88 * @return string table name 89 */ 90 function getName($quoted = false) 91 { 92 if ($quoted) { 93 return PMA_backquote($this->name); 94 } 95 return $this->name; 96 } 97 98 /** 99 * sets database name for this table 100 * 101 * @uses $this->db_name to set it 102 * @param string $db_name 103 */ 104 function setDbName($db_name) 105 { 106 $this->db_name = $db_name; 107 } 108 109 /** 110 * returns database name for this table 111 * 112 * @uses $this->db_name as return value 113 * @param boolean wether to quote name with backticks `` 114 * @return string database name for this table 115 */ 116 function getDbName($quoted = false) 117 { 118 if ($quoted) { 119 return PMA_backquote($this->db_name); 120 } 121 return $this->db_name; 122 } 123 124 /** 125 * returns full name for table, including database name 126 * 127 * @param boolean wether to quote name with backticks `` 128 */ 129 function getFullName($quoted = false) 130 { 131 return $this->getDbName($quoted) . '.' . $this->getName($quoted); 132 } 133 134 function isView($db = null, $table = null) 135 { 136 if (null !== $db && null !== $table) { 137 return PMA_Table::_isView($db, $table); 138 } 139 140 if (strpos($this->get('TABLE TYPE'), 'VIEW')) { 141 return true; 142 } 143 144 return false; 145 } 146 147 /** 148 * sets given $value for given $param 149 * 150 * @uses $this->settings to add or change value 151 * @param string param name 152 * @param mixed param value 153 */ 154 function set($param, $value) 155 { 156 $this->settings[$param] = $value; 157 } 158 159 /** 160 * returns value for given setting/param 161 * 162 * @uses $this->settings to return value 163 * @param string name for value to return 164 * @return mixed value for $param 165 */ 166 function get($param) 167 { 168 if (isset($this->settings[$param])) { 169 return $this->settings[$param]; 170 } 171 172 return null; 173 } 174 175 /** 176 * loads structure data 177 */ 178 function loadStructure() 179 { 180 $table_info = PMA_DBI_get_tables_full($this->getDbName(), $this->getName()); 181 182 if (false === $table_info) { 183 return false; 184 } 185 186 $this->settings = $table_info; 187 188 if ($this->get('TABLE_ROWS') === null) { 189 $this->set('TABLE_ROWS', PMA_Table::countRecords($this->getDbName(), 190 $this->getName(), true, true)); 191 } 192 193 $create_options = explode(' ', $this->get('TABLE_ROWS')); 194 195 // export create options by its name as variables into gloabel namespace 196 // f.e. pack_keys=1 becomes available as $pack_keys with value of '1' 197 foreach ($create_options as $each_create_option) { 198 $each_create_option = explode('=', $each_create_option); 199 if (isset($each_create_option[1])) { 200 $this->set($$each_create_option[0], $each_create_option[1]); 201 } 202 } 203 } 204 205 /** 206 * old PHP 4style constructor 207 * 208 * @see PMA_Table::__construct() 209 */ 210 function PMA_Table($table_name, $db_name) 211 { 212 $this->__construct($table_name, $db_name); 213 } 214 215 /** 216 * Checks if this "table" is a view 217 * 218 * @deprecated 219 * @todo see what we could do with the possible existence of $table_is_view 220 * @param string the database name 221 * @param string the table name 222 * 223 * @return boolean whether this is a view 224 * 225 * @access public 226 */ 227 function _isView($db, $table) { 228 // maybe we already know if the table is a view 229 if (isset($GLOBALS['tbl_is_view']) && $GLOBALS['tbl_is_view']) { 230 return true; 231 } 232 // old MySQL version: no view 233 if (PMA_MYSQL_INT_VERSION < 50000) { 234 return false; 235 } 236 // This would be the correct way of doing the check but at least in 237 // MySQL 5.0.33 it's too slow when there are hundreds of databases 238 // and/or tables (more than 3 minutes for 400 tables) 239 /*if (false === PMA_DBI_fetch_value('SELECT TABLE_NAME FROM `information_schema`.`VIEWS` WHERE `TABLE_SCHEMA` = \'' . $db . '\' AND `TABLE_NAME` = \'' . $table . '\';')) { 240 return false; 241 } else { 242 return true; 243 } */ 244 // A more complete verification would be to check if all columns 245 // from the result set are NULL except Name and Comment. 246 // MySQL from 5.0.0 to 5.0.12 returns 'view', 247 // from 5.0.13 returns 'VIEW'. 248 $comment = strtoupper(PMA_DBI_fetch_value('SHOW TABLE STATUS FROM ' . PMA_backquote($db) . ' LIKE \'' . $table . '\'', 0, 'Comment')); 249 return ($comment == 'VIEW'); 250 } 251 252 /** 253 * generates column/field specification for ALTER or CREATE TABLE syntax 254 * 255 * @todo move into class PMA_Column 256 * @todo on the interface, some js to clear the default value when the default 257 * current_timestamp is checked 258 * @static 259 * @param string $name name 260 * @param string $type type ('INT', 'VARCHAR', 'BIT', ...) 261 * @param string $length length ('2', '5,2', '', ...) 262 * @param string $attribute 263 * @param string $collation 264 * @param string $null with 'NULL' or 'NOT NULL' 265 * @param string $default default value 266 * @param boolean $default_current_timestamp whether default value is 267 * CURRENT_TIMESTAMP or not 268 * this overrides $default value 269 * @param string $extra 'AUTO_INCREMENT' 270 * @param string $comment field comment 271 * @param array &$field_primary list of fields for PRIMARY KEY 272 * @param string $index 273 * @param string $default_orig 274 * @return string field specification 275 */ 276 function generateFieldSpec($name, $type, $length = '', $attribute = '', 277 $collation = '', $null = false, $default = '', 278 $default_current_timestamp = false, $extra = '', $comment = '', 279 &$field_primary, $index, $default_orig = false) 280 { 281 282 $is_timestamp = strpos(' ' . strtoupper($type), 'TIMESTAMP') == 1; 283 284 // $default_current_timestamp has priority over $default 285 286 /** 287 * @todo include db-name 288 */ 289 $query = PMA_backquote($name) . ' ' . $type; 290 291 if ($length != '' 292 && !preg_match('@^(DATE|DATETIME|TIME|TINYBLOB|TINYTEXT|BLOB|TEXT|MEDIUMBLOB|MEDIUMTEXT|LONGBLOB|LONGTEXT)$@i', $type)) { 293 $query .= '(' . $length . ')'; 294 } 295 296 if ($attribute != '') { 297 $query .= ' ' . $attribute; 298 } 299 300 if (PMA_MYSQL_INT_VERSION >= 40100 && !empty($collation) 301 && $collation != 'NULL' 302 && preg_match('@^(TINYTEXT|TEXT|MEDIUMTEXT|LONGTEXT|VARCHAR|CHAR|ENUM|SET)$@i', $type)) { 303 $query .= PMA_generateCharsetQueryPart($collation); 304 } 305 306 if ($null !== false) { 307 if (!empty($null)) { 308 $query .= ' NOT NULL'; 309 } else { 310 $query .= ' NULL'; 311 } 312 } 313 314 if ($default_current_timestamp && $is_timestamp) { 315 $query .= ' DEFAULT CURRENT_TIMESTAMP'; 316 // auto_increment field cannot have a default value 317 } elseif ($extra !== 'AUTO_INCREMENT' 318 && (strlen($default) || $default != $default_orig)) { 319 if (strtoupper($default) == 'NULL') { 320 $query .= ' DEFAULT NULL'; 321 } else { 322 if (strlen($default)) { 323 if ($is_timestamp) { 324 // a TIMESTAMP does not accept DEFAULT '0' 325 // but DEFAULT 0 works 326 $query .= ' DEFAULT ' . PMA_sqlAddslashes($default); 327 } else { 328 $query .= ' DEFAULT \'' . PMA_sqlAddslashes($default) . '\''; 329 } 330 } 331 } 332 } 333 334 if (!empty($extra)) { 335 $query .= ' ' . $extra; 336 // An auto_increment field must be use as a primary key 337 if ($extra == 'AUTO_INCREMENT' && isset($field_primary)) { 338 $primary_cnt = count($field_primary); 339 for ($j = 0; $j < $primary_cnt && $field_primary[$j] != $index; $j++) { 340 // void 341 } // end for 342 if (isset($field_primary[$j]) && $field_primary[$j] == $index) { 343 $query .= ' PRIMARY KEY'; 344 unset($field_primary[$j]); 345 } // end if 346 } // end if (auto_increment) 347 } 348 if (PMA_MYSQL_INT_VERSION >= 40100 && !empty($comment)) { 349 $query .= " COMMENT '" . PMA_sqlAddslashes($comment) . "'"; 350 } 351 return $query; 352 } // end function 353 354 /** 355 * Counts and returns (or displays) the number of records in a table 356 * 357 * Revision 13 July 2001: Patch for limiting dump size from 358 * vinay@sanisoft.com & girish@sanisoft.com 359 * 360 * @param string the current database name 361 * @param string the current table name 362 * @param boolean whether to retain or to displays the result 363 * @param boolean whether to force an exact count 364 * 365 * @return mixed the number of records if retain is required, true else 366 * 367 * @access public 368 */ 369 function countRecords($db, $table, $ret = false, $force_exact = false) 370 { 371 $row_count = false; 372 373 if (! $force_exact) { 374 $row_count = PMA_DBI_fetch_value( 375 'SHOW TABLE STATUS FROM ' . PMA_backquote($db) . ' LIKE \'' 376 . PMA_sqlAddslashes($table, true) . '\';', 377 0, 'Rows'); 378 } 379 380 $tbl_is_view = PMA_Table::isView($db, $table); 381 382 // for a VIEW, $row_count is always false at this point 383 if (false === $row_count || $row_count < $GLOBALS['cfg']['MaxExactCount']) { 384 if (! $tbl_is_view) { 385 $row_count = PMA_DBI_fetch_value( 386 'SELECT COUNT(*) FROM ' . PMA_backquote($db) . '.' 387 . PMA_backquote($table)); 388 } else { 389 // For complex views, even trying to get a partial record 390 // count could bring down a server, so we offer an 391 // alternative: setting MaxExactCountViews to 0 will bypass 392 // completely the record counting for views 393 394 if ($GLOBALS['cfg']['MaxExactCountViews'] == 0) { 395 $row_count = 0; 396 } else { 397 // Counting all rows of a VIEW could be too long, so use 398 // a LIMIT clause. 399 // Use try_query because it can fail ( a VIEW is based on 400 // a table that no longer exists) 401 $result = PMA_DBI_try_query( 402 'SELECT 1 FROM ' . PMA_backquote($db) . '.' 403 . PMA_backquote($table) . ' LIMIT ' 404 . $GLOBALS['cfg']['MaxExactCountViews'], 405 null, PMA_DBI_QUERY_STORE); 406 if (!PMA_DBI_getError()) { 407 $row_count = PMA_DBI_num_rows($result); 408 PMA_DBI_free_result($result); 409 } 410 } 411 } 412 } 413 414 if ($ret) { 415 return $row_count; 416 } 417 418 /** 419 * @deprecated at the moment nowhere is $return = false used 420 */ 421 // Note: as of PMA 2.8.0, we no longer seem to be using 422 // PMA_Table::countRecords() in display mode. 423 echo PMA_formatNumber($row_count, 0); 424 if ($tbl_is_view) { 425 echo ' ' 426 . sprintf($GLOBALS['strViewMaxExactCount'], 427 $GLOBALS['cfg']['MaxExactCount'], 428 '[a@./Documentation.html#cfg_MaxExactCount@_blank]', '[/a]'); 429 } 430 } // end of the 'PMA_Table::countRecords()' function 431 432 /** 433 * @todo add documentation 434 */ 435 function generateAlter($oldcol, $newcol, $type, $length, 436 $attribute, $collation, $null, $default, $default_current_timestamp, 437 $extra, $comment='', $default_orig) 438 { 439 $empty_a = array(); 440 return PMA_backquote($oldcol) . ' ' 441 . PMA_Table::generateFieldSpec($newcol, $type, $length, $attribute, 442 $collation, $null, $default, $default_current_timestamp, $extra, 443 $comment, $empty_a, -1, $default_orig); 444 } // end function 445 446 /** 447 * Inserts existing entries in a PMA_* table by reading a value from an old entry 448 * 449 * @param string The array index, which Relation feature to check 450 * ('relwork', 'commwork', ...) 451 * @param string The array index, which PMA-table to update 452 * ('bookmark', 'relation', ...) 453 * @param array Which fields will be SELECT'ed from the old entry 454 * @param array Which fields will be used for the WHERE query 455 * (array('FIELDNAME' => 'FIELDVALUE')) 456 * @param array Which fields will be used as new VALUES. These are the important 457 * keys which differ from the old entry. 458 * (array('FIELDNAME' => 'NEW FIELDVALUE')) 459 460 * @global string relation variable 461 * 462 * @author Garvin Hicking <me@supergarv.de> 463 */ 464 function duplicateInfo($work, $pma_table, $get_fields, $where_fields, 465 $new_fields) 466 { 467 $last_id = -1; 468 469 if (isset($GLOBALS['cfgRelation']) && $GLOBALS['cfgRelation'][$work]) { 470 $select_parts = array(); 471 $row_fields = array(); 472 foreach ($get_fields as $get_field) { 473 $select_parts[] = PMA_backquote($get_field); 474 $row_fields[$get_field] = 'cc'; 475 } 476 477 $where_parts = array(); 478 foreach ($where_fields as $_where => $_value) { 479 $where_parts[] = PMA_backquote($_where) . ' = \'' 480 . PMA_sqlAddslashes($_value) . '\''; 481 } 482 483 $new_parts = array(); 484 $new_value_parts = array(); 485 foreach ($new_fields as $_where => $_value) { 486 $new_parts[] = PMA_backquote($_where); 487 $new_value_parts[] = PMA_sqlAddslashes($_value); 488 } 489 490 $table_copy_query = ' 491 SELECT ' . implode(', ', $select_parts) . ' 492 FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' 493 . PMA_backquote($GLOBALS['cfgRelation'][$pma_table]) . ' 494 WHERE ' . implode(' AND ', $where_parts); 495 496 // must use PMA_DBI_QUERY_STORE here, since we execute another 497 // query inside the loop 498 $table_copy_rs = PMA_query_as_cu($table_copy_query, true, 499 PMA_DBI_QUERY_STORE); 500 501 while ($table_copy_row = @PMA_DBI_fetch_assoc($table_copy_rs)) { 502 $value_parts = array(); 503 foreach ($table_copy_row as $_key => $_val) { 504 if (isset($row_fields[$_key]) && $row_fields[$_key] == 'cc') { 505 $value_parts[] = PMA_sqlAddslashes($_val); 506 } 507 } 508 509 $new_table_query = ' 510 INSERT IGNORE INTO ' . PMA_backquote($GLOBALS['cfgRelation']['db']) 511 . '.' . PMA_backquote($GLOBALS['cfgRelation'][$pma_table]) . ' 512 (' . implode(', ', $select_parts) . ', 513 ' . implode(', ', $new_parts) . ') 514 VALUES 515 (\'' . implode('\', \'', $value_parts) . '\', 516 \'' . implode('\', \'', $new_value_parts) . '\')'; 517 518 PMA_query_as_cu($new_table_query); 519 $last_id = PMA_DBI_insert_id(); 520 } // end while 521 522 PMA_DBI_free_result($table_copy_rs); 523 524 return $last_id; 525 } 526 527 return true; 528 } // end of 'PMA_Table::duplicateInfo()' function 529 530 531 /** 532 * Copies or renames table 533 * @todo use RENAME for move operations 534 * - would work only if the databases are on the same filesystem, 535 * how can we check that? try the operation and 536 * catch an error? 537 * - for views, only if MYSQL > 50013 538 * - still have to handle pmadb synch. 539 * 540 * @author Michal Cihar <michal@cihar.com> 541 */ 542 function moveCopy($source_db, $source_table, $target_db, $target_table, $what, $move, $mode) 543 { 544 global $err_url; 545 546 if (! isset($GLOBALS['sql_query'])) { 547 $GLOBALS['sql_query'] = ''; 548 } 549 550 // set export settings we need 551 $GLOBALS['sql_backquotes'] = 1; 552 $GLOBALS['asfile'] = 1; 553 554 // Ensure the target is valid 555 if (! $GLOBALS['PMA_List_Database']->exists($source_db, $target_db)) { 556 /** 557 * @todo exit really needed here? or just a return? 558 */ 559 exit; 560 } 561 562 $source = PMA_backquote($source_db) . '.' . PMA_backquote($source_table); 563 if (! isset($target_db) || ! strlen($target_db)) { 564 $target_db = $source_db; 565 } 566 567 // Doing a select_db could avoid some problems with replicated databases, 568 // when moving table from replicated one to not replicated one 569 PMA_DBI_select_db($target_db); 570 571 $target = PMA_backquote($target_db) . '.' . PMA_backquote($target_table); 572 573 // do not create the table if dataonly 574 if ($what != 'dataonly') { 575 require_once './libraries/export/sql.php'; 576 577 $no_constraints_comments = true; 578 $GLOBALS['sql_constraints_query'] = ''; 579 580 $sql_structure = PMA_getTableDef($source_db, $source_table, "\n", $err_url); 581 unset($no_constraints_comments); 582 $parsed_sql = PMA_SQP_parse($sql_structure); 583 $analyzed_sql = PMA_SQP_analyze($parsed_sql); 584 $i = 0; 585 if (empty($analyzed_sql[0]['create_table_fields'])) { 586 // this is not a CREATE TABLE, so find the first VIEW 587 $target_for_view = PMA_backquote($target_db); 588 while (true) { 589 if ($parsed_sql[$i]['type'] == 'alpha_reservedWord' && $parsed_sql[$i]['data'] == 'VIEW') { 590 break; 591 } 592 $i++; 593 } 594 } 595 unset($analyzed_sql); 596 597 /* nijel: Find table name in query and replace it */ 598 while ($parsed_sql[$i]['type'] != 'quote_backtick') { 599 $i++; 600 } 601 602 /* no need to PMA_backquote() */ 603 if (isset($target_for_view)) { 604 // this a view definition; we just found the first db name 605 // that follows DEFINER VIEW 606 // so change it for the new db name 607 $parsed_sql[$i]['data'] = $target_for_view; 608 // then we have to find all references to the source db 609 // and change them to the target db, ensuring we stay into 610 // the $parsed_sql limits 611 $last = $parsed_sql['len'] - 1; 612 $backquoted_source_db = PMA_backquote($source_db); 613 for (++$i; $i <= $last; $i++) { 614 if ($parsed_sql[$i]['type'] == 'quote_backtick' && $parsed_sql[$i]['data'] == $backquoted_source_db) { 615 $parsed_sql[$i]['data'] = $target_for_view; 616 } 617 } 618 unset($last,$backquoted_source_db); 619 } else { 620 $parsed_sql[$i]['data'] = $target; 621 } 622 623 /* Generate query back */ 624 $sql_structure = PMA_SQP_formatHtml($parsed_sql, 'query_only'); 625 // If table exists, and 'add drop table' is selected: Drop it! 626 $drop_query = ''; 627 if (isset($GLOBALS['drop_if_exists']) 628 && $GLOBALS['drop_if_exists'] == 'true') { 629 if (PMA_Table::_isView($target_db,$target_table)) { 630 $drop_query = 'DROP VIEW'; 631 } else { 632 $drop_query = 'DROP TABLE'; 633 } 634 $drop_query .= ' IF EXISTS ' 635 . PMA_backquote($target_db) . '.' 636 . PMA_backquote($target_table); 637 PMA_DBI_query($drop_query); 638 639 $GLOBALS['sql_query'] .= "\n" . $drop_query . ';'; 640 641 // garvin: If an existing table gets deleted, maintain any 642 // entries for the PMA_* tables 643 $maintain_relations = true; 644 } 645 646 @PMA_DBI_query($sql_structure); 647 $GLOBALS['sql_query'] .= "\n" . $sql_structure . ';'; 648 649 if (($move || isset($GLOBALS['add_constraints'])) 650 && !empty($GLOBALS['sql_constraints_query'])) { 651 $parsed_sql = PMA_SQP_parse($GLOBALS['sql_constraints_query']); 652 $i = 0; 653 654 // find the first quote_backtick, it must be the source table name 655 while ($parsed_sql[$i]['type'] != 'quote_backtick') { 656 $i++; 657 // maybe someday we should guard against going over limit 658 //if ($i == $parsed_sql['len']) { 659 // break; 660 //} 661 } 662 663 // replace it by the target table name, no need to PMA_backquote() 664 $parsed_sql[$i]['data'] = $target; 665 666 // now we must remove all quote_backtick that follow a CONSTRAINT 667 // keyword, because a constraint name must be unique in a db 668 669 $cnt = $parsed_sql['len'] - 1; 670 671 for ($j = $i; $j < $cnt; $j++) { 672 if ($parsed_sql[$j]['type'] == 'alpha_reservedWord' 673 && strtoupper($parsed_sql[$j]['data']) == 'CONSTRAINT') { 674 if ($parsed_sql[$j+1]['type'] == 'quote_backtick') { 675 $parsed_sql[$j+1]['data'] = ''; 676 } 677 } 678 } 679 680 // Generate query back 681 $GLOBALS['sql_constraints_query'] = PMA_SQP_formatHtml($parsed_sql, 682 'query_only'); 683 if ($mode == 'one_table') { 684 PMA_DBI_query($GLOBALS['sql_constraints_query']); 685 } 686 $GLOBALS['sql_query'] .= "\n" . $GLOBALS['sql_constraints_query']; 687 if ($mode == 'one_table') { 688 unset($GLOBALS['sql_constraints_query']); 689 } 690 } 691 692 } else { 693 $GLOBALS['sql_query'] = ''; 694 } 695 696 // Copy the data unless this is a VIEW 697 if (($what == 'data' || $what == 'dataonly') && ! PMA_Table::_isView($target_db,$target_table)) { 698 $sql_insert_data = 699 'INSERT INTO ' . $target . ' SELECT * FROM ' . $source; 700 PMA_DBI_query($sql_insert_data); 701 $GLOBALS['sql_query'] .= "\n\n" . $sql_insert_data . ';'; 702 } 703 704 require_once './libraries/relation.lib.php'; 705 $GLOBALS['cfgRelation'] = PMA_getRelationsParam(); 706 707 // Drops old table if the user has requested to move it 708 if ($move) { 709 710 // This could avoid some problems with replicated databases, when 711 // moving table from replicated one to not replicated one 712 PMA_DBI_select_db($source_db); 713 714 if (PMA_Table::_isView($source_db,$source_table)) { 715 $sql_drop_query = 'DROP VIEW'; 716 } else { 717 $sql_drop_query = 'DROP TABLE'; 718 } 719 $sql_drop_query .= ' ' . $source; 720 PMA_DBI_query($sql_drop_query); 721 722 // garvin: Move old entries from PMA-DBs to new table 723 if ($GLOBALS['cfgRelation']['commwork']) { 724 $remove_query = 'UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($GLOBALS['cfgRelation']['column_info']) 725 . ' SET table_name = \'' . PMA_sqlAddslashes($target_table) . '\', ' 726 . ' db_name = \'' . PMA_sqlAddslashes($target_db) . '\'' 727 . ' WHERE db_name = \'' . PMA_sqlAddslashes($source_db) . '\'' 728 . ' AND table_name = \'' . PMA_sqlAddslashes($source_table) . '\''; 729 PMA_query_as_cu($remove_query); 730 unset($remove_query); 731 } 732 733 // garvin: updating bookmarks is not possible since only a single table is moved, 734 // and not the whole DB. 735 736 if ($GLOBALS['cfgRelation']['displaywork']) { 737 $table_query = 'UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($GLOBALS['cfgRelation']['table_info']) 738 . ' SET db_name = \'' . PMA_sqlAddslashes($target_db) . '\', ' 739 . ' table_name = \'' . PMA_sqlAddslashes($target_table) . '\'' 740 . ' WHERE db_name = \'' . PMA_sqlAddslashes($source_db) . '\'' 741 . ' AND table_name = \'' . PMA_sqlAddslashes($source_table) . '\''; 742 PMA_query_as_cu($table_query); 743 unset($table_query); 744 } 745 746 if ($GLOBALS['cfgRelation']['relwork']) { 747 $table_query = 'UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($GLOBALS['cfgRelation']['relation']) 748 . ' SET foreign_table = \'' . PMA_sqlAddslashes($target_table) . '\',' 749 . ' foreign_db = \'' . PMA_sqlAddslashes($target_db) . '\'' 750 . ' WHERE foreign_db = \'' . PMA_sqlAddslashes($source_db) . '\'' 751 . ' AND foreign_table = \'' . PMA_sqlAddslashes($source_table) . '\''; 752 PMA_query_as_cu($table_query); 753 unset($table_query); 754 755 $table_query = 'UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($GLOBALS['cfgRelation']['relation']) 756 . ' SET master_table = \'' . PMA_sqlAddslashes($target_table) . '\',' 757 . ' master_db = \'' . PMA_sqlAddslashes($target_db) . '\'' 758 . ' WHERE master_db = \'' . PMA_sqlAddslashes($source_db) . '\'' 759 . ' AND master_table = \'' . PMA_sqlAddslashes($source_table) . '\''; 760 PMA_query_as_cu($table_query); 761 unset($table_query); 762 } 763 764 /** 765 * @todo garvin: Can't get moving PDFs the right way. The page numbers 766 * always get screwed up independently from duplication because the 767 * numbers do not seem to be stored on a per-database basis. Would 768 * the author of pdf support please have a look at it? 769 */ 770 771 if ($GLOBALS['cfgRelation']['pdfwork']) { 772 $table_query = 'UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($GLOBALS['cfgRelation']['table_coords']) 773 . ' SET table_name = \'' . PMA_sqlAddslashes($target_table) . '\',' 774 . ' db_name = \'' . PMA_sqlAddslashes($target_db) . '\'' 775 . ' WHERE db_name = \'' . PMA_sqlAddslashes($source_db) . '\'' 776 . ' AND table_name = \'' . PMA_sqlAddslashes($source_table) . '\''; 777 PMA_query_as_cu($table_query); 778 unset($table_query); 779 /* 780 $pdf_query = 'SELECT pdf_page_number ' 781 . ' FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($GLOBALS['cfgRelation']['table_coords']) 782 . ' WHERE db_name = \'' . PMA_sqlAddslashes($target_db) . '\'' 783 . ' AND table_name = \'' . PMA_sqlAddslashes($target_table) . '\''; 784 $pdf_rs = PMA_query_as_cu($pdf_query); 785 786 while ($pdf_copy_row = PMA_DBI_fetch_assoc($pdf_rs)) { 787 $table_query = 'UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($GLOBALS['cfgRelation']['pdf_pages']) 788 . ' SET db_name = \'' . PMA_sqlAddslashes($target_db) . '\'' 789 . ' WHERE db_name = \'' . PMA_sqlAddslashes($source_db) . '\'' 790 . ' AND page_nr = \'' . PMA_sqlAddslashes($pdf_copy_row['pdf_page_number']) . '\''; 791 $tb_rs = PMA_query_as_cu($table_query); 792 unset($table_query); 793 unset($tb_rs); 794 } 795 */ 796 } 797 798 $GLOBALS['sql_query'] .= "\n\n" . $sql_drop_query . ';'; 799 } else { 800 // garvin: Create new entries as duplicates from old PMA DBs 801 if ($what != 'dataonly' && !isset($maintain_relations)) { 802 if ($GLOBALS['cfgRelation']['commwork']) { 803 // Get all comments and MIME-Types for current table 804 $comments_copy_query = 'SELECT 805 column_name, ' . PMA_backquote('comment') . ($GLOBALS['cfgRelation']['mimework'] ? ', mimetype, transformation, transformation_options' : '') . ' 806 FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($GLOBALS['cfgRelation']['column_info']) . ' 807 WHERE 808 db_name = \'' . PMA_sqlAddslashes($source_db) . '\' AND 809 table_name = \'' . PMA_sqlAddslashes($source_table) . '\''; 810 $comments_copy_rs = PMA_query_as_cu($comments_copy_query); 811 812 // Write every comment as new copied entry. [MIME] 813 while ($comments_copy_row = PMA_DBI_fetch_assoc($comments_copy_rs)) { 814 $new_comment_query = 'REPLACE INTO ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($GLOBALS['cfgRelation']['column_info']) 815 . ' (db_name, table_name, column_name, ' . PMA_backquote('comment') . ($GLOBALS['cfgRelation']['mimework'] ? ', mimetype, transformation, transformation_options' : '') . ') ' 816 . ' VALUES(' 817 . '\'' . PMA_sqlAddslashes($target_db) . '\',' 818 . '\'' . PMA_sqlAddslashes($target_table) . '\',' 819 . '\'' . PMA_sqlAddslashes($comments_copy_row['column_name']) . '\'' 820 . ($GLOBALS['cfgRelation']['mimework'] ? ',\'' . PMA_sqlAddslashes($comments_copy_row['comment']) . '\',' 821 . '\'' . PMA_sqlAddslashes($comments_copy_row['mimetype']) . '\',' 822 . '\'' . PMA_sqlAddslashes($comments_copy_row['transformation']) . '\',' 823 . '\'' . PMA_sqlAddslashes($comments_copy_row['transformation_options']) . '\'' : '') 824 . ')'; 825 PMA_query_as_cu($new_comment_query); 826 } // end while 827 PMA_DBI_free_result($comments_copy_rs); 828 unset($comments_copy_rs); 829 } 830 831 // duplicating the bookmarks must not be done here, but 832 // just once per db 833 834 $get_fields = array('display_field'); 835 $where_fields = array('db_name' => $source_db, 'table_name' => $source_table); 836 $new_fields = array('db_name' => $target_db, 'table_name' => $target_table); 837 PMA_Table::duplicateInfo('displaywork', 'table_info', $get_fields, $where_fields, $new_fields); 838 839 $get_fields = array('master_field', 'foreign_db', 'foreign_table', 'foreign_field'); 840 $where_fields = array('master_db' => $source_db, 'master_table' => $source_table); 841 $new_fields = array('master_db' => $target_db, 'master_table' => $target_table); 842 PMA_Table::duplicateInfo('relwork', 'relation', $get_fields, $where_fields, $new_fields); 843 844 $get_fields = array('foreign_field', 'master_db', 'master_table', 'master_field'); 845 $where_fields = array('foreign_db' => $source_db, 'foreign_table' => $source_table); 846 $new_fields = array('foreign_db' => $target_db, 'foreign_table' => $target_table); 847 PMA_Table::duplicateInfo('relwork', 'relation', $get_fields, $where_fields, $new_fields); 848 849 /** 850 * @todo garvin: Can't get duplicating PDFs the right way. The 851 * page numbers always get screwed up independently from 852 * duplication because the numbers do not seem to be stored on a 853 * per-database basis. Would the author of pdf support please 854 * have a look at it? 855 * 856 $get_fields = array('page_descr'); 857 $where_fields = array('db_name' => $source_db); 858 $new_fields = array('db_name' => $target_db); 859 $last_id = PMA_Table::duplicateInfo('pdfwork', 'pdf_pages', $get_fields, $where_fields, $new_fields); 860 861 if (isset($last_id) && $last_id >= 0) { 862 $get_fields = array('x', 'y'); 863 $where_fields = array('db_name' => $source_db, 'table_name' => $source_table); 864 $new_fields = array('db_name' => $target_db, 'table_name' => $target_table, 'pdf_page_number' => $last_id); 865 PMA_Table::duplicateInfo('pdfwork', 'table_coords', $get_fields, $where_fields, $new_fields); 866 } 867 */ 868 } 869 } 870 871 } 872 873 /** 874 * checks if given name is a valid table name, 875 * currently if not empty, trailing spaces, '.', '/' and '\' 876 * 877 * @todo add check for valid chars in filename on current system/os 878 * @see http://dev.mysql.com/doc/refman/5.0/en/legal-names.html 879 * @param string $table_name name to check 880 * @return boolean whether the string is valid or not 881 */ 882 function isValidName($table_name) 883 { 884 if ($table_name !== trim($table_name)) { 885 // trailing spaces 886 return false; 887 } 888 889 if (! strlen($table_name)) { 890 // zero length 891 return false; 892 } 893 894 if (preg_match('/[.\/\\\\]+/i', $table_name)) { 895 // illegal char . / \ 896 return false; 897 } 898 899 return true; 900 } 901 902 /** 903 * renames table 904 * 905 * @param string new table name 906 * @param string new database name 907 * @return boolean success 908 */ 909 function rename($new_name, $new_db = null) 910 { 911 if (null !== $new_db && $new_db !== $this->getDbName()) { 912 // Ensure the target is valid 913 if (! $GLOBALS['PMA_List_Database']->exists($new_db)) { 914 $this->errors[] = $GLOBALS['strInvalidDatabase'] . ': ' . $new_db; 915 return false; 916 } 917 } else { 918 $new_db = $this->getDbName(); 919 } 920 921 $new_table = new PMA_Table($new_name, $new_db); 922 923 if ($this->getFullName() === $new_table->getFullName()) { 924 return true; 925 } 926 927 if (! PMA_Table::isValidName($new_name)) { 928 $this->errors[] = $GLOBALS['strInvalidTableName'] . ': ' . $new_table->getFullName(); 929 return false; 930 } 931 932 $GLOBALS['sql_query'] = ' 933 RENAME TABLE ' . $this->getFullName(true) . ' 934 TO ' . $new_table->getFullName(true) . ';'; 935 if (! PMA_DBI_query($GLOBALS['sql_query'])) { 936 $this->errors[] = sprintf($GLOBALS['strErrorRenamingTable'], $this->getFullName(), $new_table->getFullName()); 937 return false; 938 } 939 940 $old_name = $this->getName(); 941 $old_db = $this->getDbName(); 942 $this->setName($new_name); 943 $this->setDbName($new_db); 944 945 /** 946 * @todo move into extra function PMA_Relation::renameTable($new_name, $old_name, $new_db, $old_db) 947 */ 948 // garvin: Move old entries from comments to new table 949 require_once './libraries/relation.lib.php'; 950 $GLOBALS['cfgRelation'] = PMA_getRelationsParam(); 951 if ($GLOBALS['cfgRelation']['commwork']) { 952 $remove_query = ' 953 UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' 954 . PMA_backquote($GLOBALS['cfgRelation']['column_info']) . ' 955 SET `db_name` = \'' . PMA_sqlAddslashes($new_db) . '\', 956 `table_name` = \'' . PMA_sqlAddslashes($new_name) . '\' 957 WHERE `db_name` = \'' . PMA_sqlAddslashes($old_db) . '\' 958 AND `table_name` = \'' . PMA_sqlAddslashes($old_name) . '\''; 959 PMA_query_as_cu($remove_query); 960 unset($remove_query); 961 } 962 963 if ($GLOBALS['cfgRelation']['displaywork']) { 964 $table_query = ' 965 UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' 966 . PMA_backquote($GLOBALS['cfgRelation']['table_info']) . ' 967 SET `db_name` = \'' . PMA_sqlAddslashes($new_db) . '\', 968 `table_name` = \'' . PMA_sqlAddslashes($new_name) . '\' 969 WHERE `db_name` = \'' . PMA_sqlAddslashes($old_db) . '\' 970 AND `table_name` = \'' . PMA_sqlAddslashes($old_name) . '\''; 971 PMA_query_as_cu($table_query); 972 unset($table_query); 973 } 974 975 if ($GLOBALS['cfgRelation']['relwork']) { 976 $table_query = ' 977 UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' 978 . PMA_backquote($GLOBALS['cfgRelation']['relation']) . ' 979 SET `foreign_db` = \'' . PMA_sqlAddslashes($new_db) . '\', 980 `foreign_table` = \'' . PMA_sqlAddslashes($new_name) . '\' 981 WHERE `foreign_db` = \'' . PMA_sqlAddslashes($old_db) . '\' 982 AND `foreign_table` = \'' . PMA_sqlAddslashes($old_name) . '\''; 983 PMA_query_as_cu($table_query); 984 985 $table_query = ' 986 UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' 987 . PMA_backquote($GLOBALS['cfgRelation']['relation']) . ' 988 SET `master_db` = \'' . PMA_sqlAddslashes($new_db) . '\', 989 `master_table` = \'' . PMA_sqlAddslashes($new_name) . '\' 990 WHERE `master_db` = \'' . PMA_sqlAddslashes($old_db) . '\' 991 AND `master_table` = \'' . PMA_sqlAddslashes($old_name) . '\''; 992 PMA_query_as_cu($table_query); 993 unset($table_query); 994 } 995 996 if ($GLOBALS['cfgRelation']['pdfwork']) { 997 $table_query = ' 998 UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' 999 . PMA_backquote($GLOBALS['cfgRelation']['table_coords']) . ' 1000 SET `db_name` = \'' . PMA_sqlAddslashes($new_db) . '\', 1001 `table_name` = \'' . PMA_sqlAddslashes($new_name) . '\' 1002 WHERE `db_name` = \'' . PMA_sqlAddslashes($old_db) . '\' 1003 AND `table_name` = \'' . PMA_sqlAddslashes($old_name) . '\''; 1004 PMA_query_as_cu($table_query); 1005 unset($table_query); 1006 } 1007 1008 $this->messages[] = sprintf($GLOBALS['strRenameTableOK'], 1009 htmlspecialchars($old_name), htmlspecialchars($new_name)); 1010 return true; 1011 } 1012 } 1013 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Mon Nov 26 15:18:20 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |