/** * Includes and instantiates the specified plugin type for a certain format * * @param string $plugin_type the type of the plugin (import, export, etc) * @param string $plugin_format the format of the plugin (sql, xml, et ) * @param string $plugins_dir directrory with plugins * @param mixed $plugin_param parameter to plugin by which they can * decide whether they can work * * @return object new plugin instance */ function PMA_getPlugin($plugin_type, $plugin_format, $plugins_dir, $plugin_param = false) { $GLOBALS['plugin_param'] = $plugin_param; $class_name = strtoupper($plugin_type[0]) . strtolower(substr($plugin_type, 1)) . strtoupper($plugin_format[0]) . strtolower(substr($plugin_format, 1)); $file = $class_name . ".class.php"; if (is_file($plugins_dir . $file)) { include_once $plugins_dir . $file; return new $class_name(); } // by default, return SQL plugin return PMA_getPlugin($plugin_type, 'sql', $plugins_dir, $plugin_param); }
/** * get all the export options and verify * call and include the appropriate Schema Class depending on $export_type * * @param string $export_type format of the export * * @return void */ function PMA_processExportSchema($export_type) { /** * default is PDF, otherwise validate it's only letters a-z */ if (!isset($export_type) || !preg_match('/^[a-zA-Z]+$/', $export_type)) { $export_type = 'pdf'; } // sanitize this parameter which will be used below in a file inclusion $export_type = PMA_securePath($export_type); // get the specific plugin $export_plugin = PMA_getPlugin("schema", $export_type, 'libraries/plugins/schema/'); // Check schema export type if (!isset($export_plugin)) { PMA_fatalError(__('Bad type!')); } $GLOBALS['dbi']->selectDb($GLOBALS['db']); $export_plugin->exportSchema($GLOBALS['db']); }
$original_skip = $skip; while ($skip > 0) { PMA_importGetNextChunk($skip < $read_limit ? $skip : $read_limit); // Disable read progressivity, otherwise we eat all memory! $read_multiply = 1; $skip -= $read_limit; } unset($skip); } // This array contain the data like numberof valid sql queries in the statement // and complete valid sql statement (which affected for rows) $sql_data = array('valid_sql' => array(), 'valid_queries' => 0); if (!$error) { // Check for file existance include_once "libraries/plugin_interface.lib.php"; $import_plugin = PMA_getPlugin("import", $format, 'libraries/plugins/import/', $import_type); if ($import_plugin == null) { $message = PMA_Message::error(__('Could not load import plugins, please check your installation!')); PMA_stopImport($message); } else { // Do the real import $import_plugin->doImport($sql_data); } } if (false !== $import_handle && null !== $import_handle) { fclose($import_handle); } // Cleanup temporary file if ($file_to_unlink != '') { unlink($file_to_unlink); }
/** * Copies or renames table * * @param string $source_db source database * @param string $source_table source table * @param string $target_db target database * @param string $target_table target table * @param string $what what to be moved or copied (data, dataonly) * @param bool $move whether to move * @param string $mode mode * * @return bool true if success, false otherwise */ public static function moveCopy($source_db, $source_table, $target_db, $target_table, $what, $move, $mode) { global $err_url; /* Try moving table directly */ if ($move && $what == 'data') { $tbl = new PMA_Table($source_table, $source_db); $result = $tbl->rename($target_table, $target_db); if ($result) { $GLOBALS['message'] = $tbl->getLastMessage(); return true; } } // set export settings we need $GLOBALS['sql_backquotes'] = 1; $GLOBALS['asfile'] = 1; // Ensure the target is valid if (!$GLOBALS['pma']->databases->exists($source_db, $target_db)) { if (!$GLOBALS['pma']->databases->exists($source_db)) { $GLOBALS['message'] = PMA_Message::rawError(sprintf(__('Source database `%s` was not found!'), htmlspecialchars($source_db))); } if (!$GLOBALS['pma']->databases->exists($target_db)) { $GLOBALS['message'] = PMA_Message::rawError(sprintf(__('Target database `%s` was not found!'), htmlspecialchars($target_db))); } return false; } $source = PMA_Util::backquote($source_db) . '.' . PMA_Util::backquote($source_table); if (!isset($target_db) || !strlen($target_db)) { $target_db = $source_db; } // Doing a select_db could avoid some problems with replicated databases, // when moving table from replicated one to not replicated one PMA_DBI_select_db($target_db); $target = PMA_Util::backquote($target_db) . '.' . PMA_Util::backquote($target_table); // do not create the table if dataonly if ($what != 'dataonly') { include_once "libraries/plugin_interface.lib.php"; // get Export SQL instance $export_sql_plugin = PMA_getPlugin("export", "sql", 'libraries/plugins/export/', array('export_type' => 'table', 'single_table' => isset($single_table))); $no_constraints_comments = true; $GLOBALS['sql_constraints_query'] = ''; $sql_structure = $export_sql_plugin->getTableDef($source_db, $source_table, "\n", $err_url, false, false); unset($no_constraints_comments); $parsed_sql = PMA_SQP_parse($sql_structure); $analyzed_sql = PMA_SQP_analyze($parsed_sql); $i = 0; if (empty($analyzed_sql[0]['create_table_fields'])) { // this is not a CREATE TABLE, so find the first VIEW $target_for_view = PMA_Util::backquote($target_db); while (true) { if ($parsed_sql[$i]['type'] == 'alpha_reservedWord' && $parsed_sql[$i]['data'] == 'VIEW') { break; } $i++; } } unset($analyzed_sql); if (PMA_DRIZZLE) { $table_delimiter = 'quote_backtick'; } else { $server_sql_mode = PMA_DBI_fetch_value("SHOW VARIABLES LIKE 'sql_mode'", 0, 1); // ANSI_QUOTES might be a subset of sql_mode, for example // REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI if (false !== strpos($server_sql_mode, 'ANSI_QUOTES')) { $table_delimiter = 'quote_double'; } else { $table_delimiter = 'quote_backtick'; } unset($server_sql_mode); } /* Find table name in query and replace it */ while ($parsed_sql[$i]['type'] != $table_delimiter) { $i++; } /* no need to backquote() */ if (isset($target_for_view)) { // this a view definition; we just found the first db name // that follows DEFINER VIEW // so change it for the new db name $parsed_sql[$i]['data'] = $target_for_view; // then we have to find all references to the source db // and change them to the target db, ensuring we stay into // the $parsed_sql limits $last = $parsed_sql['len'] - 1; $backquoted_source_db = PMA_Util::backquote($source_db); for (++$i; $i <= $last; $i++) { if ($parsed_sql[$i]['type'] == $table_delimiter && $parsed_sql[$i]['data'] == $backquoted_source_db && $parsed_sql[$i - 1]['type'] != 'punct_qualifier') { $parsed_sql[$i]['data'] = $target_for_view; } } unset($last, $backquoted_source_db); } else { $parsed_sql[$i]['data'] = $target; } /* Generate query back */ $sql_structure = PMA_SQP_formatHtml($parsed_sql, 'query_only'); // If table exists, and 'add drop table' is selected: Drop it! $drop_query = ''; if (isset($_REQUEST['drop_if_exists']) && $_REQUEST['drop_if_exists'] == 'true') { if (PMA_Table::isView($target_db, $target_table)) { $drop_query = 'DROP VIEW'; } else { $drop_query = 'DROP TABLE'; } $drop_query .= ' IF EXISTS ' . PMA_Util::backquote($target_db) . '.' . PMA_Util::backquote($target_table); PMA_DBI_query($drop_query); $GLOBALS['sql_query'] .= "\n" . $drop_query . ';'; // If an existing table gets deleted, maintain any // entries for the PMA_* tables $maintain_relations = true; } @PMA_DBI_query($sql_structure); $GLOBALS['sql_query'] .= "\n" . $sql_structure . ';'; if (($move || isset($GLOBALS['add_constraints'])) && !empty($GLOBALS['sql_constraints_query'])) { $parsed_sql = PMA_SQP_parse($GLOBALS['sql_constraints_query']); $i = 0; // find the first $table_delimiter, it must be the source // table name while ($parsed_sql[$i]['type'] != $table_delimiter) { $i++; // maybe someday we should guard against going over limit //if ($i == $parsed_sql['len']) { // break; //} } // replace it by the target table name, no need // to backquote() $parsed_sql[$i]['data'] = $target; // now we must remove all $table_delimiter that follow a // CONSTRAINT keyword, because a constraint name must be // unique in a db $cnt = $parsed_sql['len'] - 1; for ($j = $i; $j < $cnt; $j++) { if ($parsed_sql[$j]['type'] == 'alpha_reservedWord' && strtoupper($parsed_sql[$j]['data']) == 'CONSTRAINT') { if ($parsed_sql[$j + 1]['type'] == $table_delimiter) { $parsed_sql[$j + 1]['data'] = ''; } } } // Generate query back $GLOBALS['sql_constraints_query'] = PMA_SQP_formatHtml($parsed_sql, 'query_only'); if ($mode == 'one_table') { PMA_DBI_query($GLOBALS['sql_constraints_query']); } $GLOBALS['sql_query'] .= "\n" . $GLOBALS['sql_constraints_query']; if ($mode == 'one_table') { unset($GLOBALS['sql_constraints_query']); } } } else { $GLOBALS['sql_query'] = ''; } // Copy the data unless this is a VIEW if (($what == 'data' || $what == 'dataonly') && !PMA_Table::isView($target_db, $target_table)) { $sql_set_mode = "SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO'"; PMA_DBI_query($sql_set_mode); $GLOBALS['sql_query'] .= "\n\n" . $sql_set_mode . ';'; $sql_insert_data = 'INSERT INTO ' . $target . ' SELECT * FROM ' . $source; PMA_DBI_query($sql_insert_data); $GLOBALS['sql_query'] .= "\n\n" . $sql_insert_data . ';'; } $GLOBALS['cfgRelation'] = PMA_getRelationsParam(); // Drops old table if the user has requested to move it if ($move) { // This could avoid some problems with replicated databases, when // moving table from replicated one to not replicated one PMA_DBI_select_db($source_db); if (PMA_Table::isView($source_db, $source_table)) { $sql_drop_query = 'DROP VIEW'; } else { $sql_drop_query = 'DROP TABLE'; } $sql_drop_query .= ' ' . $source; PMA_DBI_query($sql_drop_query); // Renable table in configuration storage PMA_REL_renameTable($source_db, $target_db, $source_table, $target_table); $GLOBALS['sql_query'] .= "\n\n" . $sql_drop_query . ';'; // end if ($move) } else { // we are copying // Create new entries as duplicates from old PMA DBs if ($what != 'dataonly' && !isset($maintain_relations)) { if ($GLOBALS['cfgRelation']['commwork']) { // Get all comments and MIME-Types for current table $comments_copy_query = 'SELECT column_name, comment' . ($GLOBALS['cfgRelation']['mimework'] ? ', mimetype, transformation, transformation_options' : '') . ' FROM ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_Util::backquote($GLOBALS['cfgRelation']['column_info']) . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($source_db) . '\' AND table_name = \'' . PMA_Util::sqlAddSlashes($source_table) . '\''; $comments_copy_rs = PMA_queryAsControlUser($comments_copy_query); // Write every comment as new copied entry. [MIME] while ($comments_copy_row = PMA_DBI_fetch_assoc($comments_copy_rs)) { $new_comment_query = 'REPLACE INTO ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_Util::backquote($GLOBALS['cfgRelation']['column_info']) . ' (db_name, table_name, column_name, comment' . ($GLOBALS['cfgRelation']['mimework'] ? ', mimetype, transformation, transformation_options' : '') . ') ' . ' VALUES(' . '\'' . PMA_Util::sqlAddSlashes($target_db) . '\',' . '\'' . PMA_Util::sqlAddSlashes($target_table) . '\',' . '\'' . PMA_Util::sqlAddSlashes($comments_copy_row['column_name']) . '\'' . ($GLOBALS['cfgRelation']['mimework'] ? ',\'' . PMA_Util::sqlAddSlashes($comments_copy_row['comment']) . '\',' . '\'' . PMA_Util::sqlAddSlashes($comments_copy_row['mimetype']) . '\',' . '\'' . PMA_Util::sqlAddSlashes($comments_copy_row['transformation']) . '\',' . '\'' . PMA_Util::sqlAddSlashes($comments_copy_row['transformation_options']) . '\'' : '') . ')'; PMA_queryAsControlUser($new_comment_query); } // end while PMA_DBI_free_result($comments_copy_rs); unset($comments_copy_rs); } // duplicating the bookmarks must not be done here, but // just once per db $get_fields = array('display_field'); $where_fields = array('db_name' => $source_db, 'table_name' => $source_table); $new_fields = array('db_name' => $target_db, 'table_name' => $target_table); PMA_Table::duplicateInfo('displaywork', 'table_info', $get_fields, $where_fields, $new_fields); /** * @todo revise this code when we support cross-db relations */ $get_fields = array('master_field', 'foreign_table', 'foreign_field'); $where_fields = array('master_db' => $source_db, 'master_table' => $source_table); $new_fields = array('master_db' => $target_db, 'foreign_db' => $target_db, 'master_table' => $target_table); PMA_Table::duplicateInfo('relwork', 'relation', $get_fields, $where_fields, $new_fields); $get_fields = array('foreign_field', 'master_table', 'master_field'); $where_fields = array('foreign_db' => $source_db, 'foreign_table' => $source_table); $new_fields = array('master_db' => $target_db, 'foreign_db' => $target_db, 'foreign_table' => $target_table); PMA_Table::duplicateInfo('relwork', 'relation', $get_fields, $where_fields, $new_fields); $get_fields = array('x', 'y', 'v', 'h'); $where_fields = array('db_name' => $source_db, 'table_name' => $source_table); $new_fields = array('db_name' => $target_db, 'table_name' => $target_table); PMA_Table::duplicateInfo('designerwork', 'designer_coords', $get_fields, $where_fields, $new_fields); /** * @todo Can't get duplicating PDFs the right way. The * page numbers always get screwed up independently from * duplication because the numbers do not seem to be stored on a * per-database basis. Would the author of pdf support please * have a look at it? * $get_fields = array('page_descr'); $where_fields = array('db_name' => $source_db); $new_fields = array('db_name' => $target_db); $last_id = PMA_Table::duplicateInfo( 'pdfwork', 'pdf_pages', $get_fields, $where_fields, $new_fields ); if (isset($last_id) && $last_id >= 0) { $get_fields = array('x', 'y'); $where_fields = array( 'db_name' => $source_db, 'table_name' => $source_table ); $new_fields = array( 'db_name' => $target_db, 'table_name' => $target_table, 'pdf_page_number' => $last_id ); PMA_Table::duplicateInfo( 'pdfwork', 'table_coords', $get_fields, $where_fields, $new_fields ); } */ } } return true; }
* * - Please keep the parameters in order of their appearance in the form * - Some of these parameters are not used, as the code below directly * verifies from the superglobal $_POST or $_REQUEST */ $post_params = array('db', 'table', 'single_table', 'export_type', 'export_method', 'quick_or_custom', 'db_select', 'table_select', 'limit_to', 'limit_from', 'allrows', 'output_format', 'filename_template', 'maxsize', 'remember_template', 'charset_of_file', 'compression', 'what', 'knjenc', 'xkana', 'htmlword_structure_or_data', 'htmlword_null', 'htmlword_columns', 'mediawiki_headers', 'mediawiki_structure_or_data', 'mediawiki_caption', 'pdf_structure_or_data', 'odt_structure_or_data', 'odt_relation', 'odt_comments', 'odt_mime', 'odt_columns', 'odt_null', 'codegen_structure_or_data', 'codegen_format', 'excel_null', 'excel_removeCRLF', 'excel_columns', 'excel_edition', 'excel_structure_or_data', 'yaml_structure_or_data', 'ods_null', 'ods_structure_or_data', 'ods_columns', 'json_structure_or_data', 'xml_structure_or_data', 'xml_export_events', 'xml_export_functions', 'xml_export_procedures', 'xml_export_tables', 'xml_export_triggers', 'xml_export_views', 'xml_export_contents', 'texytext_structure_or_data', 'texytext_columns', 'texytext_null', 'phparray_structure_or_data', 'sql_include_comments', 'sql_header_comment', 'sql_dates', 'sql_relation', 'sql_mime', 'sql_use_transaction', 'sql_disable_fk', 'sql_compatibility', 'sql_structure_or_data', 'sql_create_database', 'sql_drop_table', 'sql_procedure_function', 'sql_create_table_statements', 'sql_create_table', 'sql_create_view', 'sql_create_trigger', 'sql_if_not_exists', 'sql_auto_increment', 'sql_backquotes', 'sql_truncate', 'sql_delayed', 'sql_ignore', 'sql_type', 'sql_insert_syntax', 'sql_max_query_size', 'sql_hex_for_binary', 'sql_utc_time', 'sql_drop_database', 'sql_views_as_tables', 'csv_separator', 'csv_enclosed', 'csv_escaped', 'csv_terminated', 'csv_null', 'csv_removeCRLF', 'csv_columns', 'csv_structure_or_data', 'latex_caption', 'latex_structure_or_data', 'latex_structure_caption', 'latex_structure_continued_caption', 'latex_structure_label', 'latex_relation', 'latex_comments', 'latex_mime', 'latex_columns', 'latex_data_caption', 'latex_data_continued_caption', 'latex_data_label', 'latex_null'); foreach ($post_params as $one_post_param) { if (isset($_POST[$one_post_param])) { $GLOBALS[$one_post_param] = $_POST[$one_post_param]; } } // sanitize this parameter which will be used below in a file inclusion $what = PMA_securePath($what); PMA_Util::checkParameters(array('what', 'export_type')); // export class instance, not array of properties, as before $export_plugin = PMA_getPlugin("export", $what, 'libraries/plugins/export/', array('export_type' => $export_type, 'single_table' => isset($single_table))); // Backward compatibility $type = $what; // Check export type if (!isset($export_plugin)) { PMA_fatalError(__('Bad type!')); } /** * valid compression methods */ $compression_methods = array('zip', 'gzip'); /** * init and variable checking */ $compression = false; $onserver = false;
if ($move || !empty($_REQUEST['create_database_before_copying'])) { PMA_createDbBeforeCopy(); } // here I don't use DELIMITER because it's not part of the // language; I have to send each statement one by one // to avoid selecting alternatively the current and new db // we would need to modify the CREATE definitions to qualify // the db name PMA_runProcedureAndFunctionDefinitions($GLOBALS['db']); // go back to current db, just in case $GLOBALS['dbi']->selectDb($GLOBALS['db']); $tables_full = $GLOBALS['dbi']->getTablesFull($GLOBALS['db']); include_once "libraries/plugin_interface.lib.php"; // remove all foreign key constraints, otherwise we can get errors /* @var $export_sql_plugin ExportSql */ $export_sql_plugin = PMA_getPlugin("export", "sql", 'libraries/plugins/export/', array('single_table' => isset($single_table), 'export_type' => 'database')); // create stand-in tables for views $views = PMA_getViewsAndCreateSqlViewStandIn($tables_full, $export_sql_plugin, $GLOBALS['db']); // copy tables $sqlConstratints = PMA_copyTables($tables_full, $move, $GLOBALS['db']); // handle the views if (!$_error) { PMA_handleTheViews($views, $move, $GLOBALS['db']); } unset($views); // now that all tables exist, create all the accumulated constraints if (!$_error && count($sqlConstratints) > 0) { PMA_createAllAccumulatedConstraints($sqlConstratints); } unset($sqlConstratints); if (PMA_MYSQL_INT_VERSION >= 50100) {
/** * Creates tracking version of a table / view * (in other words: create a job to track future changes on the table). * * @param string $dbname name of database * @param string $tablename name of table * @param string $version version * @param string $tracking_set set of tracking statements * @param bool $is_view if table is a view * * @static * * @return int result of version insertion */ public static function createVersion($dbname, $tablename, $version, $tracking_set = '', $is_view = false) { global $sql_backquotes, $export_type; if ($tracking_set == '') { $tracking_set = $GLOBALS['cfg']['Server']['tracking_default_statements']; } // get Export SQL instance include_once "libraries/plugin_interface.lib.php"; /* @var $export_sql_plugin \PMA\libraries\plugins\export\ExportSql */ $export_sql_plugin = PMA_getPlugin("export", "sql", 'libraries/plugins/export/', array('export_type' => $export_type, 'single_table' => false)); $sql_backquotes = true; $date = date('Y-m-d H:i:s'); // Get data definition snapshot of table $columns = $GLOBALS['dbi']->getColumns($dbname, $tablename, null, true); // int indices to reduce size $columns = array_values($columns); // remove Privileges to reduce size for ($i = 0, $nb = count($columns); $i < $nb; $i++) { unset($columns[$i]['Privileges']); } $indexes = $GLOBALS['dbi']->getTableIndexes($dbname, $tablename); $snapshot = array('COLUMNS' => $columns, 'INDEXES' => $indexes); $snapshot = serialize($snapshot); // Get DROP TABLE / DROP VIEW and CREATE TABLE SQL statements $sql_backquotes = true; $create_sql = ""; if ($GLOBALS['cfg']['Server']['tracking_add_drop_table'] == true && $is_view == false) { $create_sql .= self::getLogComment() . 'DROP TABLE IF EXISTS ' . Util::backquote($tablename) . ";\n"; } if ($GLOBALS['cfg']['Server']['tracking_add_drop_view'] == true && $is_view == true) { $create_sql .= self::getLogComment() . 'DROP VIEW IF EXISTS ' . Util::backquote($tablename) . ";\n"; } $create_sql .= self::getLogComment() . $export_sql_plugin->getTableDef($dbname, $tablename, "\n", ""); // Save version $sql_query = "/*NOTRACK*/\n" . "INSERT INTO " . self::_getTrackingTable() . " (" . "db_name, " . "table_name, " . "version, " . "date_created, " . "date_updated, " . "schema_snapshot, " . "schema_sql, " . "data_sql, " . "tracking " . ") " . "values (\n '" . Util::sqlAddSlashes($dbname) . "',\n '" . Util::sqlAddSlashes($tablename) . "',\n '" . Util::sqlAddSlashes($version) . "',\n '" . Util::sqlAddSlashes($date) . "',\n '" . Util::sqlAddSlashes($date) . "',\n '" . Util::sqlAddSlashes($snapshot) . "',\n '" . Util::sqlAddSlashes($create_sql) . "',\n '" . Util::sqlAddSlashes("\n") . "',\n '" . Util::sqlAddSlashes($tracking_set) . "' )"; $result = PMA_queryAsControlUser($sql_query); if ($result) { // Deactivate previous version self::deactivateTracking($dbname, $tablename, $version - 1); } return $result; }
/** * Copies or renames table * * @param string $source_db source database * @param string $source_table source table * @param string $target_db target database * @param string $target_table target table * @param string $what what to be moved or copied (data, dataonly) * @param bool $move whether to move * @param string $mode mode * * @return bool true if success, false otherwise */ public static function moveCopy($source_db, $source_table, $target_db, $target_table, $what, $move, $mode) { global $err_url; // Try moving the tables directly, using native `RENAME` statement. if ($move && $what == 'data') { $tbl = new PMA_Table($source_table, $source_db); if ($tbl->rename($target_table, $target_db)) { $GLOBALS['message'] = $tbl->getLastMessage(); return true; } } // Setting required export settings. $GLOBALS['sql_backquotes'] = 1; $GLOBALS['asfile'] = 1; // Ensuring the target database is valid. if (!$GLOBALS['pma']->databases->exists($source_db, $target_db)) { if (!$GLOBALS['pma']->databases->exists($source_db)) { $GLOBALS['message'] = PMA_Message::rawError(sprintf(__('Source database `%s` was not found!'), htmlspecialchars($source_db))); } if (!$GLOBALS['pma']->databases->exists($target_db)) { $GLOBALS['message'] = PMA_Message::rawError(sprintf(__('Target database `%s` was not found!'), htmlspecialchars($target_db))); } return false; } /** * The full name of source table, quoted. * @var string $source */ $source = PMA_Util::backquote($source_db) . '.' . PMA_Util::backquote($source_table); // If the target database is not specified, the operation is taking // place in the same database. if (!isset($target_db) || !mb_strlen($target_db)) { $target_db = $source_db; } // Selecting the database could avoid some problems with replicated // databases, when moving table from replicated one to not replicated one. $GLOBALS['dbi']->selectDb($target_db); /** * The full name of target table, quoted. * @var string $target */ $target = PMA_Util::backquote($target_db) . '.' . PMA_Util::backquote($target_table); // No table is created when this is a data-only operation. if ($what != 'dataonly') { include_once "libraries/plugin_interface.lib.php"; /** * Instance used for exporting the current structure of the table. * * @var ExportSql */ $export_sql_plugin = PMA_getPlugin("export", "sql", 'libraries/plugins/export/', array('export_type' => 'table', 'single_table' => false)); $no_constraints_comments = true; $GLOBALS['sql_constraints_query'] = ''; // set the value of global sql_auto_increment variable if (isset($_POST['sql_auto_increment'])) { $GLOBALS['sql_auto_increment'] = $_POST['sql_auto_increment']; } /** * The old structure of the table.. * @var string $sql_structure */ $sql_structure = $export_sql_plugin->getTableDef($source_db, $source_table, "\n", $err_url, false, false); unset($no_constraints_comments); // ----------------------------------------------------------------- // Phase 0: Preparing structures used. /** * The destination where the table is moved or copied to. * @var SqlParser\Components\Expression */ $destination = new SqlParser\Components\Expression($target_db, $target_table, ''); // Find server's SQL mode so the builder can generate correct // queries. // One of the options that alters the behaviour is `ANSI_QUOTES`. // This is not availabile for Drizzle. if (!PMA_DRIZZLE) { SqlParser\Context::setMode($GLOBALS['dbi']->fetchValue("SELECT @@sql_mode")); } // ----------------------------------------------------------------- // Phase 1: Dropping existent element of the same name (if exists // and required). if (isset($_REQUEST['drop_if_exists']) && $_REQUEST['drop_if_exists'] == 'true') { /** * Drop statement used for building the query. * @var SqlParser\Statements\DropStatement $statement */ $statement = new SqlParser\Statements\DropStatement(); $tbl = new PMA_Table($target_db, $target_table); $statement->options = new SqlParser\Components\OptionsArray(array($tbl->isView() ? 'VIEW' : 'TABLE', 'IF EXISTS')); $statement->fields = array($destination); // Building the query. $drop_query = $statement->build() . ';'; // Executing it. $GLOBALS['dbi']->query($drop_query); $GLOBALS['sql_query'] .= "\n" . $drop_query; // If an existing table gets deleted, maintain any entries for // the PMA_* tables. $maintain_relations = true; } // ----------------------------------------------------------------- // Phase 2: Generating the new query of this structure. /** * The parser responsible for parsing the old queries. * @var SqlParser\Parser $parser */ $parser = new SqlParser\Parser($sql_structure); if (!empty($parser->statements[0])) { /** * The CREATE statement of this structure. * @var SqlParser\Statements\CreateStatement $statement */ $statement = $parser->statements[0]; // Changing the destination. $statement->name = $destination; // Building back the query. $sql_structure = $statement->build() . ';'; // Executing it. $GLOBALS['dbi']->query($sql_structure); $GLOBALS['sql_query'] .= "\n" . $sql_structure; } // ----------------------------------------------------------------- // Phase 3: Adding constraints. // All constraint names are removed because they must be unique. if (($move || isset($GLOBALS['add_constraints'])) && !empty($GLOBALS['sql_constraints_query'])) { $parser = new SqlParser\Parser($GLOBALS['sql_constraints_query']); /** * The ALTER statement that generates the constraints. * @var SqlParser\Statements\AlterStatement $statement */ $statement = $parser->statements[0]; // Changing the altered table to the destination. $statement->table = $destination; // Removing the name of the constraints. foreach ($statement->altered as $idx => $altered) { // All constraint names are removed because they must be unique. if ($altered->options->has('CONSTRAINT')) { $altered->field = null; } } // Building back the query. $GLOBALS['sql_constraints_query'] = $statement->build() . ';'; // Executing it. if ($mode == 'one_table') { $GLOBALS['dbi']->query($GLOBALS['sql_constraints_query']); } $GLOBALS['sql_query'] .= "\n" . $GLOBALS['sql_constraints_query']; if ($mode == 'one_table') { unset($GLOBALS['sql_constraints_query']); } } // ----------------------------------------------------------------- // Phase 4: Adding indexes. // View phase 3. if (!empty($GLOBALS['sql_indexes'])) { $parser = new SqlParser\Parser($GLOBALS['sql_indexes']); /** * The ALTER statement that generates the indexes. * @var SqlParser\Statements\AlterStatement $statement */ $statement = $parser->statements[0]; // Changing the altered table to the destination. $statement->table = $destination; // Removing the name of the constraints. foreach ($statement->altered as $idx => $altered) { // All constraint names are removed because they must be unique. if ($altered->options->has('CONSTRAINT')) { $altered->field = null; } } // Building back the query. $GLOBALS['sql_indexes'] = $statement->build() . ';'; // Executing it. if ($mode == 'one_table' || $mode == 'db_copy') { $GLOBALS['dbi']->query($GLOBALS['sql_indexes']); } $GLOBALS['sql_query'] .= "\n" . $GLOBALS['sql_indexes']; if ($mode == 'one_table' || $mode == 'db_copy') { unset($GLOBALS['sql_indexes']); } } // ----------------------------------------------------------------- // Phase 5: Adding AUTO_INCREMENT. if (!empty($GLOBALS['sql_auto_increments'])) { if ($mode == 'one_table' || $mode == 'db_copy') { $parser = new SqlParser\Parser($GLOBALS['sql_auto_increments']); /** * The ALTER statement that alters the AUTO_INCREMENT value. * @var SqlParser\Statements\AlterStatement $statement */ $statement = $parser->statements[0]; // Changing the altered table to the destination. $statement->table = $destination; // Building back the query. $GLOBALS['sql_auto_increments'] = $statement->build() . ';'; // Executing it. $GLOBALS['dbi']->query($GLOBALS['sql_auto_increments']); $GLOBALS['sql_query'] .= "\n" . $GLOBALS['sql_auto_increments']; unset($GLOBALS['sql_auto_increments']); } } } else { $GLOBALS['sql_query'] = ''; } $_table = new PMA_Table($target_table, $target_db); // Copy the data unless this is a VIEW if (($what == 'data' || $what == 'dataonly') && !$_table->isView()) { if (!PMA_DRIZZLE) { $sql_set_mode = "SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO'"; $GLOBALS['dbi']->query($sql_set_mode); $GLOBALS['sql_query'] .= "\n\n" . $sql_set_mode . ';'; } $sql_insert_data = 'INSERT INTO ' . $target . ' SELECT * FROM ' . $source; $GLOBALS['dbi']->query($sql_insert_data); $GLOBALS['sql_query'] .= "\n\n" . $sql_insert_data . ';'; } PMA_getRelationsParam(); // Drops old table if the user has requested to move it if ($move) { // This could avoid some problems with replicated databases, when // moving table from replicated one to not replicated one $GLOBALS['dbi']->selectDb($source_db); $_source_table = new PMA_Table($source_table, $source_db); if ($_source_table->isView()) { $sql_drop_query = 'DROP VIEW'; } else { $sql_drop_query = 'DROP TABLE'; } $sql_drop_query .= ' ' . $source; $GLOBALS['dbi']->query($sql_drop_query); // Renable table in configuration storage PMA_REL_renameTable($source_db, $target_db, $source_table, $target_table); $GLOBALS['sql_query'] .= "\n\n" . $sql_drop_query . ';'; // end if ($move) return true; } // we are copying // Create new entries as duplicates from old PMA DBs if ($what == 'dataonly' || isset($maintain_relations)) { return true; } if ($GLOBALS['cfgRelation']['commwork']) { // Get all comments and MIME-Types for current table $comments_copy_rs = PMA_queryAsControlUser('SELECT column_name, comment' . ($GLOBALS['cfgRelation']['mimework'] ? ', mimetype, transformation, transformation_options' : '') . ' FROM ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_Util::backquote($GLOBALS['cfgRelation']['column_info']) . ' WHERE ' . ' db_name = \'' . PMA_Util::sqlAddSlashes($source_db) . '\'' . ' AND ' . ' table_name = \'' . PMA_Util::sqlAddSlashes($source_table) . '\''); // Write every comment as new copied entry. [MIME] while ($comments_copy_row = $GLOBALS['dbi']->fetchAssoc($comments_copy_rs)) { $new_comment_query = 'REPLACE INTO ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_Util::backquote($GLOBALS['cfgRelation']['column_info']) . ' (db_name, table_name, column_name, comment' . ($GLOBALS['cfgRelation']['mimework'] ? ', mimetype, transformation, transformation_options' : '') . ') ' . ' VALUES(' . '\'' . PMA_Util::sqlAddSlashes($target_db) . '\',\'' . PMA_Util::sqlAddSlashes($target_table) . '\',\'' . PMA_Util::sqlAddSlashes($comments_copy_row['column_name']) . '\'' . ($GLOBALS['cfgRelation']['mimework'] ? ',\'' . PMA_Util::sqlAddSlashes($comments_copy_row['comment']) . '\',' . '\'' . PMA_Util::sqlAddSlashes($comments_copy_row['mimetype']) . '\',' . '\'' . PMA_Util::sqlAddSlashes($comments_copy_row['transformation']) . '\',' . '\'' . PMA_Util::sqlAddSlashes($comments_copy_row['transformation_options']) . '\'' : '') . ')'; PMA_queryAsControlUser($new_comment_query); } // end while $GLOBALS['dbi']->freeResult($comments_copy_rs); unset($comments_copy_rs); } // duplicating the bookmarks must not be done here, but // just once per db $get_fields = array('display_field'); $where_fields = array('db_name' => $source_db, 'table_name' => $source_table); $new_fields = array('db_name' => $target_db, 'table_name' => $target_table); PMA_Table::duplicateInfo('displaywork', 'table_info', $get_fields, $where_fields, $new_fields); /** * @todo revise this code when we support cross-db relations */ $get_fields = array('master_field', 'foreign_table', 'foreign_field'); $where_fields = array('master_db' => $source_db, 'master_table' => $source_table); $new_fields = array('master_db' => $target_db, 'foreign_db' => $target_db, 'master_table' => $target_table); PMA_Table::duplicateInfo('relwork', 'relation', $get_fields, $where_fields, $new_fields); $get_fields = array('foreign_field', 'master_table', 'master_field'); $where_fields = array('foreign_db' => $source_db, 'foreign_table' => $source_table); $new_fields = array('master_db' => $target_db, 'foreign_db' => $target_db, 'foreign_table' => $target_table); PMA_Table::duplicateInfo('relwork', 'relation', $get_fields, $where_fields, $new_fields); /** * @todo Can't get duplicating PDFs the right way. The * page numbers always get screwed up independently from * duplication because the numbers do not seem to be stored on a * per-database basis. Would the author of pdf support please * have a look at it? * $get_fields = array('page_descr'); $where_fields = array('db_name' => $source_db); $new_fields = array('db_name' => $target_db); $last_id = PMA_Table::duplicateInfo( 'pdfwork', 'pdf_pages', $get_fields, $where_fields, $new_fields ); if (isset($last_id) && $last_id >= 0) { $get_fields = array('x', 'y'); $where_fields = array( 'db_name' => $source_db, 'table_name' => $source_table ); $new_fields = array( 'db_name' => $target_db, 'table_name' => $target_table, 'pdf_page_number' => $last_id ); PMA_Table::duplicateInfo( 'pdfwork', 'table_coords', $get_fields, $where_fields, $new_fields ); } */ return true; }
/** * Creates tracking version of a table / view * (in other words: create a job to track future changes on the table). * * @param string $dbname name of database * @param string $tablename name of table * @param string $version version * @param string $tracking_set set of tracking statements * @param bool $is_view if table is a view * * @static * * @return int result of version insertion */ static public function createVersion($dbname, $tablename, $version, $tracking_set = '', $is_view = false ) { global $sql_backquotes, $export_type; $common_functions = PMA_CommonFunctions::getInstance(); if ($tracking_set == '') { $tracking_set = self::$default_tracking_set; } // get Export SQL instance require_once "libraries/plugin_interface.lib.php"; $export_sql_plugin = PMA_getPlugin( "export", "sql", 'libraries/plugins/export/', array( 'export_type' => $export_type, 'single_table' => isset($single_table) ) ); $sql_backquotes = true; $date = date('Y-m-d H:i:s'); // Get data definition snapshot of table $columns = PMA_DBI_get_columns($dbname, $tablename, null, true); // int indices to reduce size $columns = array_values($columns); // remove Privileges to reduce size for ($i = 0; $i < count($columns); $i++) { unset($columns[$i]['Privileges']); } $indexes = PMA_DBI_get_table_indexes($dbname, $tablename); $snapshot = array('COLUMNS' => $columns, 'INDEXES' => $indexes); $snapshot = serialize($snapshot); // Get DROP TABLE / DROP VIEW and CREATE TABLE SQL statements $sql_backquotes = true; $create_sql = ""; if (self::$add_drop_table == true && $is_view == false) { $create_sql .= self::getLogComment() . 'DROP TABLE IF EXISTS ' . $common_functions->backquote($tablename) . ";\n"; } if (self::$add_drop_view == true && $is_view == true) { $create_sql .= self::getLogComment() . 'DROP VIEW IF EXISTS ' . $common_functions->backquote($tablename) . ";\n"; } $create_sql .= self::getLogComment() . $export_sql_plugin->getTableDef($dbname, $tablename, "\n", ""); // Save version $sql_query = "/*NOTRACK*/\n" . "INSERT INTO" . self::$pma_table . " (" . "db_name, " . "table_name, " . "version, " . "date_created, " . "date_updated, " . "schema_snapshot, " . "schema_sql, " . "data_sql, " . "tracking " . ") " . "values ( '" . $common_functions->sqlAddSlashes($dbname) . "', '" . $common_functions->sqlAddSlashes($tablename) . "', '" . $common_functions->sqlAddSlashes($version) . "', '" . $common_functions->sqlAddSlashes($date) . "', '" . $common_functions->sqlAddSlashes($date) . "', '" . $common_functions->sqlAddSlashes($snapshot) . "', '" . $common_functions->sqlAddSlashes($create_sql) . "', '" . $common_functions->sqlAddSlashes("\n") . "', '" . $common_functions->sqlAddSlashes(self::_transformTrackingSet($tracking_set)) . "' )"; $result = PMA_queryAsControlUser($sql_query); if ($result) { // Deactivate previous version self::deactivateTracking($dbname, $tablename, ($version - 1)); } return $result; }