[ Index ]
 

Code source de phpMyAdmin 2.10.3

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/libraries/ -> Table.class.php (source)

   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 '&nbsp;'
 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  ?>


Généré le : Mon Nov 26 15:18:20 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics