home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / phpMyAdmin / libraries / export / sql.php < prev    next >
Encoding:
PHP Script  |  2008-06-23  |  39.3 KB  |  992 lines

  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4.  * Set of functions used to build SQL dumps of tables
  5.  *
  6.  * @version $Id: sql.php 11326 2008-06-17 21:32:48Z lem9 $
  7.  */
  8. if (! defined('PHPMYADMIN')) {
  9.     exit;
  10. }
  11.  
  12. /**
  13.  *
  14.  */
  15. if (isset($plugin_list)) {
  16.     $hide_sql       = false;
  17.     $hide_structure = false;
  18.     if ($plugin_param['export_type'] == 'table' && !$plugin_param['single_table']) {
  19.         $hide_structure = true;
  20.         $hide_sql       = true;
  21.     }
  22.     if (!$hide_sql) {
  23.         $plugin_list['sql'] = array(
  24.             'text' => 'strSQL',
  25.             'extension' => 'sql',
  26.             'mime_type' => 'text/x-sql',
  27.             'options' => array(
  28.                 array('type' => 'text', 'name' => 'header_comment', 'text' => 'strAddHeaderComment'),
  29.                 array('type' => 'bool', 'name' => 'use_transaction', 'text' => 'strEncloseInTransaction'),
  30.                 array('type' => 'bool', 'name' => 'disable_fk', 'text' => 'strDisableForeignChecks'),
  31.                 ),
  32.             'options_text' => 'strOptions',
  33.             );
  34.         $compats = PMA_DBI_getCompatibilities();
  35.         if (count($compats) > 0) {
  36.             $values = array();
  37.             foreach($compats as $val) {
  38.                 $values[$val] = $val;
  39.             }
  40.             $plugin_list['sql']['options'][] =
  41.                 array('type' => 'select', 'name' => 'compatibility', 'text' => 'strSQLCompatibility', 'values' => $values, 'doc' => array('manual_MySQL_Database_Administration', 'Server_SQL_mode'));
  42.             unset($values);
  43.         }
  44.  
  45.         /* Server export options */
  46.         if ($plugin_param['export_type'] == 'server') {
  47.             $plugin_list['sql']['options'][] =
  48.                 array('type' => 'bgroup', 'text' => 'strDatabaseExportOptions');
  49.             $plugin_list['sql']['options'][] =
  50.                 array('type' => 'bool', 'name' => 'drop_database', 'text' => sprintf($GLOBALS['strAddClause'], 'DROP DATABASE'));
  51.             $plugin_list['sql']['options'][] =
  52.                 array('type' => 'egroup');
  53.         }
  54.  
  55.         /* Structure options */
  56.         if (!$hide_structure) {
  57.             $plugin_list['sql']['options'][] =
  58.                 array('type' => 'bgroup', 'name' => 'structure', 'text' => 'strStructure', 'force' => 'data');
  59.             if ($plugin_param['export_type'] == 'table') {
  60.                 if (PMA_Table::_isView($GLOBALS['db'], $GLOBALS['table'])) {
  61.                     $drop_clause = 'DROP VIEW';
  62.                 } else {
  63.                     $drop_clause = 'DROP TABLE';
  64.                 }
  65.             } elseif (PMA_MYSQL_INT_VERSION >= 50000) {
  66.                 $drop_clause = 'DROP TABLE / VIEW / PROCEDURE / FUNCTION';
  67.             } else {
  68.                 $drop_clause = 'DROP TABLE';
  69.             }
  70.             $plugin_list['sql']['options'][] =
  71.                 array('type' => 'bool', 'name' => 'drop_table', 'text' => sprintf($GLOBALS['strAddClause'], $drop_clause));
  72.             $plugin_list['sql']['options'][] =
  73.                 array('type' => 'bool', 'name' => 'if_not_exists', 'text' => sprintf($GLOBALS['strAddClause'], 'IF NOT EXISTS'));
  74.             $plugin_list['sql']['options'][] =
  75.                 array('type' => 'bool', 'name' => 'auto_increment', 'text' => 'strAddAutoIncrement');
  76.             $plugin_list['sql']['options'][] =
  77.                 array('type' => 'bool', 'name' => 'backquotes', 'text' => 'strUseBackquotes');
  78.             $plugin_list['sql']['options'][] =
  79.                 array('type' => 'bool', 'name' => 'procedure_function', 'text' => sprintf($GLOBALS['strAddClause'], 'CREATE PROCEDURE / FUNCTION'));
  80.  
  81.             /* MIME stuff etc. */
  82.             $plugin_list['sql']['options'][] =
  83.                 array('type' => 'bgroup', 'text' => 'strAddIntoComments');
  84.             $plugin_list['sql']['options'][] =
  85.                 array('type' => 'bool', 'name' => 'dates', 'text' => 'strCreationDates');
  86.             if (!empty($GLOBALS['cfgRelation']['relation'])) {
  87.                 $plugin_list['sql']['options'][] =
  88.                     array('type' => 'bool', 'name' => 'relation', 'text' => 'strRelations');
  89.             }
  90.             if (!empty($GLOBALS['cfgRelation']['commwork']) && PMA_MYSQL_INT_VERSION < 40100) {
  91.                 $plugin_list['sql']['options'][] =
  92.                     array('type' => 'bool', 'name' => 'comments', 'text' => 'strComments');
  93.             }
  94.             if (!empty($GLOBALS['cfgRelation']['mimework'])) {
  95.                 $plugin_list['sql']['options'][] =
  96.                     array('type' => 'bool', 'name' => 'mime', 'text' => 'strMIME_MIMEtype');
  97.             }
  98.             $plugin_list['sql']['options'][] =
  99.                 array('type' => 'egroup');
  100.  
  101.             $plugin_list['sql']['options'][] =
  102.                 array('type' => 'egroup');
  103.         }
  104.  
  105.         /* Data */
  106.         $plugin_list['sql']['options'][] =
  107.             array('type' => 'bgroup', 'name' => 'data', 'text' => 'strData', 'force' => 'structure');
  108.         $plugin_list['sql']['options'][] =
  109.             array('type' => 'bool', 'name' => 'columns', 'text' => 'strCompleteInserts');
  110.         $plugin_list['sql']['options'][] =
  111.             array('type' => 'bool', 'name' => 'extended', 'text' => 'strExtendedInserts');
  112.         $plugin_list['sql']['options'][] =
  113.             array('type' => 'text', 'name' => 'max_query_size', 'text' => 'strMaximalQueryLength');
  114.         $plugin_list['sql']['options'][] =
  115.             array('type' => 'bool', 'name' => 'delayed', 'text' => 'strDelayedInserts');
  116.         $plugin_list['sql']['options'][] =
  117.             array('type' => 'bool', 'name' => 'ignore', 'text' => 'strIgnoreInserts');
  118.         $plugin_list['sql']['options'][] =
  119.             array('type' => 'bool', 'name' => 'hex_for_blob', 'text' => 'strHexForBLOB');
  120.         $plugin_list['sql']['options'][] =
  121.             array('type' => 'select', 'name' => 'type', 'text' => 'strSQLExportType', 'values' => array('INSERT', 'UPDATE', 'REPLACE'));
  122.         $plugin_list['sql']['options'][] =
  123.             array('type' => 'egroup');
  124.     }
  125. } else {
  126.  
  127. /**
  128.  * Avoids undefined variables, use NULL so isset() returns false
  129.  */
  130. if (! isset($sql_backquotes)) {
  131.     $sql_backquotes = null;
  132. }
  133.  
  134. /**
  135.  * Outputs comment
  136.  *
  137.  * @param   string      Text of comment
  138.  *
  139.  * @return  string      The formatted comment 
  140.  */
  141. function PMA_exportComment($text = '')
  142. {
  143.     // see http://dev.mysql.com/doc/refman/5.0/en/ansi-diff-comments.html
  144.     return '--' . (empty($text) ? '' : ' ') . $text . $GLOBALS['crlf'];
  145. }
  146.  
  147. /**
  148.  * Outputs export footer
  149.  *
  150.  * @return  bool        Whether it suceeded
  151.  *
  152.  * @access  public
  153.  */
  154. function PMA_exportFooter()
  155. {
  156.     global $crlf;
  157.     global $mysql_charset_map;
  158.  
  159.     $foot = '';
  160.  
  161.     if (isset($GLOBALS['sql_disable_fk'])) {
  162.         $foot .=  $crlf . 'SET FOREIGN_KEY_CHECKS=1;' . $crlf;
  163.     }
  164.  
  165.     if (isset($GLOBALS['sql_use_transaction'])) {
  166.         $foot .=  $crlf . 'COMMIT;' . $crlf;
  167.     }
  168.  
  169.     // restore connection settings
  170.     // (not set if $cfg['AllowAnywhereRecoding'] is false)
  171.     $charset_of_file = isset($GLOBALS['charset_of_file']) ? $GLOBALS['charset_of_file'] : '';
  172.     if (!empty($GLOBALS['asfile']) && isset($mysql_charset_map[$charset_of_file])) {
  173.         $foot .=  $crlf
  174.                . '/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;' . $crlf
  175.                . '/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;' . $crlf
  176.                . '/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;' . $crlf;
  177.     }
  178.  
  179.     return PMA_exportOutputHandler($foot);
  180. }
  181.  
  182. /**
  183.  * Outputs export header
  184.  *
  185.  * @return  bool        Whether it suceeded
  186.  *
  187.  * @access  public
  188.  */
  189. function PMA_exportHeader()
  190. {
  191.     global $crlf;
  192.     global $cfg;
  193.     global $mysql_charset_map;
  194.  
  195.     if (PMA_MYSQL_INT_VERSION >= 40100 && isset($GLOBALS['sql_compatibility']) && $GLOBALS['sql_compatibility'] != 'NONE') {
  196.         PMA_DBI_try_query('SET SQL_MODE="' . $GLOBALS['sql_compatibility'] . '"');
  197.     }
  198.     $head  =  PMA_exportComment('phpMyAdmin SQL Dump')
  199.            .  PMA_exportComment('version ' . PMA_VERSION)
  200.            .  PMA_exportComment('http://www.phpmyadmin.net')
  201.            .  PMA_exportComment();
  202.     $head .= empty($cfg['Server']['port']) ? PMA_exportComment($GLOBALS['strHost'] . ': ' . $cfg['Server']['host']) : PMA_exportComment($GLOBALS['strHost'] . ': ' .  $cfg['Server']['host'] . ':' . $cfg['Server']['port']);
  203.     $head .=  PMA_exportComment($GLOBALS['strGenTime']
  204.            . ': ' .  PMA_localisedDate())
  205.            .  PMA_exportComment($GLOBALS['strServerVersion'] . ': ' . substr(PMA_MYSQL_INT_VERSION, 0, 1) . '.' . (int) substr(PMA_MYSQL_INT_VERSION, 1, 2) . '.' . (int) substr(PMA_MYSQL_INT_VERSION, 3))
  206.            .  PMA_exportComment($GLOBALS['strPHPVersion'] . ': ' . phpversion());
  207.  
  208.     if (isset($GLOBALS['sql_header_comment']) && !empty($GLOBALS['sql_header_comment'])) {
  209.         // '\n' is not a newline (like "\n" would be), it's the characters
  210.         // backslash and n, as explained on the export interface
  211.         $lines = explode('\n', $GLOBALS['sql_header_comment']);
  212.         $head .= PMA_exportComment();
  213.         foreach($lines as $one_line) {
  214.             $head .= PMA_exportComment($one_line);
  215.         } 
  216.         $head .= PMA_exportComment();
  217.     }
  218.  
  219.     if (isset($GLOBALS['sql_disable_fk'])) {
  220.         $head .=  $crlf . 'SET FOREIGN_KEY_CHECKS=0;' . $crlf;
  221.     }
  222.  
  223.     /* We want exported AUTO_INCREMENT fields to have still same value, do this only for recent MySQL exports */
  224.     if (!isset($GLOBALS['sql_compatibility']) || $GLOBALS['sql_compatibility'] == 'NONE') {
  225.         $head .=  $crlf . (PMA_MYSQL_INT_VERSION >= 40101 ? 'SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";' . $crlf : ''); 
  226.     }
  227.  
  228.     if (isset($GLOBALS['sql_use_transaction'])) {
  229.         $head .=  $crlf .'SET AUTOCOMMIT=0;' . $crlf
  230.                 . 'START TRANSACTION;' . $crlf;
  231.     }
  232.  
  233.     $head .= $crlf;
  234.  
  235.     if (! empty($GLOBALS['asfile'])) {
  236.         // we are saving as file, therefore we provide charset information
  237.         // so that a utility like the mysql client can interpret
  238.         // the file correctly 
  239.         if (isset($GLOBALS['charset_of_file']) && isset($mysql_charset_map[$GLOBALS['charset_of_file']])) {
  240.             // $cfg['AllowAnywhereRecoding'] was true so we got a charset from 
  241.             // the export dialog
  242.             $set_names = $mysql_charset_map[$GLOBALS['charset_of_file']];
  243.         } else {
  244.             // by default we use the connection charset
  245.             $set_names = $mysql_charset_map[$GLOBALS['charset']]; 
  246.         } 
  247.         $head .=  $crlf
  248.                . '/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;' . $crlf
  249.                . '/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;' . $crlf
  250.                . '/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;' . $crlf
  251.                . '/*!40101 SET NAMES ' . $set_names . ' */;' . $crlf . $crlf;
  252.     }
  253.  
  254.     return PMA_exportOutputHandler($head);
  255. }
  256.  
  257. /**
  258.  * Outputs CREATE DATABASE database
  259.  *
  260.  * @param   string      Database name
  261.  *
  262.  * @return  bool        Whether it suceeded
  263.  *
  264.  * @access  public
  265.  */
  266. function PMA_exportDBCreate($db)
  267. {
  268.     global $crlf;
  269.     if (isset($GLOBALS['sql_drop_database'])) {
  270.         if (!PMA_exportOutputHandler('DROP DATABASE ' . (isset($GLOBALS['sql_backquotes']) ? PMA_backquote($db) : $db) . ';' . $crlf)) {
  271.             return FALSE;
  272.         }
  273.     }
  274.     $create_query = 'CREATE DATABASE ' . (isset($GLOBALS['sql_backquotes']) ? PMA_backquote($db) : $db);
  275.     if (PMA_MYSQL_INT_VERSION >= 40101) {
  276.         $collation = PMA_getDbCollation($db);
  277.         if (strpos($collation, '_')) {
  278.             $create_query .= ' DEFAULT CHARACTER SET ' . substr($collation, 0, strpos($collation, '_')) . ' COLLATE ' . $collation;
  279.         } else {
  280.             $create_query .= ' DEFAULT CHARACTER SET ' . $collation;
  281.         }
  282.     }
  283.     $create_query .= ';' . $crlf;
  284.     if (!PMA_exportOutputHandler($create_query)) {
  285.         return FALSE;
  286.     }
  287.     if (isset($GLOBALS['sql_backquotes']) && PMA_MYSQL_INT_VERSION >= 40100 && isset($GLOBALS['sql_compatibility']) && $GLOBALS['sql_compatibility'] == 'NONE') {
  288.         return PMA_exportOutputHandler('USE ' . PMA_backquote($db) . ';' . $crlf);
  289.     }
  290.     return PMA_exportOutputHandler('USE ' . $db . ';' . $crlf);
  291. }
  292.  
  293. /**
  294.  * Outputs database header
  295.  *
  296.  * @param   string      Database name
  297.  *
  298.  * @return  bool        Whether it suceeded
  299.  *
  300.  * @access  public
  301.  */
  302. function PMA_exportDBHeader($db)
  303. {
  304.     $head = PMA_exportComment() 
  305.           . PMA_exportComment($GLOBALS['strDatabase'] . ': ' . (isset($GLOBALS['sql_backquotes']) ? PMA_backquote($db) : '\'' . $db . '\''))
  306.           . PMA_exportComment();
  307.     return PMA_exportOutputHandler($head);
  308. }
  309.  
  310. /**
  311.  * Outputs database footer
  312.  *
  313.  * @param   string      Database name
  314.  *
  315.  * @return  bool        Whether it suceeded
  316.  *
  317.  * @access  public
  318.  */
  319. function PMA_exportDBFooter($db)
  320. {
  321.     global $crlf;
  322.  
  323.     $result = TRUE;
  324.     if (isset($GLOBALS['sql_constraints'])) {
  325.         $result = PMA_exportOutputHandler($GLOBALS['sql_constraints']);
  326.         unset($GLOBALS['sql_constraints']);
  327.     }
  328.  
  329.     if (PMA_MYSQL_INT_VERSION >= 50000 && isset($GLOBALS['sql_structure']) && isset($GLOBALS['sql_procedure_function'])) {
  330.         $procs_funcs = '';
  331.         $delimiter = '$$';
  332.  
  333.         $procedure_names = PMA_DBI_get_procedures_or_functions($db, 'PROCEDURE');
  334.         $function_names = PMA_DBI_get_procedures_or_functions($db, 'FUNCTION');
  335.  
  336.         if ($procedure_names || $function_names) {
  337.             $procs_funcs .= $crlf
  338.               . 'DELIMITER ' . $delimiter . $crlf;
  339.         }
  340.  
  341.         if ($procedure_names) {
  342.             $procs_funcs .= 
  343.                 PMA_exportComment() 
  344.               . PMA_exportComment($GLOBALS['strProcedures'])
  345.               . PMA_exportComment();
  346.  
  347.             foreach($procedure_names as $procedure_name) {
  348.                 if (! empty($GLOBALS['sql_drop_table'])) {
  349.             $procs_funcs .= 'DROP PROCEDURE ' . PMA_backquote($procedure_name) . $delimiter . $crlf;
  350.                 }    
  351.                 $procs_funcs .= PMA_DBI_get_procedure_or_function_def($db, 'PROCEDURE', $procedure_name) . $delimiter . $crlf . $crlf;
  352.             }
  353.         }
  354.  
  355.         if ($function_names) {
  356.             $procs_funcs .= 
  357.                 PMA_exportComment()
  358.               . PMA_exportComment($GLOBALS['strFunctions'])
  359.               . PMA_exportComment();
  360.  
  361.             foreach($function_names as $function_name) {
  362.                 if (! empty($GLOBALS['sql_drop_table'])) {
  363.             $procs_funcs .= 'DROP FUNCTION ' . PMA_backquote($function_name) . $delimiter . $crlf;
  364.                 }    
  365.                 $procs_funcs .= PMA_DBI_get_procedure_or_function_def($db, 'FUNCTION', $function_name) . $delimiter . $crlf . $crlf;
  366.             }
  367.         }
  368.  
  369.         if ($procedure_names || $function_names) {
  370.             $procs_funcs .= 'DELIMITER ;' . $crlf;
  371.         }
  372.  
  373.         if (!empty($procs_funcs)) {
  374.             $result = PMA_exportOutputHandler($procs_funcs);
  375.         }
  376.     }
  377.     return $result;
  378. }
  379.  
  380.  
  381. /**
  382.  * Returns a stand-in CREATE definition to resolve view dependencies
  383.  *
  384.  * @param   string   the database name
  385.  * @param   string   the vew name
  386.  * @param   string   the end of line sequence
  387.  *
  388.  * @return  string   resulting definition
  389.  *
  390.  * @access  public
  391.  */
  392. function PMA_getTableDefStandIn($db, $view, $crlf) {
  393.  
  394.     $create_query = '';
  395.     if (! empty($GLOBALS['sql_drop_table'])) {
  396.         $create_query .= 'DROP VIEW IF EXISTS ' . PMA_backquote($view) . ';' . $crlf;
  397.     }
  398.  
  399.     $create_query .= 'CREATE TABLE ';
  400.     if (isset($GLOBALS['sql_if_not_exists']) && $GLOBALS['sql_if_not_exists']) {
  401.         $create_query .= 'IF NOT EXISTS ';
  402.     }
  403.     $create_query .= PMA_backquote($view) . ' (' . $crlf;
  404.     $tmp = array();
  405.     $columns = PMA_DBI_get_columns_full($db, $view);
  406.     foreach($columns as $column_name => $definition) {
  407.         $tmp[] = PMA_backquote($column_name) . ' ' . $definition['Type'] . $crlf;
  408.     }
  409.     $create_query .= implode(',', $tmp) . ');';
  410.     return($create_query);
  411. }
  412.  
  413. /**
  414.  * Returns $table's CREATE definition
  415.  *
  416.  * @param   string   the database name
  417.  * @param   string   the table name
  418.  * @param   string   the end of line sequence
  419.  * @param   string   the url to go back in case of error
  420.  * @param   boolean  whether to include creation/update/check dates
  421.  *
  422.  * @return  string   resulting schema
  423.  *
  424.  * @global  boolean  whether to add 'drop' statements or not
  425.  * @global  boolean  whether to use backquotes to allow the use of special
  426.  *                   characters in database, table and fields names or not
  427.  *
  428.  * @access  public
  429.  */
  430. function PMA_getTableDef($db, $table, $crlf, $error_url, $show_dates = false)
  431. {
  432.     global $sql_drop_table;
  433.     global $sql_backquotes;
  434.     global $cfgRelation;
  435.     global $sql_constraints;
  436.     global $sql_constraints_query; // just the text of the query
  437.  
  438.     $schema_create = '';
  439.     $auto_increment = '';
  440.     $new_crlf = $crlf;
  441.  
  442.     // need to use PMA_DBI_QUERY_STORE with PMA_DBI_num_rows() in mysqli
  443.     $result = PMA_DBI_query('SHOW TABLE STATUS FROM ' . PMA_backquote($db) . ' LIKE \'' . PMA_sqlAddslashes($table) . '\'', null, PMA_DBI_QUERY_STORE);
  444.     if ($result != FALSE) {
  445.         if (PMA_DBI_num_rows($result) > 0) {
  446.             $tmpres        = PMA_DBI_fetch_assoc($result);
  447.             // Here we optionally add the AUTO_INCREMENT next value,
  448.             // but starting with MySQL 5.0.24, the clause is already included
  449.             // in SHOW CREATE TABLE so we'll remove it below
  450.             if (isset($GLOBALS['sql_auto_increment']) && !empty($tmpres['Auto_increment'])) {
  451.                 $auto_increment .= ' AUTO_INCREMENT=' . $tmpres['Auto_increment'] . ' ';
  452.             }
  453.  
  454.             if ($show_dates && isset($tmpres['Create_time']) && !empty($tmpres['Create_time'])) {
  455.                 $schema_create .= PMA_exportComment($GLOBALS['strStatCreateTime'] . ': ' . PMA_localisedDate(strtotime($tmpres['Create_time'])));
  456.                 $new_crlf = PMA_exportComment() . $crlf;
  457.             }
  458.  
  459.             if ($show_dates && isset($tmpres['Update_time']) && !empty($tmpres['Update_time'])) {
  460.                 $schema_create .= PMA_exportComment($GLOBALS['strStatUpdateTime'] . ': ' . PMA_localisedDate(strtotime($tmpres['Update_time'])));
  461.                 $new_crlf = PMA_exportComment() . $crlf;
  462.             }
  463.  
  464.             if ($show_dates && isset($tmpres['Check_time']) && !empty($tmpres['Check_time'])) {
  465.                 $schema_create .= PMA_exportComment($GLOBALS['strStatCheckTime'] . ': ' . PMA_localisedDate(strtotime($tmpres['Check_time'])));
  466.                 $new_crlf = PMA_exportComment() . $crlf;
  467.             }
  468.         }
  469.         PMA_DBI_free_result($result);
  470.     }
  471.  
  472.     $schema_create .= $new_crlf;
  473.  
  474.     // no need to generate a DROP VIEW here, it was done earlier
  475.     if (! empty($sql_drop_table) && ! PMA_Table::isView($db,$table)) {
  476.         $schema_create .= 'DROP TABLE IF EXISTS ' . PMA_backquote($table, $sql_backquotes) . ';' . $crlf;
  477.     }
  478.  
  479.     // Steve Alberty's patch for complete table dump,
  480.     // Whether to quote table and fields names or not
  481.     if ($sql_backquotes) {
  482.         PMA_DBI_query('SET SQL_QUOTE_SHOW_CREATE = 1');
  483.     } else {
  484.         PMA_DBI_query('SET SQL_QUOTE_SHOW_CREATE = 0');
  485.     }
  486.  
  487.     // I don't see the reason why this unbuffered query could cause problems,
  488.     // because SHOW CREATE TABLE returns only one row, and we free the
  489.     // results below. Nonetheless, we got 2 user reports about this
  490.     // (see bug 1562533) so I remove the unbuffered mode.
  491.     //$result = PMA_DBI_query('SHOW CREATE TABLE ' . PMA_backquote($db) . '.' . PMA_backquote($table), null, PMA_DBI_QUERY_UNBUFFERED);
  492.     //
  493.     // Note: SHOW CREATE TABLE, at least in MySQL 5.1.23, does not
  494.     // produce a displayable result for the default value of a BIT
  495.     // field, nor does the mysqldump command. See MySQL bug 35796 
  496.     $result = PMA_DBI_query('SHOW CREATE TABLE ' . PMA_backquote($db) . '.' . PMA_backquote($table));
  497.     if ($result != FALSE && ($row = PMA_DBI_fetch_row($result))) {
  498.         $create_query = $row[1];
  499.         unset($row);
  500.  
  501.         // Convert end of line chars to one that we want (note that MySQL doesn't return query it will accept in all cases)
  502.         if (strpos($create_query, "(\r\n ")) {
  503.             $create_query = str_replace("\r\n", $crlf, $create_query);
  504.         } elseif (strpos($create_query, "(\n ")) {
  505.             $create_query = str_replace("\n", $crlf, $create_query);
  506.         } elseif (strpos($create_query, "(\r ")) {
  507.             $create_query = str_replace("\r", $crlf, $create_query);
  508.         }
  509.  
  510.         // Should we use IF NOT EXISTS?
  511.         if (isset($GLOBALS['sql_if_not_exists'])) {
  512.             $create_query     = preg_replace('/^CREATE TABLE/', 'CREATE TABLE IF NOT EXISTS', $create_query);
  513.         }
  514.  
  515.         // are there any constraints to cut out?
  516.         if (preg_match('@CONSTRAINT|FOREIGN[\s]+KEY@', $create_query)) {
  517.  
  518.             // Split the query into lines, so we can easily handle it. We know lines are separated by $crlf (done few lines above).
  519.             $sql_lines = explode($crlf, $create_query);
  520.             $sql_count = count($sql_lines);
  521.  
  522.             // lets find first line with constraints
  523.             for ($i = 0; $i < $sql_count; $i++) {
  524.                 if (preg_match('@^[\s]*(CONSTRAINT|FOREIGN[\s]+KEY)@', $sql_lines[$i])) {
  525.                     break;
  526.                 }
  527.             }
  528.  
  529.             // If we really found a constraint
  530.             if ($i != $sql_count) {
  531.  
  532.                 // remove , from the end of create statement
  533.                 $sql_lines[$i - 1] = preg_replace('@,$@', '', $sql_lines[$i - 1]);
  534.  
  535.                 // prepare variable for constraints
  536.                 if (!isset($sql_constraints)) {
  537.                     if (isset($GLOBALS['no_constraints_comments'])) {
  538.                         $sql_constraints = '';
  539.                     } else {
  540.                         $sql_constraints = $crlf
  541.                                          . PMA_exportComment() 
  542.                                          . PMA_exportComment($GLOBALS['strConstraintsForDumped'])
  543.                                          . PMA_exportComment();
  544.                     }
  545.                 }
  546.  
  547.                 // comments for current table
  548.                 if (!isset($GLOBALS['no_constraints_comments'])) {
  549.                     $sql_constraints .= $crlf
  550.                                      . PMA_exportComment()
  551.                                      . PMA_exportComment($GLOBALS['strConstraintsForTable'] . ' ' . PMA_backquote($table))
  552.                                      . PMA_exportComment();
  553.                 }
  554.  
  555.                 // let's do the work
  556.                 $sql_constraints_query .= 'ALTER TABLE ' . PMA_backquote($table) . $crlf;
  557.                 $sql_constraints .= 'ALTER TABLE ' . PMA_backquote($table) . $crlf;
  558.  
  559.                 $first = TRUE;
  560.                 for ($j = $i; $j < $sql_count; $j++) {
  561.                     if (preg_match('@CONSTRAINT|FOREIGN[\s]+KEY@', $sql_lines[$j])) {
  562.                         if (!$first) {
  563.                             $sql_constraints .= $crlf;
  564.                         }
  565.                         if (strpos($sql_lines[$j], 'CONSTRAINT') === FALSE) {
  566.                             $str_tmp = preg_replace('/(FOREIGN[\s]+KEY)/', 'ADD \1', $sql_lines[$j]);
  567.                             $sql_constraints_query .= $str_tmp;
  568.                             $sql_constraints .= $str_tmp;
  569.                         } else {
  570.                             $str_tmp = preg_replace('/(CONSTRAINT)/', 'ADD \1', $sql_lines[$j]);
  571.                             $sql_constraints_query .= $str_tmp;
  572.                             $sql_constraints .= $str_tmp;
  573.                         }
  574.                         $first = FALSE;
  575.                     } else {
  576.                         break;
  577.                     }
  578.                 }
  579.                 $sql_constraints .= ';' . $crlf;
  580.                 $sql_constraints_query .= ';';
  581.  
  582.                 $create_query = implode($crlf, array_slice($sql_lines, 0, $i)) . $crlf . implode($crlf, array_slice($sql_lines, $j, $sql_count - 1));
  583.                 unset($sql_lines);
  584.             }
  585.         }
  586.         $schema_create .= $create_query;
  587.     }
  588.  
  589.     // remove a possible "AUTO_INCREMENT = value" clause
  590.     // that could be there starting with MySQL 5.0.24
  591.     $schema_create = preg_replace('/AUTO_INCREMENT\s*=\s*([0-9])+/', '', $schema_create);
  592.  
  593.     $schema_create .= $auto_increment;
  594.  
  595.     PMA_DBI_free_result($result);
  596.     return $schema_create;
  597. } // end of the 'PMA_getTableDef()' function
  598.  
  599.  
  600. /**
  601.  * Returns $table's comments, relations etc.
  602.  *
  603.  * @param   string   the database name
  604.  * @param   string   the table name
  605.  * @param   string   the end of line sequence
  606.  * @param   boolean  whether to include relation comments
  607.  * @param   boolean  whether to include column comments
  608.  * @param   boolean  whether to include mime comments
  609.  *
  610.  * @return  string   resulting comments
  611.  *
  612.  * @access  public
  613.  */
  614. function PMA_getTableComments($db, $table, $crlf, $do_relation = false, $do_comments = false, $do_mime = false)
  615. {
  616.     global $cfgRelation;
  617.     global $sql_backquotes;
  618.     global $sql_constraints;
  619.  
  620.     $schema_create = '';
  621.  
  622.     // triggered only for MySQL < 4.1.x (pmadb-style comments)
  623.     if ($do_comments && $cfgRelation['commwork']) {
  624.         if (!($comments_map = PMA_getComments($db, $table))) {
  625.             unset($comments_map);
  626.         }
  627.     }
  628.  
  629.     // Check if we can use Relations (Mike Beck)
  630.     if ($do_relation && !empty($cfgRelation['relation'])) {
  631.         // Find which tables are related with the current one and write it in
  632.         // an array
  633.         $res_rel = PMA_getForeigners($db, $table);
  634.  
  635.         if ($res_rel && count($res_rel) > 0) {
  636.             $have_rel = TRUE;
  637.         } else {
  638.             $have_rel = FALSE;
  639.         }
  640.     } else {
  641.            $have_rel = FALSE;
  642.     } // end if
  643.  
  644.     if ($do_mime && $cfgRelation['mimework']) {
  645.         if (!($mime_map = PMA_getMIME($db, $table, true))) {
  646.             unset($mime_map);
  647.         }
  648.     }
  649.  
  650.     if (isset($comments_map) && count($comments_map) > 0) {
  651.         $schema_create .= $crlf
  652.                        . PMA_exportComment() 
  653.                        . PMA_exportComment($GLOBALS['strCommentsForTable']. ' ' . PMA_backquote($table, $sql_backquotes) . ':');
  654.         foreach ($comments_map AS $comment_field => $comment) {
  655.             $schema_create .= PMA_exportComment('  ' . PMA_backquote($comment_field, $sql_backquotes))
  656.                             . PMA_exportComment('      ' . PMA_backquote($comment, $sql_backquotes));
  657.         }
  658.         $schema_create .= PMA_exportComment();
  659.     }
  660.  
  661.     if (isset($mime_map) && count($mime_map) > 0) {
  662.         $schema_create .= $crlf
  663.                        . PMA_exportComment() 
  664.                        . PMA_exportComment($GLOBALS['strMIMETypesForTable']. ' ' . PMA_backquote($table, $sql_backquotes) . ':');
  665.         @reset($mime_map);
  666.         foreach ($mime_map AS $mime_field => $mime) {
  667.             $schema_create .= PMA_exportComment('  ' . PMA_backquote($mime_field, $sql_backquotes))
  668.                             . PMA_exportComment('      ' . PMA_backquote($mime['mimetype'], $sql_backquotes));
  669.         }
  670.         $schema_create .= PMA_exportComment(); 
  671.     }
  672.  
  673.     if ($have_rel) {
  674.         $schema_create .= $crlf
  675.                        . PMA_exportComment() 
  676.                        . PMA_exportComment($GLOBALS['strRelationsForTable']. ' ' . PMA_backquote($table, $sql_backquotes) . ':');
  677.         foreach ($res_rel AS $rel_field => $rel) {
  678.             $schema_create .= PMA_exportComment('  ' . PMA_backquote($rel_field, $sql_backquotes))
  679.                             . PMA_exportComment('      ' . PMA_backquote($rel['foreign_table'], $sql_backquotes)
  680.                             . ' -> ' . PMA_backquote($rel['foreign_field'], $sql_backquotes));
  681.         }
  682.         $schema_create .= PMA_exportComment(); 
  683.     }
  684.  
  685.     return $schema_create;
  686.  
  687. } // end of the 'PMA_getTableComments()' function
  688.  
  689. /**
  690.  * Outputs table's structure
  691.  *
  692.  * @param   string   the database name
  693.  * @param   string   the table name
  694.  * @param   string   the end of line sequence
  695.  * @param   string   the url to go back in case of error
  696.  * @param   boolean  whether to include relation comments
  697.  * @param   boolean  whether to include column comments
  698.  * @param   boolean  whether to include mime comments
  699.  * @param   string   'stand_in', 'create_table', 'create_view'
  700.  * @param   string   'server', 'database', 'table' 
  701.  *
  702.  * @return  bool     Whether it suceeded
  703.  *
  704.  * @access  public
  705.  */
  706. function PMA_exportStructure($db, $table, $crlf, $error_url, $relation = FALSE, $comments = FALSE, $mime = FALSE, $dates = FALSE, $export_mode, $export_type)
  707. {
  708.     $formatted_table_name = (isset($GLOBALS['sql_backquotes']))
  709.                           ? PMA_backquote($table)
  710.                           : '\'' . $table . '\'';
  711.     $dump = $crlf
  712.           . PMA_exportComment(str_repeat('-', 56))
  713.           . $crlf
  714.           . PMA_exportComment(); 
  715.  
  716.     switch($export_mode) {
  717.         case 'create_table':
  718.             $dump .=  PMA_exportComment($GLOBALS['strTableStructure'] . ' ' . $formatted_table_name)
  719.                   . PMA_exportComment(); 
  720.             $dump .= PMA_getTableDef($db, $table, $crlf, $error_url, $dates) . ';' . $crlf;
  721.             $triggers = PMA_DBI_get_triggers($db, $table);
  722.             if ($triggers) {
  723.                 $dump .=  $crlf
  724.                       . PMA_exportComment() 
  725.                       . PMA_exportComment($GLOBALS['strTriggers'] . ' ' . $formatted_table_name)
  726.                       . PMA_exportComment(); 
  727.                 $delimiter = '//';
  728.                 foreach ($triggers as $trigger) {
  729.                     $dump .= $trigger['drop'] . ';' . $crlf;
  730.                     $dump .= 'DELIMITER ' . $delimiter . $crlf;
  731.                     $dump .= $trigger['create'];
  732.                     $dump .= 'DELIMITER ;' . $crlf;
  733.                 }
  734.             }
  735.             break;
  736.         case 'create_view':
  737.             $dump .= PMA_exportComment($GLOBALS['strStructureForView'] . ' ' . $formatted_table_name)
  738.                   .  PMA_exportComment();
  739.             // delete the stand-in table previously created (if any)
  740.             if ($export_type != 'table') {
  741.                 $dump .= 'DROP TABLE IF EXISTS ' . PMA_backquote($table) . ';' . $crlf;
  742.             }
  743.             $dump .= PMA_getTableDef($db, $table, $crlf, $error_url, $dates) . ';' . $crlf;
  744.             break;
  745.         case 'stand_in':
  746.             $dump .=  PMA_exportComment($GLOBALS['strStandInStructureForView'] . ' ' . $formatted_table_name)
  747.                   .  PMA_exportComment();
  748.             // export a stand-in definition to resolve view dependencies
  749.             $dump .= PMA_getTableDefStandIn($db, $table, $crlf);
  750.     } // end switch
  751.  
  752.     $dump .= PMA_getTableComments($db, $table, $crlf, $relation, $comments, $mime);
  753.     // this one is built by PMA_getTableDef() to use in table copy/move
  754.     // but not in the case of export
  755.     unset($GLOBALS['sql_constraints_query']);
  756.  
  757.     return PMA_exportOutputHandler($dump);
  758. }
  759.  
  760. /**
  761.  * Dispatches between the versions of 'getTableContent' to use depending
  762.  * on the php version
  763.  *
  764.  * @param   string      the database name
  765.  * @param   string      the table name
  766.  * @param   string      the end of line sequence
  767.  * @param   string      the url to go back in case of error
  768.  * @param   string      SQL query for obtaining data
  769.  *
  770.  * @return  bool        Whether it suceeded
  771.  *
  772.  * @global  boolean  whether to use backquotes to allow the use of special
  773.  *                   characters in database, table and fields names or not
  774.  * @global  integer  the number of records
  775.  * @global  integer  the current record position
  776.  *
  777.  * @access  public
  778.  *
  779.  * @see     PMA_getTableContentFast(), PMA_getTableContentOld()
  780.  *
  781.  * @author  staybyte
  782.  */
  783. function PMA_exportData($db, $table, $crlf, $error_url, $sql_query)
  784. {
  785.     global $sql_backquotes;
  786.     global $rows_cnt;
  787.     global $current_row;
  788.  
  789.     $formatted_table_name = (isset($GLOBALS['sql_backquotes']))
  790.                           ? PMA_backquote($table)
  791.                           : '\'' . $table . '\'';
  792.  
  793.     // Do not export data for a VIEW
  794.     // (For a VIEW, this is called only when exporting a single VIEW)
  795.     if (PMA_Table::_isView($db, $table)) {
  796.         $head = $crlf
  797.           . PMA_exportComment() 
  798.           . PMA_exportComment('VIEW ' . ' ' . $formatted_table_name)
  799.           . PMA_exportComment($GLOBALS['strData'] . ': ' . $GLOBALS['strNone']) 
  800.           . PMA_exportComment() 
  801.           . $crlf;
  802.  
  803.         if (! PMA_exportOutputHandler($head)) {
  804.             return FALSE;
  805.         }
  806.         return true;
  807.     }
  808.  
  809.     // it's not a VIEW
  810.     $head = $crlf
  811.           . PMA_exportComment() 
  812.           . PMA_exportComment($GLOBALS['strDumpingData'] . ' ' . $formatted_table_name)
  813.           . PMA_exportComment() 
  814.           . $crlf;
  815.  
  816.     if (! PMA_exportOutputHandler($head)) {
  817.         return FALSE;
  818.     }
  819.  
  820.     $buffer = '';
  821.  
  822.     // analyze the query to get the true column names, not the aliases
  823.     // (this fixes an undefined index, also if Complete inserts
  824.     //  are used, we did not get the true column name in case of aliases)
  825.     $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($sql_query));
  826.  
  827.     $result      = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
  828.     if ($result != FALSE) {
  829.         $fields_cnt     = PMA_DBI_num_fields($result);
  830.  
  831.         // Get field information
  832.         $fields_meta    = PMA_DBI_get_fields_meta($result);
  833.         $field_flags    = array();
  834.         for ($j = 0; $j < $fields_cnt; $j++) {
  835.             $field_flags[$j] = PMA_DBI_field_flags($result, $j);
  836.         }
  837.  
  838.         for ($j = 0; $j < $fields_cnt; $j++) {
  839.             if (isset($analyzed_sql[0]['select_expr'][$j]['column'])) {
  840.                 $field_set[$j] = PMA_backquote($analyzed_sql[0]['select_expr'][$j]['column'], $sql_backquotes);
  841.             } else {
  842.                 $field_set[$j] = PMA_backquote($fields_meta[$j]->name, $sql_backquotes);
  843.             }
  844.         }
  845.  
  846.         if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'UPDATE') {
  847.             // update
  848.             $schema_insert  = 'UPDATE ';
  849.             if (isset($GLOBALS['sql_ignore'])) {
  850.                 $schema_insert .= 'IGNORE ';
  851.             }
  852.             // avoid EOL blank
  853.             $schema_insert .= PMA_backquote($table, $sql_backquotes) . ' SET';
  854.         } else {
  855.             // insert or replace
  856.             if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'REPLACE') {
  857.                 $sql_command    = 'REPLACE';
  858.             } else {
  859.                 $sql_command    = 'INSERT';
  860.             }
  861.  
  862.             // delayed inserts?
  863.             if (isset($GLOBALS['sql_delayed'])) {
  864.                 $insert_delayed = ' DELAYED';
  865.             } else {
  866.                 $insert_delayed = '';
  867.             }
  868.  
  869.             // insert ignore?
  870.             if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'INSERT' && isset($GLOBALS['sql_ignore'])) {
  871.                 $insert_delayed .= ' IGNORE';
  872.             }
  873.  
  874.             // scheme for inserting fields
  875.             if (isset($GLOBALS['sql_columns'])) {
  876.                 $fields        = implode(', ', $field_set);
  877.                 $schema_insert = $sql_command . $insert_delayed .' INTO ' . PMA_backquote($table, $sql_backquotes)
  878.             // avoid EOL blank
  879.                                . ' (' . $fields . ') VALUES';
  880.             } else {
  881.                 $schema_insert = $sql_command . $insert_delayed .' INTO ' . PMA_backquote($table, $sql_backquotes)
  882.                                . ' VALUES';
  883.             }
  884.         }
  885.  
  886.         $search       = array("\x00", "\x0a", "\x0d", "\x1a"); //\x08\\x09, not required
  887.         $replace      = array('\0', '\n', '\r', '\Z');
  888.         $current_row  = 0;
  889.         $query_size   = 0;
  890.         if (isset($GLOBALS['sql_extended']) && (!isset($GLOBALS['sql_type']) || $GLOBALS['sql_type'] != 'UPDATE')) {
  891.             $separator    = ',';
  892.             $schema_insert .= $crlf;
  893.         } else {
  894.             $separator    = ';';
  895.         }
  896.  
  897.         while ($row = PMA_DBI_fetch_row($result)) {
  898.             $current_row++;
  899.             for ($j = 0; $j < $fields_cnt; $j++) {
  900.                 // NULL
  901.                 if (!isset($row[$j]) || is_null($row[$j])) {
  902.                     $values[]     = 'NULL';
  903.                 // a number
  904.                 // timestamp is numeric on some MySQL 4.1, BLOBs are sometimes numeric
  905.                 } elseif ($fields_meta[$j]->numeric && $fields_meta[$j]->type != 'timestamp'
  906.                         && ! $fields_meta[$j]->blob) {
  907.                     $values[] = $row[$j];
  908.                 // a true BLOB
  909.                 // - mysqldump only generates hex data when the --hex-blob
  910.                 //   option is used, for fields having the binary attribute
  911.                 //   no hex is generated
  912.                 // - a TEXT field returns type blob but a real blob
  913.                 //   returns also the 'binary' flag
  914.                 } elseif (stristr($field_flags[$j], 'BINARY')
  915.                         && $fields_meta[$j]->blob
  916.                         && isset($GLOBALS['sql_hex_for_blob'])) {
  917.                     // empty blobs need to be different, but '0' is also empty :-(
  918.                     if (empty($row[$j]) && $row[$j] != '0') {
  919.                         $values[] = '\'\'';
  920.                     } else {
  921.                         $values[] = '0x' . bin2hex($row[$j]);
  922.                     }
  923.                 // detection of 'bit' works only on mysqli extension
  924.                 } elseif ($fields_meta[$j]->type == 'bit') {
  925.                     $values[] = "b'" . PMA_sqlAddslashes(PMA_printable_bit_value($row[$j], $fields_meta[$j]->length)) . "'";
  926.                 // something else -> treat as a string
  927.                 } else {
  928.                     $values[] = '\'' . str_replace($search, $replace, PMA_sqlAddslashes($row[$j])) . '\'';
  929.                 } // end if
  930.             } // end for
  931.  
  932.             // should we make update?
  933.             if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'UPDATE') {
  934.  
  935.                 $insert_line = $schema_insert;
  936.                 for ($i = 0; $i < $fields_cnt; $i++) {
  937.                     if (0 == $i) {
  938.                         $insert_line .= ' ';
  939.                     }
  940.                     if ($i > 0) {
  941.                         // avoid EOL blank
  942.                         $insert_line .= ',';
  943.                     }
  944.                     $insert_line .= $field_set[$i] . ' = ' . $values[$i];
  945.                 }
  946.  
  947.                 $insert_line .= ' WHERE ' . PMA_getUniqueCondition($result, $fields_cnt, $fields_meta, $row);
  948.  
  949.             } else {
  950.  
  951.                 // Extended inserts case
  952.                 if (isset($GLOBALS['sql_extended'])) {
  953.                     if ($current_row == 1) {
  954.                         $insert_line  = $schema_insert . '(' . implode(', ', $values) . ')';
  955.                     } else {
  956.                         $insert_line  = '(' . implode(', ', $values) . ')';
  957.                         if (isset($GLOBALS['sql_max_query_size']) && $GLOBALS['sql_max_query_size'] > 0 && $query_size + strlen($insert_line) > $GLOBALS['sql_max_query_size']) {
  958.                             if (!PMA_exportOutputHandler(';' . $crlf)) {
  959.                                 return FALSE;
  960.                             }
  961.                             $query_size = 0;
  962.                             $current_row = 1;
  963.                             $insert_line = $schema_insert . $insert_line;
  964.                         }
  965.                     }
  966.                     $query_size += strlen($insert_line);
  967.                 }
  968.                 // Other inserts case
  969.                 else {
  970.                     $insert_line      = $schema_insert . '(' . implode(', ', $values) . ')';
  971.                 }
  972.             }
  973.             unset($values);
  974.  
  975.             if (!PMA_exportOutputHandler(($current_row == 1 ? '' : $separator . $crlf) . $insert_line)) {
  976.                 return FALSE;
  977.             }
  978.  
  979.         } // end while
  980.         if ($current_row > 0) {
  981.             if (!PMA_exportOutputHandler(';' . $crlf)) {
  982.                 return FALSE;
  983.             }
  984.         }
  985.     } // end if ($result != FALSE)
  986.     PMA_DBI_free_result($result);
  987.  
  988.     return TRUE;
  989. } // end of the 'PMA_exportData()' function
  990. }
  991. ?>
  992.