echo backquote('owners db'); // owners db
/** * Outputs table's structure * * @param string $db database name * @param string $table table name * @param string $crlf the end of line sequence * @param string $error_url the url to go back in case of error * @param string $export_mode 'create_table','triggers','create_view', * 'stand_in' * @param string $export_type 'server', 'database', 'table' * @param bool $relation whether to include relation comments * @param bool $comments whether to include the pmadb-style column * comments as comments in the structure; this is * deprecated but the parameter is left here * because export.php calls exportStructure() * also for other export types which use this * parameter * @param bool $mime whether to include mime comments * @param bool $dates whether to include creation/update/check dates * @param array $aliases Aliases of db/table/columns * * @return bool Whether it succeeded */ public function exportStructure($db, $table, $crlf, $error_url, $export_mode, $export_type, $relation = false, $comments = false, $mime = false, $dates = false, $aliases = array()) { $db_alias = $db; $table_alias = $table; $this->initAlias($aliases, $db_alias, $table_alias); if (isset($GLOBALS['sql_compatibility'])) { $compat = $GLOBALS['sql_compatibility']; } else { $compat = 'NONE'; } $formatted_table_name = Util::backquoteCompat($table_alias, $compat, isset($GLOBALS['sql_backquotes'])); $dump = $this->_possibleCRLF() . $this->_exportComment(str_repeat('-', 56)) . $this->_possibleCRLF() . $this->_exportComment(); switch ($export_mode) { case 'create_table': $dump .= $this->_exportComment(__('Table structure for table') . ' ' . $formatted_table_name); $dump .= $this->_exportComment(); $dump .= $this->getTableDef($db, $table, $crlf, $error_url, $dates, true, false, true, $aliases); $dump .= $this->_getTableComments($db, $table, $crlf, $relation, $mime, $aliases); break; case 'triggers': $dump = ''; $delimiter = '$$'; $triggers = $GLOBALS['dbi']->getTriggers($db, $table, $delimiter); if ($triggers) { $dump .= $this->_possibleCRLF() . $this->_exportComment() . $this->_exportComment(__('Triggers') . ' ' . $formatted_table_name) . $this->_exportComment(); $used_alias = false; $trigger_query = ''; foreach ($triggers as $trigger) { if (!empty($GLOBALS['sql_drop_table'])) { $trigger_query .= $trigger['drop'] . ';' . $crlf; } $trigger_query .= 'DELIMITER ' . $delimiter . $crlf; $trigger_query .= $this->replaceWithAliases($trigger['create'], $aliases, $db, $table, $flag); if ($flag) { $used_alias = true; } $trigger_query .= 'DELIMITER ;' . $crlf; } // One warning per table. if ($used_alias) { $dump .= $this->_exportComment(__('It appears your table uses triggers;')) . $this->_exportComment(__('alias export may not work reliably in all cases.')) . $this->_exportComment(); } $dump .= $trigger_query; } break; case 'create_view': if (empty($GLOBALS['sql_views_as_tables'])) { $dump .= $this->_exportComment(__('Structure for view') . ' ' . $formatted_table_name) . $this->_exportComment(); // delete the stand-in table previously created (if any) if ($export_type != 'table') { $dump .= 'DROP TABLE IF EXISTS ' . Util::backquote($table_alias) . ';' . $crlf; } $dump .= $this->getTableDef($db, $table, $crlf, $error_url, $dates, true, true, true, $aliases); } else { $dump .= $this->_exportComment(sprintf(__('Structure for view %s exported as a table'), $formatted_table_name)) . $this->_exportComment(); // delete the stand-in table previously created (if any) if ($export_type != 'table') { $dump .= 'DROP TABLE IF EXISTS ' . Util::backquote($table_alias) . ';' . $crlf; } $dump .= $this->_getTableDefForView($db, $table, $crlf, true, $aliases); } break; case 'stand_in': $dump .= $this->_exportComment(__('Stand-in structure for view') . ' ' . $formatted_table_name) . $this->_exportComment(); // export a stand-in definition to resolve view dependencies $dump .= $this->getTableDefStandIn($db, $table, $crlf, $aliases); } // end switch // this one is built by getTableDef() to use in table copy/move // but not in the case of export unset($GLOBALS['sql_constraints_query']); return PMA_exportOutputHandler($dump); }
/** * Move or copy a table * * @param string $db current database name * @param string $table current table name * * @return void */ function PMA_moveOrCopyTable($db, $table) { /** * Selects the database to work with */ $GLOBALS['dbi']->selectDb($db); /** * $_REQUEST['target_db'] could be empty in case we came from an input field * (when there are many databases, no drop-down) */ if (empty($_REQUEST['target_db'])) { $_REQUEST['target_db'] = $db; } /** * A target table name has been sent to this script -> do the work */ if (PMA_isValid($_REQUEST['new_name'])) { if ($db == $_REQUEST['target_db'] && $table == $_REQUEST['new_name']) { if (isset($_REQUEST['submit_move'])) { $message = Message::error(__('Can\'t move table to same one!')); } else { $message = Message::error(__('Can\'t copy table to same one!')); } } else { Table::moveCopy($db, $table, $_REQUEST['target_db'], $_REQUEST['new_name'], $_REQUEST['what'], isset($_REQUEST['submit_move']), 'one_table'); if (isset($_REQUEST['adjust_privileges']) && !empty($_REQUEST['adjust_privileges'])) { if (isset($_REQUEST['submit_move'])) { PMA_AdjustPrivileges_renameOrMoveTable($db, $table, $_REQUEST['target_db'], $_REQUEST['new_name']); } else { PMA_AdjustPrivileges_copyTable($db, $table, $_REQUEST['target_db'], $_REQUEST['new_name']); } if (isset($_REQUEST['submit_move'])) { $message = Message::success(__('Table %s has been moved to %s. Privileges have been ' . 'adjusted.')); } else { $message = Message::success(__('Table %s has been copied to %s. Privileges have been ' . 'adjusted.')); } } else { if (isset($_REQUEST['submit_move'])) { $message = Message::success(__('Table %s has been moved to %s.')); } else { $message = Message::success(__('Table %s has been copied to %s.')); } } $old = PMA\libraries\Util::backquote($db) . '.' . PMA\libraries\Util::backquote($table); $message->addParam($old); $new = PMA\libraries\Util::backquote($_REQUEST['target_db']) . '.' . PMA\libraries\Util::backquote($_REQUEST['new_name']); $message->addParam($new); /* Check: Work on new table or on old table? */ if (isset($_REQUEST['submit_move']) || PMA_isValid($_REQUEST['switch_to_new'])) { } } } else { /** * No new name for the table! */ $message = Message::error(__('The table name is empty!')); } if ($GLOBALS['is_ajax_request'] == true) { $response = PMA\libraries\Response::getInstance(); $response->addJSON('message', $message); if ($message->isSuccess()) { $response->addJSON('db', $GLOBALS['db']); } else { $response->setRequestStatus(false); } exit; } }
/** * Create the routine * * @param string $routine_query Query to create routine * @param string $create_routine Query to restore routine * @param array $privilegesBackup Privileges backup * * @return array */ function PMA_RTN_createRoutine($routine_query, $create_routine, $privilegesBackup) { $result = $GLOBALS['dbi']->tryQuery($routine_query); if (!$result) { $errors = array(); $errors[] = sprintf(__('The following query has failed: "%s"'), htmlspecialchars($routine_query)) . '<br />' . __('MySQL said: ') . $GLOBALS['dbi']->getError(null); // We dropped the old routine, // but were unable to create the new one // Try to restore the backup query $result = $GLOBALS['dbi']->tryQuery($create_routine); $errors = checkResult($result, __('Sorry, we failed to restore' . ' the dropped routine.'), $create_routine, $errors); return array($errors, null); } // Default value $resultAdjust = false; if ($GLOBALS['proc_priv'] && $GLOBALS['is_reload_priv']) { // Insert all the previous privileges // but with the new name and the new type foreach ($privilegesBackup as $priv) { $adjustProcPrivilege = 'INSERT INTO ' . Util::backquote('mysql') . '.' . Util::backquote('procs_priv') . ' VALUES("' . $priv[0] . '", "' . $priv[1] . '", "' . $priv[2] . '", "' . $_REQUEST['item_name'] . '", "' . $_REQUEST['item_type'] . '", "' . $priv[5] . '", "' . $priv[6] . '", "' . $priv[7] . '");'; $resultAdjust = $GLOBALS['dbi']->query($adjustProcPrivilege); } } $message = PMA_RTN_flushPrivileges($resultAdjust); return array(array(), $message); }
/** * Displays the list of tables * * @return void */ protected function displayTableList() { // table form $this->response->addHTML(Template::get('database/structure/table_header')->render(array('db' => $this->db, 'db_is_system_schema' => $this->_db_is_system_schema, 'replication' => $GLOBALS['replication_info']['slave']['status']))); $i = $sum_entries = 0; $overhead_check = ''; $create_time_all = ''; $update_time_all = ''; $check_time_all = ''; $num_columns = $GLOBALS['cfg']['PropertiesNumColumns'] > 1 ? ceil($this->_num_tables / $GLOBALS['cfg']['PropertiesNumColumns']) + 1 : 0; $row_count = 0; $sum_size = (double) 0; $overhead_size = (double) 0; $hidden_fields = array(); $odd_row = true; $overall_approx_rows = false; foreach ($this->_tables as $keyname => $current_table) { // Get valid statistics whatever is the table type $drop_query = ''; $drop_message = ''; $overhead = ''; $table_is_view = false; $table_encoded = urlencode($current_table['TABLE_NAME']); // Sets parameters for links $tbl_url_query = $this->_url_query . '&table=' . $table_encoded; // do not list the previous table's size info for a view list($current_table, $formatted_size, $unit, $formatted_overhead, $overhead_unit, $overhead_size, $table_is_view, $sum_size) = $this->getStuffForEngineTypeTable($current_table, $sum_size, $overhead_size); $curTable = $this->dbi->getTable($this->db, $current_table['TABLE_NAME']); if (!$curTable->isMerge()) { $sum_entries += $current_table['TABLE_ROWS']; } if (isset($current_table['Collation'])) { $collation = '<dfn title="' . PMA_getCollationDescr($current_table['Collation']) . '">' . $current_table['Collation'] . '</dfn>'; } else { $collation = '---'; } if ($this->_is_show_stats) { if ($formatted_overhead != '') { $overhead = '<a href="tbl_structure.php' . $tbl_url_query . '#showusage">' . '<span>' . $formatted_overhead . '</span> ' . '<span class="unit">' . $overhead_unit . '</span>' . '</a>' . "\n"; $overhead_check .= "markAllRows('row_tbl_" . ($i + 1) . "');"; } else { $overhead = '-'; } } // end if $showtable = $this->dbi->getTable($this->db, $current_table['TABLE_NAME'])->getStatusInfo(null, true); if ($GLOBALS['cfg']['ShowDbStructureCreation']) { $create_time = isset($showtable['Create_time']) ? $showtable['Create_time'] : ''; if ($create_time && (!$create_time_all || $create_time < $create_time_all)) { $create_time_all = $create_time; } } if ($GLOBALS['cfg']['ShowDbStructureLastUpdate']) { // $showtable might already be set from ShowDbStructureCreation, // see above $update_time = isset($showtable['Update_time']) ? $showtable['Update_time'] : ''; if ($update_time && (!$update_time_all || $update_time < $update_time_all)) { $update_time_all = $update_time; } } if ($GLOBALS['cfg']['ShowDbStructureLastCheck']) { // $showtable might already be set from ShowDbStructureCreation, // see above $check_time = isset($showtable['Check_time']) ? $showtable['Check_time'] : ''; if ($check_time && (!$check_time_all || $check_time < $check_time_all)) { $check_time_all = $check_time; } } $truename = htmlspecialchars(!empty($tooltip_truename) && isset($tooltip_truename[$current_table['TABLE_NAME']]) ? $tooltip_truename[$current_table['TABLE_NAME']] : $current_table['TABLE_NAME']); $truename = str_replace(' ', ' ', $truename); $i++; $row_count++; if ($table_is_view) { $hidden_fields[] = '<input type="hidden" name="views[]" value="' . htmlspecialchars($current_table['TABLE_NAME']) . '" />'; } /* * Always activate links for Browse, Search and Empty, even if * the icons are greyed, because * 1. for views, we don't know the number of rows at this point * 2. for tables, another source could have populated them since the * page was generated * * I could have used the PHP ternary conditional operator but I find * the code easier to read without this operator. */ $may_have_rows = $current_table['TABLE_ROWS'] > 0 || $table_is_view; $titles = Util::buildActionTitles(); $browse_table = Template::get('database/structure/browse_table')->render(array('tbl_url_query' => $tbl_url_query, 'title' => $may_have_rows ? $titles['Browse'] : $titles['NoBrowse'])); $search_table = Template::get('database/structure/search_table')->render(array('tbl_url_query' => $tbl_url_query, 'title' => $may_have_rows ? $titles['Search'] : $titles['NoSearch'])); $browse_table_label = Template::get('database/structure/browse_table_label')->render(array('tbl_url_query' => $tbl_url_query, 'title' => htmlspecialchars($current_table['TABLE_COMMENT']), 'truename' => $truename)); $empty_table = ''; if (!$this->_db_is_system_schema) { $empty_table = ' '; if (!$table_is_view) { $empty_table = Template::get('database/structure/empty_table')->render(array('tbl_url_query' => $tbl_url_query, 'sql_query' => urlencode('TRUNCATE ' . Util::backquote($current_table['TABLE_NAME'])), 'message_to_show' => urlencode(sprintf(__('Table %s has been emptied.'), htmlspecialchars($current_table['TABLE_NAME']))), 'title' => $may_have_rows ? $titles['Empty'] : $titles['NoEmpty'])); } $drop_query = sprintf('DROP %s %s', $table_is_view || $current_table['ENGINE'] == null ? 'VIEW' : 'TABLE', Util::backquote($current_table['TABLE_NAME'])); $drop_message = sprintf($table_is_view || $current_table['ENGINE'] == null ? __('View %s has been dropped.') : __('Table %s has been dropped.'), str_replace(' ', ' ', htmlspecialchars($current_table['TABLE_NAME']))); } if ($num_columns > 0 && $this->_num_tables > $num_columns && $row_count % $num_columns == 0) { $row_count = 1; $odd_row = true; $this->response->addHTML('</tr></tbody></table></form>'); $this->response->addHTML(Template::get('database/structure/table_header')->render(array('db' => $this->db, 'db_is_system_schema' => $this->_db_is_system_schema, 'replication' => $GLOBALS['replication_info']['slave']['status']))); } list($approx_rows, $show_superscript) = $this->isRowCountApproximated($current_table, $table_is_view); list($do, $ignored) = $this->getReplicationStatus($truename); $this->response->addHTML(Template::get('database/structure/structure_table_row')->render(array('db' => $this->db, 'curr' => $i, 'odd_row' => $odd_row, 'table_is_view' => $table_is_view, 'current_table' => $current_table, 'browse_table_label' => $browse_table_label, 'tracking_icon' => $this->getTrackingIcon($truename), 'server_slave_status' => $GLOBALS['replication_info']['slave']['status'], 'browse_table' => $browse_table, 'tbl_url_query' => $tbl_url_query, 'search_table' => $search_table, 'db_is_system_schema' => $this->_db_is_system_schema, 'titles' => $titles, 'empty_table' => $empty_table, 'drop_query' => $drop_query, 'drop_message' => $drop_message, 'collation' => $collation, 'formatted_size' => $formatted_size, 'unit' => $unit, 'overhead' => $overhead, 'create_time' => isset($create_time) ? $create_time : '', 'update_time' => isset($update_time) ? $update_time : '', 'check_time' => isset($check_time) ? $check_time : '', 'is_show_stats' => $this->_is_show_stats, 'ignored' => $ignored, 'do' => $do, 'colspan_for_structure' => $GLOBALS['colspan_for_structure'], 'approx_rows' => $approx_rows, 'show_superscript' => $show_superscript, 'already_favorite' => $this->checkFavoriteTable($current_table['TABLE_NAME'])))); $odd_row = !$odd_row; $overall_approx_rows = $overall_approx_rows || $approx_rows; } // end foreach $this->response->addHTML('</tbody>'); $db_collation = PMA_getDbCollation($this->db); // Show Summary $this->response->addHTML(Template::get('database/structure/body_for_table_summary')->render(array('num_tables' => $this->_num_tables, 'server_slave_status' => $GLOBALS['replication_info']['slave']['status'], 'db_is_system_schema' => $this->_db_is_system_schema, 'sum_entries' => $sum_entries, 'db_collation' => $db_collation, 'is_show_stats' => $this->_is_show_stats, 'sum_size' => $sum_size, 'overhead_size' => $overhead_size, 'create_time_all' => $create_time_all, 'update_time_all' => $update_time_all, 'check_time_all' => $check_time_all, 'approx_rows' => $overall_approx_rows))); $this->response->addHTML('</table>'); //check all $this->response->addHTML(Template::get('database/structure/check_all_tables')->render(array('pmaThemeImage' => $GLOBALS['pmaThemeImage'], 'text_dir' => $GLOBALS['text_dir'], 'overhead_check' => $overhead_check, 'db_is_system_schema' => $this->_db_is_system_schema, 'hidden_fields' => $hidden_fields))); $this->response->addHTML('</form>'); //end of form }
/** * Returns the file name * * @param String $extension file extension * * @return string file name */ protected function getFileName($extension) { $filename = $this->db . $extension; // Get the name of this page to use as filename if ($this->pageNumber != -1 && !$this->offline) { $_name_sql = 'SELECT page_descr FROM ' . PMA\libraries\Util::backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA\libraries\Util::backquote($GLOBALS['cfgRelation']['pdf_pages']) . ' WHERE page_nr = ' . $this->pageNumber; $_name_rs = PMA_queryAsControlUser($_name_sql); $_name_row = $GLOBALS['dbi']->fetchRow($_name_rs); $filename = $_name_row[0] . $extension; } return $filename; }
/** * Prepares queries for adding users and * also create database and return query and message * * @param boolean $_error whether user create or not * @param string $real_sql_query SQL query for add a user * @param string $sql_query SQL query to be displayed * @param string $username username * @param string $hostname host name * @param string $dbname database name * * @return array $sql_query, $message */ function PMA_addUserAndCreateDatabase($_error, $real_sql_query, $sql_query, $username, $hostname, $dbname) { if ($_error || !empty($real_sql_query) && !$GLOBALS['dbi']->tryQuery($real_sql_query)) { $_REQUEST['createdb-1'] = $_REQUEST['createdb-2'] = $_REQUEST['createdb-3'] = null; $message = Message::rawError($GLOBALS['dbi']->getError()); } else { $message = Message::success(__('You have added a new user.')); } if (isset($_REQUEST['createdb-1'])) { // Create database with same name and grant all privileges $q = 'CREATE DATABASE IF NOT EXISTS ' . Util::backquote(Util::sqlAddSlashes($username)) . ';'; $sql_query .= $q; if (!$GLOBALS['dbi']->tryQuery($q)) { $message = Message::rawError($GLOBALS['dbi']->getError()); } /** * Reload the navigation */ $GLOBALS['reload'] = true; $GLOBALS['db'] = $username; $q = 'GRANT ALL PRIVILEGES ON ' . Util::backquote(Util::escapeMysqlWildcards(Util::sqlAddSlashes($username))) . '.* TO \'' . Util::sqlAddSlashes($username) . '\'@\'' . Util::sqlAddSlashes($hostname) . '\';'; $sql_query .= $q; if (!$GLOBALS['dbi']->tryQuery($q)) { $message = Message::rawError($GLOBALS['dbi']->getError()); } } if (isset($_REQUEST['createdb-2'])) { // Grant all privileges on wildcard name (username\_%) $q = 'GRANT ALL PRIVILEGES ON ' . Util::backquote(Util::sqlAddSlashes($username) . '\\_%') . '.* TO \'' . Util::sqlAddSlashes($username) . '\'@\'' . Util::sqlAddSlashes($hostname) . '\';'; $sql_query .= $q; if (!$GLOBALS['dbi']->tryQuery($q)) { $message = Message::rawError($GLOBALS['dbi']->getError()); } } if (isset($_REQUEST['createdb-3'])) { // Grant all privileges on the specified database to the new user $q = 'GRANT ALL PRIVILEGES ON ' . Util::backquote(Util::sqlAddSlashes($dbname)) . '.* TO \'' . Util::sqlAddSlashes($username) . '\'@\'' . Util::sqlAddSlashes($hostname) . '\';'; $sql_query .= $q; if (!$GLOBALS['dbi']->tryQuery($q)) { $message = Message::rawError($GLOBALS['dbi']->getError()); } } return array($sql_query, $message); }
/** * Return the where clause for query generation based on the inputs provided. * * @param mixed $criteriaValues Search criteria input * @param string $names Name of the column on which search is submitted * @param string $types Type of the field * @param string $func_type Search function/operator * @param bool $unaryFlag Whether operator unary or not * @param bool $geom_func Whether geometry functions should be applied * * @return string generated where clause. */ private function _getWhereClause($criteriaValues, $names, $types, $func_type, $unaryFlag, $geom_func = null) { // If geometry function is set if (!empty($geom_func)) { return $this->_getGeomWhereClause($criteriaValues, $names, $func_type, $types, $geom_func); } $backquoted_name = Util::backquote($names); $where = ''; if ($unaryFlag) { $where = $backquoted_name . ' ' . $func_type; } elseif (strncasecmp($types, 'enum', 4) == 0 && !empty($criteriaValues)) { $where = $backquoted_name; $where .= $this->_getEnumWhereClause($criteriaValues, $func_type); } elseif ($criteriaValues != '') { // For these types we quote the value. Even if it's another type // (like INT), for a LIKE we always quote the value. MySQL converts // strings to numbers and numbers to strings as necessary // during the comparison if (preg_match('@char|binary|blob|text|set|date|time|year@i', $types) || mb_strpos(' ' . $func_type, 'LIKE')) { $quot = '\''; } else { $quot = ''; } // LIKE %...% if ($func_type == 'LIKE %...%') { $func_type = 'LIKE'; $criteriaValues = '%' . $criteriaValues . '%'; } if ($func_type == 'REGEXP ^...$') { $func_type = 'REGEXP'; $criteriaValues = '^' . $criteriaValues . '$'; } if ('IN (...)' != $func_type && 'NOT IN (...)' != $func_type && 'BETWEEN' != $func_type && 'NOT BETWEEN' != $func_type) { if ($func_type == 'LIKE %...%' || $func_type == 'LIKE') { $where = $backquoted_name . ' ' . $func_type . ' ' . $quot . Util::sqlAddSlashes($criteriaValues, true) . $quot; } else { $where = $backquoted_name . ' ' . $func_type . ' ' . $quot . Util::sqlAddSlashes($criteriaValues) . $quot; } return $where; } $func_type = str_replace(' (...)', '', $func_type); //Don't explode if this is already an array //(Case for (NOT) IN/BETWEEN.) if (is_array($criteriaValues)) { $values = $criteriaValues; } else { $values = explode(',', $criteriaValues); } // quote values one by one $emptyKey = false; foreach ($values as $key => &$value) { if ('' === $value) { $emptyKey = $key; $value = 'NULL'; continue; } $value = $quot . Util::sqlAddSlashes(trim($value)) . $quot; } if ('BETWEEN' == $func_type || 'NOT BETWEEN' == $func_type) { $where = $backquoted_name . ' ' . $func_type . ' ' . (isset($values[0]) ? $values[0] : '') . ' AND ' . (isset($values[1]) ? $values[1] : ''); } else { //[NOT] IN if (false !== $emptyKey) { unset($values[$emptyKey]); } $wheres = array(); if (!empty($values)) { $wheres[] = $backquoted_name . ' ' . $func_type . ' (' . implode(',', $values) . ')'; } if (false !== $emptyKey) { $wheres[] = $backquoted_name . ' IS NULL'; } $where = implode(' OR ', $wheres); if (1 < count($wheres)) { $where = '(' . $where . ')'; } } } // end if return $where; }
/** * Returns the real row count for a table * * @return number */ function getRealRowCountTable() { // SQL query to get row count for a table. $result = $this->_dbi->fetchSingleRow(sprintf('SELECT COUNT(*) AS %s FROM %s.%s', Util::backquote('row_count'), Util::backquote($this->_db_name), Util::backquote($this->_name))); return $result['row_count']; }
if ($response->isAjax()) { $response->setRequestStatus(false); $response->addJSON('message', Message::error(__('No databases selected.'))); } else { PMA_sendHeaderLocation($uri); } exit; } } // end if (ensures db exists) /** * Changes database charset if requested by the user */ if (isset($_REQUEST['submitcollation']) && isset($_REQUEST['db_collation']) && !empty($_REQUEST['db_collation'])) { list($db_charset) = explode('_', $_REQUEST['db_collation']); $sql_query = 'ALTER DATABASE ' . PMA\libraries\Util::backquote($db) . ' DEFAULT' . Util::getCharsetQueryPart($_REQUEST['db_collation']); $result = $GLOBALS['dbi']->query($sql_query); $message = Message::success(); unset($db_charset); /** * If we are in an Ajax request, let us stop the execution here. Necessary for * db charset change action on db_operations.php. If this causes a bug on * other pages, we might have to move this to a different location. */ if ($GLOBALS['is_ajax_request'] == true) { $response = PMA\libraries\Response::getInstance(); $response->setRequestStatus($message->isSuccess()); $response->addJSON('message', $message); exit; } }
// In such case we can use the value of port. $server_details['port'] = $cfg['Server']['port']; } // otherwise we leave the $server_details['port'] unset, // allowing it to take default mysql port $controllink = $GLOBALS['dbi']->connect($cfg['Server']['controluser'], $cfg['Server']['controlpass'], true, $server_details); } else { $controllink = $GLOBALS['dbi']->connect($cfg['Server']['controluser'], $cfg['Server']['controlpass'], true); } } // Connects to the server (validates user's login) /** @var DatabaseInterface $userlink */ $userlink = $GLOBALS['dbi']->connect($cfg['Server']['user'], $cfg['Server']['password'], false); // Set timestamp for the session, if required. if ($cfg['Server']['SessionTimeZone'] != '') { $sql_query_tz = 'SET ' . Util::backquote('time_zone') . ' = ' . '\'' . Util::sqlAddSlashes($cfg['Server']['SessionTimeZone']) . '\''; if (!$userlink->query($sql_query_tz)) { $error_message_tz = sprintf(__('Unable to use timezone %1$s for server %2$d. ' . 'Please check your configuration setting for ' . '[em]$cfg[\'Servers\'][%3$d][\'SessionTimeZone\'][/em]. ' . 'phpMyAdmin is currently using the default time zone ' . 'of the database server.'), $cfg['Servers'][$GLOBALS['server']]['SessionTimeZone'], $GLOBALS['server'], $GLOBALS['server']); $GLOBALS['error_handler']->addError($error_message_tz, E_USER_WARNING, '', '', false); } } if (!$controllink) { $controllink = $userlink; } $auth_plugin->storeUserCredentials(); /* Log success */ PMA_logUser($cfg['Server']['user']); if (PMA_MYSQL_INT_VERSION < $cfg['MysqlMinVersion']['internal']) { PMA_fatalError(__('You should upgrade to %s %s or later.'), array('MySQL', $cfg['MysqlMinVersion']['human'])); } /**
/** * Gets table primary key * * @return string */ protected function getKeyForTablePrimary() { $this->dbi->selectDb($this->db); $result = $this->dbi->query('SHOW KEYS FROM ' . Util::backquote($this->table) . ';'); $primary = ''; while ($row = $this->dbi->fetchAssoc($result)) { // Backups the list of primary keys if ($row['Key_name'] == 'PRIMARY') { $primary .= $row['Column_name'] . ', '; } } // end while $this->dbi->freeResult($result); return $primary; }
/** * Returns a list of allowed tabs for the current user for the given level * * @param string $level 'server', 'db' or 'table' level * * @return array list of allowed tabs */ private function _getAllowedTabs($level) { $cache_key = 'menu-levels-' . $level; if (Util::cacheExists($cache_key)) { return Util::cacheGet($cache_key); } $allowedTabs = Util::getMenuTabList($level); $cfgRelation = PMA_getRelationsParam(); if ($cfgRelation['menuswork']) { $groupTable = Util::backquote($cfgRelation['db']) . "." . Util::backquote($cfgRelation['usergroups']); $userTable = Util::backquote($cfgRelation['db']) . "." . Util::backquote($cfgRelation['users']); $sql_query = "SELECT `tab` FROM " . $groupTable . " WHERE `allowed` = 'N'" . " AND `tab` LIKE '" . $level . "%'" . " AND `usergroup` = (SELECT usergroup FROM " . $userTable . " WHERE `username` = '" . $GLOBALS['dbi']->escapeString($GLOBALS['cfg']['Server']['user']) . "')"; $result = PMA_queryAsControlUser($sql_query, false); if ($result) { while ($row = $GLOBALS['dbi']->fetchAssoc($result)) { $tabName = mb_substr($row['tab'], mb_strpos($row['tab'], '_') + 1); unset($allowedTabs[$tabName]); } } } Util::cacheSet($cache_key, $allowedTabs); return $allowedTabs; }
/** * Returns sql for fetching raw data * * @param string $sql_query The SQL to modify. * @param integer $rows Number of rows. * @param integer $pos Start position. * * @return string the modified sql query. */ private function _modifySqlQuery($sql_query, $rows, $pos) { $modified_query = 'SELECT '; // If label column is chosen add it to the query if (!empty($this->_userSpecifiedSettings['labelColumn'])) { $modified_query .= Util::backquote($this->_userSpecifiedSettings['labelColumn']) . ', '; } // Wrap the spatial column with 'ASTEXT()' function and add it $modified_query .= 'ASTEXT(' . Util::backquote($this->_userSpecifiedSettings['spatialColumn']) . ') AS ' . Util::backquote($this->_userSpecifiedSettings['spatialColumn']) . ', '; // Get the SRID $modified_query .= 'SRID(' . Util::backquote($this->_userSpecifiedSettings['spatialColumn']) . ') AS ' . Util::backquote('srid') . ' '; // Append the original query as the inner query $modified_query .= 'FROM (' . $sql_query . ') AS ' . Util::backquote('temp_gis'); // LIMIT clause if (is_numeric($rows) && $rows > 0) { $modified_query .= ' LIMIT '; if (is_numeric($pos) && $pos >= 0) { $modified_query .= $pos . ', ' . $rows; } else { $modified_query .= $rows; } } return $modified_query; }
/** * function to get distinct values count of all the column in the array $columns * * @param array $columns array of backquoted columns whose distinct values * need to be counted. * @param string $table table to which these columns belong * * @return array associative array containing the count */ function PMA_findDistinctValuesCount($columns, $table) { $result = array(); $query = 'SELECT '; foreach ($columns as $column) { if ($column) { //each column is already backquoted $query .= 'COUNT(DISTINCT ' . $column . ') as \'' . $column . '_cnt\', '; } } $query = trim($query, ', '); $query .= ' FROM (SELECT * FROM ' . Util::backquote($table) . ' LIMIT 500) as dt' . ';'; $res = $GLOBALS['dbi']->fetchResult($query, null, null, $GLOBALS['userlink']); foreach ($columns as $column) { if ($column) { $result[$column] = $res[0][$column . '_cnt']; } } return $result; }
/** * Loads the PRIMARY key. * * @return void */ protected function loadPrimaryKey() { $result = $GLOBALS['dbi']->query('SHOW INDEX FROM ' . PMA\libraries\Util::backquote($this->tableName) . ';', null, PMA\libraries\DatabaseInterface::QUERY_STORE); if ($GLOBALS['dbi']->numRows($result) > 0) { while ($row = $GLOBALS['dbi']->fetchAssoc($result)) { if ($row['Key_name'] == 'PRIMARY') { $this->primary[] = $row['Column_name']; } } } }
/** * Handles the whole import logic * * @return void */ public function doImport() { global $error, $timeout_passed, $finished, $db; $i = 0; $len = 0; $buffer = ""; /** * Read in the file via PMA_importGetNextChunk so that * it can process compressed files */ while (!($finished && $i >= $len) && !$error && !$timeout_passed) { $data = PMA_importGetNextChunk(); if ($data === false) { /* subtract data we didn't handle yet and stop processing */ $GLOBALS['offset'] -= strlen($buffer); break; } elseif ($data === true) { /* Handle rest of buffer */ } else { /* Append new data to buffer */ $buffer .= $data; unset($data); } } unset($data); /** * Disable loading of external XML entities. */ libxml_disable_entity_loader(); /** * Load the XML string * * The option LIBXML_COMPACT is specified because it can * result in increased performance without the need to * alter the code in any way. It's basically a freebee. */ $xml = @simplexml_load_string($buffer, "SimpleXMLElement", LIBXML_COMPACT); unset($buffer); /** * The XML was malformed */ if ($xml === false) { PMA\libraries\Message::error(__('The XML file specified was either malformed or incomplete.' . ' Please correct the issue and try again.'))->display(); unset($xml); $GLOBALS['finished'] = false; return; } /** * Table accumulator */ $tables = array(); /** * Row accumulator */ $rows = array(); /** * Temp arrays */ $tempRow = array(); $tempCells = array(); /** * CREATE code included (by default: no) */ $struct_present = false; /** * Analyze the data in each table */ $namespaces = $xml->getNameSpaces(true); /** * Get the database name, collation and charset */ $db_attr = $xml->children($namespaces['pma'])->{'structure_schemas'}->{'database'}; if ($db_attr instanceof SimpleXMLElement) { $db_attr = $db_attr->attributes(); $db_name = (string) $db_attr['name']; $collation = (string) $db_attr['collation']; $charset = (string) $db_attr['charset']; } else { /** * If the structure section is not present * get the database name from the data section */ $db_attr = $xml->children()->attributes(); $db_name = (string) $db_attr['name']; $collation = null; $charset = null; } /** * The XML was malformed */ if ($db_name === null) { PMA\libraries\Message::error(__('The XML file specified was either malformed or incomplete.' . ' Please correct the issue and try again.'))->display(); unset($xml); $GLOBALS['finished'] = false; return; } /** * Retrieve the structure information */ if (isset($namespaces['pma'])) { /** * Get structures for all tables * * @var SimpleXMLElement $struct */ $struct = $xml->children($namespaces['pma']); $create = array(); /** @var SimpleXMLElement $val1 */ foreach ($struct as $val1) { /** @var SimpleXMLElement $val2 */ foreach ($val1 as $val2) { // Need to select the correct database for the creation of // tables, views, triggers, etc. /** * @todo Generating a USE here blocks importing of a table * into another database. */ $attrs = $val2->attributes(); $create[] = "USE " . PMA\libraries\Util::backquote($attrs["name"]); foreach ($val2 as $val3) { /** * Remove the extra cosmetic spacing */ $val3 = str_replace(" ", "", (string) $val3); $create[] = $val3; } } } $struct_present = true; } /** * Move down the XML tree to the actual data */ $xml = $xml->children()->children(); $data_present = false; /** * Only attempt to analyze/collect data if there is data present */ if ($xml && @count($xml->children())) { $data_present = true; /** * Process all database content */ foreach ($xml as $v1) { $tbl_attr = $v1->attributes(); $isInTables = false; $num_tables = count($tables); for ($i = 0; $i < $num_tables; ++$i) { if (!strcmp($tables[$i][TBL_NAME], (string) $tbl_attr['name'])) { $isInTables = true; break; } } if (!$isInTables) { $tables[] = array((string) $tbl_attr['name']); } foreach ($v1 as $v2) { $row_attr = $v2->attributes(); if (!array_search((string) $row_attr['name'], $tempRow)) { $tempRow[] = (string) $row_attr['name']; } $tempCells[] = (string) $v2; } $rows[] = array((string) $tbl_attr['name'], $tempRow, $tempCells); $tempRow = array(); $tempCells = array(); } unset($tempRow); unset($tempCells); unset($xml); /** * Bring accumulated rows into the corresponding table */ $num_tables = count($tables); for ($i = 0; $i < $num_tables; ++$i) { $num_rows = count($rows); for ($j = 0; $j < $num_rows; ++$j) { if (!strcmp($tables[$i][TBL_NAME], $rows[$j][TBL_NAME])) { if (!isset($tables[$i][COL_NAMES])) { $tables[$i][] = $rows[$j][COL_NAMES]; } $tables[$i][ROWS][] = $rows[$j][ROWS]; } } } unset($rows); if (!$struct_present) { $analyses = array(); $len = count($tables); for ($i = 0; $i < $len; ++$i) { $analyses[] = PMA_analyzeTable($tables[$i]); } } } unset($xml); unset($tempCells); unset($rows); /** * Only build SQL from data if there is data present */ if ($data_present) { /** * Set values to NULL if they were not present * to maintain PMA_buildSQL() call integrity */ if (!isset($analyses)) { $analyses = null; if (!$struct_present) { $create = null; } } } /** * string $db_name (no backquotes) * * array $table = array(table_name, array() column_names, array()() rows) * array $tables = array of "$table"s * * array $analysis = array(array() column_types, array() column_sizes) * array $analyses = array of "$analysis"s * * array $create = array of SQL strings * * array $options = an associative array of options */ /* Set database name to the currently selected one, if applicable */ if (strlen($db)) { /* Override the database name in the XML file, if one is selected */ $db_name = $db; $options = array('create_db' => false); } else { if ($db_name === null) { $db_name = 'XML_DB'; } /* Set database collation/charset */ $options = array('db_collation' => $collation, 'db_charset' => $charset); } /* Created and execute necessary SQL statements from data */ PMA_buildSQL($db_name, $tables, $analyses, $create, $options); unset($analyses); unset($tables); unset($create); /* Commit any possible data in buffers */ PMA_importRunQuery(); }
/** * get the list of columns in given database excluding * the columns present in current table * * @param string $db selected database * @param string $table current table name * * @return string encoded list of columns present in central list for the given * database */ function PMA_getCentralColumnsListRaw($db, $table) { $cfgCentralColumns = PMA_centralColumnsGetParams(); if (empty($cfgCentralColumns)) { return json_encode(array()); } $centralTable = $cfgCentralColumns['table']; if (empty($table) || $table == '') { $query = 'SELECT * FROM ' . Util::backquote($centralTable) . ' ' . 'WHERE db_name = \'' . $db . '\';'; } else { $GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']); $columns = (array) $GLOBALS['dbi']->getColumnNames($db, $table, $GLOBALS['userlink']); $cols = ''; foreach ($columns as $col_select) { $cols .= '\'' . Util::sqlAddSlashes($col_select) . '\','; } $cols = trim($cols, ','); $query = 'SELECT * FROM ' . Util::backquote($centralTable) . ' ' . 'WHERE db_name = \'' . $db . '\''; if ($cols) { $query .= ' AND col_name NOT IN (' . $cols . ')'; } $query .= ';'; } $GLOBALS['dbi']->selectDb($cfgCentralColumns['db'], $GLOBALS['controllink']); $columns_list = (array) $GLOBALS['dbi']->fetchResult($query, null, null, $GLOBALS['controllink']); PMA_handleColumnExtra($columns_list); return json_encode($columns_list); }
/** * Prints Server Process list * * @return string */ function PMA_getHtmlForServerProcesslist() { $url_params = array(); $show_full_sql = !empty($_REQUEST['full']); if ($show_full_sql) { $url_params['full'] = 1; $full_text_link = 'server_status_processes.php' . URL::getCommon(array(), '?'); } else { $full_text_link = 'server_status_processes.php' . URL::getCommon(array('full' => 1)); } // This array contains display name and real column name of each // sortable column in the table $sortable_columns = array(array('column_name' => __('ID'), 'order_by_field' => 'Id'), array('column_name' => __('User'), 'order_by_field' => 'User'), array('column_name' => __('Host'), 'order_by_field' => 'Host'), array('column_name' => __('Database'), 'order_by_field' => 'db'), array('column_name' => __('Command'), 'order_by_field' => 'Command'), array('column_name' => __('Time'), 'order_by_field' => 'Time'), array('column_name' => __('Status'), 'order_by_field' => 'State'), array('column_name' => __('Progress'), 'order_by_field' => 'Progress'), array('column_name' => __('SQL query'), 'order_by_field' => 'Info')); $sortableColCount = count($sortable_columns); $sql_query = $show_full_sql ? 'SHOW FULL PROCESSLIST' : 'SHOW PROCESSLIST'; if (!empty($_REQUEST['order_by_field']) && !empty($_REQUEST['sort_order']) || !empty($_REQUEST['showExecuting'])) { $sql_query = 'SELECT * FROM `INFORMATION_SCHEMA`.`PROCESSLIST` '; } if (!empty($_REQUEST['showExecuting'])) { $sql_query .= ' WHERE state = "executing" '; } if (!empty($_REQUEST['order_by_field']) && !empty($_REQUEST['sort_order'])) { $sql_query .= ' ORDER BY ' . Util::backquote($_REQUEST['order_by_field']) . ' ' . $_REQUEST['sort_order']; } $result = $GLOBALS['dbi']->query($sql_query); $retval = '<table id="tableprocesslist" ' . 'class="data clearfloat noclick sortable">'; $retval .= '<thead>'; $retval .= '<tr>'; $retval .= '<th>' . __('Processes') . '</th>'; foreach ($sortable_columns as $column) { $is_sorted = !empty($_REQUEST['order_by_field']) && !empty($_REQUEST['sort_order']) && $_REQUEST['order_by_field'] == $column['order_by_field']; $column['sort_order'] = 'ASC'; if ($is_sorted && $_REQUEST['sort_order'] === 'ASC') { $column['sort_order'] = 'DESC'; } if (isset($_REQUEST['showExecuting'])) { $column['showExecuting'] = 'on'; } $retval .= '<th>'; $columnUrl = URL::getCommon($column); $retval .= '<a href="server_status_processes.php' . $columnUrl . '" '; if ($is_sorted) { $retval .= 'onmouseout="$(\'.soimg\').toggle()" ' . 'onmouseover="$(\'.soimg\').toggle()"'; } $retval .= '>'; $retval .= $column['column_name']; if ($is_sorted) { $asc_display_style = 'inline'; $desc_display_style = 'none'; if ($_REQUEST['sort_order'] === 'DESC') { $desc_display_style = 'inline'; $asc_display_style = 'none'; } $retval .= '<img class="icon ic_s_desc soimg" alt="' . __('Descending') . '" title="" src="themes/dot.gif" ' . 'style="display: ' . $desc_display_style . '" />'; $retval .= '<img class="icon ic_s_asc soimg hide" alt="' . __('Ascending') . '" title="" src="themes/dot.gif" ' . 'style="display: ' . $asc_display_style . '" />'; } $retval .= '</a>'; if (0 === --$sortableColCount) { $retval .= '<a href="' . $full_text_link . '">'; if ($show_full_sql) { $retval .= Util::getImage('s_partialtext.png', __('Truncate Shown Queries')); } else { $retval .= Util::getImage('s_fulltext.png', __('Show Full Queries')); } $retval .= '</a>'; } $retval .= '</th>'; } $retval .= '</tr>'; $retval .= '</thead>'; $retval .= '<tbody>'; while ($process = $GLOBALS['dbi']->fetchAssoc($result)) { $retval .= PMA_getHtmlForServerProcessItem($process, $show_full_sql); } $retval .= '</tbody>'; $retval .= '</table>'; return $retval; }
/** * Handles the whole import logic * * @param array &$sql_data 2-element array with sql data * * @return void */ public function doImport(&$sql_data = array()) { global $db, $table, $csv_terminated, $csv_enclosed, $csv_escaped, $csv_new_line, $csv_columns, $err_url; // $csv_replace and $csv_ignore should have been here, // but we use directly from $_POST global $error, $timeout_passed, $finished, $message; $replacements = array('\\n' => "\n", '\\t' => "\t", '\\r' => "\r"); $csv_terminated = strtr($csv_terminated, $replacements); $csv_enclosed = strtr($csv_enclosed, $replacements); $csv_escaped = strtr($csv_escaped, $replacements); $csv_new_line = strtr($csv_new_line, $replacements); $param_error = false; if (mb_strlen($csv_terminated) < 1) { $message = PMA\libraries\Message::error(__('Invalid parameter for CSV import: %s')); $message->addParam(__('Columns terminated with'), false); $error = true; $param_error = true; // The default dialog of MS Excel when generating a CSV produces a // semi-colon-separated file with no chance of specifying the // enclosing character. Thus, users who want to import this file // tend to remove the enclosing character on the Import dialog. // I could not find a test case where having no enclosing characters // confuses this script. // But the parser won't work correctly with strings so we allow just // one character. } elseif (mb_strlen($csv_enclosed) > 1) { $message = PMA\libraries\Message::error(__('Invalid parameter for CSV import: %s')); $message->addParam(__('Columns enclosed with'), false); $error = true; $param_error = true; // I could not find a test case where having no escaping characters // confuses this script. // But the parser won't work correctly with strings so we allow just // one character. } elseif (mb_strlen($csv_escaped) > 1) { $message = PMA\libraries\Message::error(__('Invalid parameter for CSV import: %s')); $message->addParam(__('Columns escaped with'), false); $error = true; $param_error = true; } elseif (mb_strlen($csv_new_line) != 1 && $csv_new_line != 'auto') { $message = PMA\libraries\Message::error(__('Invalid parameter for CSV import: %s')); $message->addParam(__('Lines terminated with'), false); $error = true; $param_error = true; } // If there is an error in the parameters entered, // indicate that immediately. if ($param_error) { PMA\libraries\Util::mysqlDie($message->getMessage(), '', false, $err_url); } $buffer = ''; $required_fields = 0; if (!$this->_getAnalyze()) { $sql_template = 'INSERT'; if (isset($_POST['csv_ignore'])) { $sql_template .= ' IGNORE'; } $sql_template .= ' INTO ' . PMA\libraries\Util::backquote($table); $tmp_fields = $GLOBALS['dbi']->getColumns($db, $table); if (empty($csv_columns)) { $fields = $tmp_fields; } else { $sql_template .= ' ('; $fields = array(); $tmp = preg_split('/,( ?)/', $csv_columns); foreach ($tmp as $key => $val) { if (count($fields) > 0) { $sql_template .= ', '; } /* Trim also `, if user already included backquoted fields */ $val = trim($val, " \t\r\n\v`"); $found = false; foreach ($tmp_fields as $field) { if ($field['Field'] == $val) { $found = true; break; } } if (!$found) { $message = PMA\libraries\Message::error(__('Invalid column (%s) specified! Ensure that columns' . ' names are spelled correctly, separated by commas' . ', and not enclosed in quotes.')); $message->addParam($val); $error = true; break; } $fields[] = $field; $sql_template .= PMA\libraries\Util::backquote($val); } $sql_template .= ') '; } $required_fields = count($fields); $sql_template .= ' VALUES ('; } // Defaults for parser $i = 0; $len = 0; $lastlen = null; $line = 1; $lasti = -1; $values = array(); $csv_finish = false; $tempRow = array(); $rows = array(); $col_names = array(); $tables = array(); $col_count = 0; $max_cols = 0; $csv_terminated_len = mb_strlen($csv_terminated); while (!($finished && $i >= $len) && !$error && !$timeout_passed) { $data = PMA_importGetNextChunk(); if ($data === false) { // subtract data we didn't handle yet and stop processing $GLOBALS['offset'] -= strlen($buffer); break; } elseif ($data === true) { // Handle rest of buffer } else { // Append new data to buffer $buffer .= $data; unset($data); // Force a trailing new line at EOF to prevent parsing problems if ($finished && $buffer) { $finalch = mb_substr($buffer, -1); if ($csv_new_line == 'auto' && $finalch != "\r" && $finalch != "\n") { $buffer .= "\n"; } elseif ($csv_new_line != 'auto' && $finalch != $csv_new_line) { $buffer .= $csv_new_line; } } // Do not parse string when we're not at the end // and don't have new line inside if ($csv_new_line == 'auto' && mb_strpos($buffer, "\r") === false && mb_strpos($buffer, "\n") === false || $csv_new_line != 'auto' && mb_strpos($buffer, $csv_new_line) === false) { continue; } } // Current length of our buffer $len = mb_strlen($buffer); // Currently parsed char $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len); $i += $csv_terminated_len - 1; } while ($i < $len) { // Deadlock protection if ($lasti == $i && $lastlen == $len) { $message = PMA\libraries\Message::error(__('Invalid format of CSV input on line %d.')); $message->addParam($line); $error = true; break; } $lasti = $i; $lastlen = $len; // This can happen with auto EOL and \r at the end of buffer if (!$csv_finish) { // Grab empty field if ($ch == $csv_terminated) { if ($i == $len - 1) { break; } $values[] = ''; $i++; $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len); $i += $csv_terminated_len - 1; } continue; } // Grab one field $fallbacki = $i; if ($ch == $csv_enclosed) { if ($i == $len - 1) { break; } $need_end = true; $i++; $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len); $i += $csv_terminated_len - 1; } } else { $need_end = false; } $fail = false; $value = ''; while ($need_end && ($ch != $csv_enclosed || $csv_enclosed == $csv_escaped) || !$need_end && !($ch == $csv_terminated || $ch == $csv_new_line || $csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n"))) { if ($ch == $csv_escaped) { if ($i == $len - 1) { $fail = true; break; } $i++; $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len); $i += $csv_terminated_len - 1; } if ($csv_enclosed == $csv_escaped && ($ch == $csv_terminated || $ch == $csv_new_line || $csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n"))) { break; } } $value .= $ch; if ($i == $len - 1) { if (!$finished) { $fail = true; } break; } $i++; $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len); $i += $csv_terminated_len - 1; } } // unquoted NULL string if (false === $need_end && $value === 'NULL') { $value = null; } if ($fail) { $i = $fallbacki; $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $i += $csv_terminated_len - 1; } break; } // Need to strip trailing enclosing char? if ($need_end && $ch == $csv_enclosed) { if ($finished && $i == $len - 1) { $ch = null; } elseif ($i == $len - 1) { $i = $fallbacki; $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $i += $csv_terminated_len - 1; } break; } else { $i++; $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len); $i += $csv_terminated_len - 1; } } } // Are we at the end? if ($ch == $csv_new_line || $csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n") || $finished && $i == $len - 1) { $csv_finish = true; } // Go to next char if ($ch == $csv_terminated) { if ($i == $len - 1) { $i = $fallbacki; $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $i += $csv_terminated_len - 1; } break; } $i++; $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len); $i += $csv_terminated_len - 1; } } // If everything went okay, store value $values[] = $value; } // End of line if ($csv_finish || $ch == $csv_new_line || $csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n")) { if ($csv_new_line == 'auto' && $ch == "\r") { // Handle "\r\n" if ($i >= $len - 2 && !$finished) { break; // We need more data to decide new line } if (mb_substr($buffer, $i + 1, 1) == "\n") { $i++; } } // We didn't parse value till the end of line, so there was // empty one if (!$csv_finish) { $values[] = ''; } if ($this->_getAnalyze()) { foreach ($values as $val) { $tempRow[] = $val; ++$col_count; } if ($col_count > $max_cols) { $max_cols = $col_count; } $col_count = 0; $rows[] = $tempRow; $tempRow = array(); } else { // Do we have correct count of values? if (count($values) != $required_fields) { // Hack for excel if ($values[count($values) - 1] == ';') { unset($values[count($values) - 1]); } else { $message = PMA\libraries\Message::error(__('Invalid column count in CSV input' . ' on line %d.')); $message->addParam($line); $error = true; break; } } $first = true; $sql = $sql_template; foreach ($values as $key => $val) { if (!$first) { $sql .= ', '; } if ($val === null) { $sql .= 'NULL'; } else { $sql .= '\'' . PMA\libraries\Util::sqlAddSlashes($val) . '\''; } $first = false; } $sql .= ')'; if (isset($_POST['csv_replace'])) { $sql .= " ON DUPLICATE KEY UPDATE "; foreach ($fields as $field) { $fieldName = PMA\libraries\Util::backquote($field['Field']); $sql .= $fieldName . " = VALUES(" . $fieldName . "), "; } $sql = rtrim($sql, ', '); } /** * @todo maybe we could add original line to verbose * SQL in comment */ PMA_importRunQuery($sql, $sql, $sql_data); } $line++; $csv_finish = false; $values = array(); $buffer = mb_substr($buffer, $i + 1); $len = mb_strlen($buffer); $i = 0; $lasti = -1; $ch = mb_substr($buffer, 0, 1); } } // End of parser loop } // End of import loop if ($this->_getAnalyze()) { /* Fill out all rows */ $num_rows = count($rows); for ($i = 0; $i < $num_rows; ++$i) { for ($j = count($rows[$i]); $j < $max_cols; ++$j) { $rows[$i][] = 'NULL'; } } if (isset($_REQUEST['csv_col_names'])) { $col_names = array_splice($rows, 0, 1); $col_names = $col_names[0]; // MySQL column names can't end with a space character. foreach ($col_names as $key => $col_name) { $col_names[$key] = rtrim($col_name); } } if (isset($col_names) && count($col_names) != $max_cols || !isset($col_names)) { // Fill out column names for ($i = 0; $i < $max_cols; ++$i) { $col_names[] = 'COL ' . ($i + 1); } } if (mb_strlen($db)) { $result = $GLOBALS['dbi']->fetchResult('SHOW TABLES'); $tbl_name = 'TABLE ' . (count($result) + 1); } else { $tbl_name = 'TBL_NAME'; } $tables[] = array($tbl_name, $col_names, $rows); /* Obtain the best-fit MySQL types for each column */ $analyses = array(); $analyses[] = PMA_analyzeTable($tables[0]); /** * string $db_name (no backquotes) * * array $table = array(table_name, array() column_names, array()() rows) * array $tables = array of "$table"s * * array $analysis = array(array() column_types, array() column_sizes) * array $analyses = array of "$analysis"s * * array $create = array of SQL strings * * array $options = an associative array of options */ /* Set database name to the currently selected one, if applicable */ list($db_name, $options) = $this->getDbnameAndOptions($db, 'CSV_DB'); /* Non-applicable parameters */ $create = null; /* Created and execute necessary SQL statements from data */ PMA_buildSQL($db_name, $tables, $analyses, $create, $options, $sql_data); unset($tables); unset($analyses); } // Commit any possible data in buffers PMA_importRunQuery('', '', $sql_data); if (count($values) != 0 && !$error) { $message = PMA\libraries\Message::error(__('Invalid format of CSV input on line %d.')); $message->addParam($line); $error = true; } }
/** * Gets the list of tables in the current db, taking into account * that they might be "in use" * * @param string $db database name * @param object $db_info_result result set * * @return array $tables list of tables * */ public static function getTablesWhenOpen($db, $db_info_result) { $sot_cache = $tables = array(); while ($tmp = $GLOBALS['dbi']->fetchAssoc($db_info_result)) { $sot_cache[$tmp['Table']] = true; } $GLOBALS['dbi']->freeResult($db_info_result); // is there at least one "in use" table? if (isset($sot_cache)) { $tblGroupSql = ""; $whereAdded = false; if (PMA_isValid($_REQUEST['tbl_group'])) { $group = Util::escapeMysqlWildcards($_REQUEST['tbl_group']); $groupWithSeparator = Util::escapeMysqlWildcards( $_REQUEST['tbl_group'] . $GLOBALS['cfg']['NavigationTreeTableSeparator'] ); $tblGroupSql .= " WHERE (" . Util::backquote('Tables_in_' . $db) . " LIKE '" . $groupWithSeparator . "%'" . " OR " . Util::backquote('Tables_in_' . $db) . " LIKE '" . $group . "')"; $whereAdded = true; } if (PMA_isValid($_REQUEST['tbl_type'], array('table', 'view'))) { $tblGroupSql .= $whereAdded ? " AND" : " WHERE"; if ($_REQUEST['tbl_type'] == 'view') { $tblGroupSql .= " `Table_type` != 'BASE TABLE'"; } else { $tblGroupSql .= " `Table_type` = 'BASE TABLE'"; } } $db_info_result = $GLOBALS['dbi']->query( 'SHOW FULL TABLES FROM ' . Util::backquote($db) . $tblGroupSql, null, DatabaseInterface::QUERY_STORE ); unset($tblGroupSql, $whereAdded); if ($db_info_result && $GLOBALS['dbi']->numRows($db_info_result) > 0) { $names = array(); while ($tmp = $GLOBALS['dbi']->fetchRow($db_info_result)) { if (! isset($sot_cache[$tmp[0]])) { $names[] = $tmp[0]; } else { // table in use $tables[$tmp[0]] = array( 'TABLE_NAME' => $tmp[0], 'ENGINE' => '', 'TABLE_TYPE' => '', 'TABLE_ROWS' => 0, 'TABLE_COMMENT' => '', ); } } // end while if (count($names) > 0) { $tables = array_merge( $tables, $GLOBALS['dbi']->getTablesFull($db, $names) ); } if ($GLOBALS['cfg']['NaturalOrder']) { uksort($tables, 'strnatcasecmp'); } } elseif ($db_info_result) { $GLOBALS['dbi']->freeResult($db_info_result); } unset($sot_cache); } return $tables; }
/** * returns details about the TRIGGERs for a specific table or database * * @param string $db db name * @param string $table table name * @param string $delimiter the delimiter to use (may be empty) * * @return array information about triggers (may be empty) */ public function getTriggers($db, $table = '', $delimiter = '//') { $result = array(); if (!$GLOBALS['cfg']['Server']['DisableIS']) { $query = 'SELECT TRIGGER_SCHEMA, TRIGGER_NAME, EVENT_MANIPULATION' . ', EVENT_OBJECT_TABLE, ACTION_TIMING, ACTION_STATEMENT' . ', EVENT_OBJECT_SCHEMA, EVENT_OBJECT_TABLE, DEFINER' . ' FROM information_schema.TRIGGERS' . ' WHERE EVENT_OBJECT_SCHEMA ' . Util::getCollateForIS() . '=' . ' \'' . Util::sqlAddSlashes($db) . '\''; if (!empty($table)) { $query .= " AND EVENT_OBJECT_TABLE " . Util::getCollateForIS() . " = '" . Util::sqlAddSlashes($table) . "';"; } } else { $query = "SHOW TRIGGERS FROM " . Util::backquote($db); if (!empty($table)) { $query .= " LIKE '" . Util::sqlAddSlashes($table, true) . "';"; } } if ($triggers = $this->fetchResult($query)) { foreach ($triggers as $trigger) { if ($GLOBALS['cfg']['Server']['DisableIS']) { $trigger['TRIGGER_NAME'] = $trigger['Trigger']; $trigger['ACTION_TIMING'] = $trigger['Timing']; $trigger['EVENT_MANIPULATION'] = $trigger['Event']; $trigger['EVENT_OBJECT_TABLE'] = $trigger['Table']; $trigger['ACTION_STATEMENT'] = $trigger['Statement']; $trigger['DEFINER'] = $trigger['Definer']; } $one_result = array(); $one_result['name'] = $trigger['TRIGGER_NAME']; $one_result['table'] = $trigger['EVENT_OBJECT_TABLE']; $one_result['action_timing'] = $trigger['ACTION_TIMING']; $one_result['event_manipulation'] = $trigger['EVENT_MANIPULATION']; $one_result['definition'] = $trigger['ACTION_STATEMENT']; $one_result['definer'] = $trigger['DEFINER']; // do not prepend the schema name; this way, importing the // definition into another schema will work $one_result['full_trigger_name'] = Util::backquote($trigger['TRIGGER_NAME']); $one_result['drop'] = 'DROP TRIGGER IF EXISTS ' . $one_result['full_trigger_name']; $one_result['create'] = 'CREATE TRIGGER ' . $one_result['full_trigger_name'] . ' ' . $trigger['ACTION_TIMING'] . ' ' . $trigger['EVENT_MANIPULATION'] . ' ON ' . Util::backquote($trigger['EVENT_OBJECT_TABLE']) . "\n" . ' FOR EACH ROW ' . $trigger['ACTION_STATEMENT'] . "\n" . $delimiter . "\n"; $result[] = $one_result; } } // Sort results by name $name = array(); foreach ($result as $value) { $name[] = $value['name']; } array_multisort($name, SORT_ASC, $result); return $result; }
/** * Returns the list of events inside this database * * @param int $pos The offset of the list within the results * @param string $searchClause A string used to filter the results of the query * * @return array */ private function _getEvents($pos, $searchClause) { $maxItems = $GLOBALS['cfg']['MaxNavigationItems']; $retval = array(); $db = $this->real_name; if (!$GLOBALS['cfg']['Server']['DisableIS']) { $escdDb = Util::sqlAddSlashes($db); $query = "SELECT `EVENT_NAME` AS `name` "; $query .= "FROM `INFORMATION_SCHEMA`.`EVENTS` "; $query .= "WHERE `EVENT_SCHEMA` " . Util::getCollateForIS() . "='{$escdDb}' "; if (!empty($searchClause)) { $query .= "AND `EVENT_NAME` LIKE '%"; $query .= Util::sqlAddSlashes($searchClause, true); $query .= "%'"; } $query .= "ORDER BY `EVENT_NAME` ASC "; $query .= "LIMIT " . intval($pos) . ", {$maxItems}"; $retval = $GLOBALS['dbi']->fetchResult($query); } else { $escdDb = Util::backquote($db); $query = "SHOW EVENTS FROM {$escdDb} "; if (!empty($searchClause)) { $query .= "WHERE `Name` LIKE '%"; $query .= Util::sqlAddSlashes($searchClause, true); $query .= "%'"; } $handle = $GLOBALS['dbi']->tryQuery($query); if ($handle !== false) { $count = 0; if ($GLOBALS['dbi']->dataSeek($handle, $pos)) { while ($arr = $GLOBALS['dbi']->fetchArray($handle)) { if ($count < $maxItems) { $retval[] = $arr['Name']; $count++; } else { break; } } } } } return $retval; }
/** * Prepares the displayable content of a data cell in Browse mode, * taking into account foreign key description field and transformations * * @param string $class css classes for the td element * @param bool $condition_field whether the column is a part of * the where clause * @param array $analyzed_sql_results the analyzed query * @param object $meta the meta-information about the * field * @param array $map the list of relations * @param string $data data * @param object|string $transformation_plugin transformation plugin. * Can also be the default function: * PMA_mimeDefaultFunction * @param string $default_function default function * @param string $nowrap 'nowrap' if the content should * not be wrapped * @param string $where_comparison data for the where clause * @param array $transform_options options for transformation * @param bool $is_field_truncated whether the field is truncated * @param string $original_length of a truncated column, or '' * * @return string formatted data * * @access private * * @see _getDataCellForNumericColumns(), _getDataCellForGeometryColumns(), * _getDataCellForNonNumericColumns(), * */ private function _getRowData($class, $condition_field, $analyzed_sql_results, $meta, $map, $data, $transformation_plugin, $default_function, $nowrap, $where_comparison, $transform_options, $is_field_truncated, $original_length = '') { $relational_display = $_SESSION['tmpval']['relational_display']; $printview = $this->__get('printview'); $decimals = isset($meta->decimals) ? $meta->decimals : '-1'; $result = '<td data-decimals="' . $decimals . '"' . ' data-type="' . $meta->type . '"'; if (!empty($original_length)) { // cannot use data-original-length $result .= ' data-originallength="' . $original_length . '"'; } $result .= ' class="' . $this->_addClass($class, $condition_field, $meta, $nowrap, $is_field_truncated, $transformation_plugin, $default_function) . '">'; if (!empty($analyzed_sql_results['statement']->expr)) { foreach ($analyzed_sql_results['statement']->expr as $expr) { if (empty($expr->alias) || empty($expr->column)) { continue; } if (strcasecmp($meta->name, $expr->alias) == 0) { $meta->name = $expr->column; } } } if (isset($map[$meta->name])) { // Field to display from the foreign table? if (isset($map[$meta->name][2]) && mb_strlen($map[$meta->name][2])) { $dispval = $this->_getFromForeign($map, $meta, $where_comparison); } else { $dispval = ''; } // end if... else... if (isset($printview) && $printview == '1') { $result .= ($transformation_plugin != $default_function ? $transformation_plugin->applyTransformation($data, $transform_options, $meta) : $default_function($data)) . ' <code>[->' . $dispval . ']</code>'; } else { if ($relational_display == self::RELATIONAL_KEY) { // user chose "relational key" in the display options, so // the title contains the display field $title = !empty($dispval) ? ' title="' . htmlspecialchars($dispval) . '"' : ''; } else { $title = ' title="' . htmlspecialchars($data) . '"'; } $_url_params = array('db' => $map[$meta->name][3], 'table' => $map[$meta->name][0], 'pos' => '0', 'sql_query' => 'SELECT * FROM ' . Util::backquote($map[$meta->name][3]) . '.' . Util::backquote($map[$meta->name][0]) . ' WHERE ' . Util::backquote($map[$meta->name][1]) . $where_comparison); $result .= '<a class="ajax" href="sql.php' . PMA_URL_getCommon($_url_params) . '"' . $title . '>'; if ($transformation_plugin != $default_function) { // always apply a transformation on the real data, // not on the display field $result .= $transformation_plugin->applyTransformation($data, $transform_options, $meta); } else { if ($relational_display == self::RELATIONAL_DISPLAY_COLUMN && !empty($map[$meta->name][2])) { // user chose "relational display field" in the // display options, so show display field in the cell $result .= $default_function($dispval); } else { // otherwise display data in the cell $result .= $default_function($data); } } $result .= '</a>'; } } else { $result .= $transformation_plugin != $default_function ? $transformation_plugin->applyTransformation($data, $transform_options, $meta) : $default_function($data); } $result .= '</td>' . "\n"; return $result; }
/** * Gets the count of hidden elements for each database * * @return array array containing the count of hidden elements for each database */ public function getNavigationHidingData() { $cfgRelation = PMA_getRelationsParam(); if ($cfgRelation['navwork']) { $navTable = Util::backquote($cfgRelation['db']) . "." . Util::backquote($cfgRelation['navigationhiding']); $sqlQuery = "SELECT `db_name`, COUNT(*) AS `count` FROM " . $navTable . " WHERE `username`='" . Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . "'" . " GROUP BY `db_name`"; $counts = $GLOBALS['dbi']->fetchResult($sqlQuery, 'db_name', 'count', $GLOBALS['controllink']); return $counts; } return null; }
/** * Adjust the privileges after copying a table * * @param string $oldDb Database name before table copying * @param string $oldTable Table name before table copying * @param string $newDb Database name after table copying * @param string $newTable Table name after table copying * * @return void */ function PMA_AdjustPrivileges_copyTable($oldDb, $oldTable, $newDb, $newTable) { if (isset($GLOBALS['table_priv']) && $GLOBALS['table_priv'] && isset($GLOBALS['col_priv']) && $GLOBALS['col_priv'] && isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv']) { $GLOBALS['dbi']->selectDb('mysql'); // For Table Specific privileges $query_table_specific_old = 'SELECT * FROM ' . Util::backquote('tables_priv') . ' where ' . 'Db = "' . $oldDb . '" AND Table_name = "' . $oldTable . '";'; $old_privs_table = $GLOBALS['dbi']->fetchResult($query_table_specific_old, 0); foreach ($old_privs_table as $old_priv) { $newDb_table_privs_query = 'INSERT INTO ' . Util::backquote('tables_priv') . ' VALUES("' . $old_priv[0] . '", "' . $newDb . '", "' . $old_priv[2] . '", "' . $newTable . '", "' . $old_priv[4] . '", "' . $old_priv[5] . '", "' . $old_priv[6] . '", "' . $old_priv[7] . '");'; $GLOBALS['dbi']->query($newDb_table_privs_query); } // For Column Specific privileges $query_col_specific_old = 'SELECT * FROM ' . Util::backquote('columns_priv') . ' WHERE ' . 'Db = "' . $oldDb . '" AND Table_name = "' . $oldTable . '";'; $old_privs_col = $GLOBALS['dbi']->fetchResult($query_col_specific_old, 0); foreach ($old_privs_col as $old_priv) { $newDb_col_privs_query = 'INSERT INTO ' . Util::backquote('columns_priv') . ' VALUES("' . $old_priv[0] . '", "' . $newDb . '", "' . $old_priv[2] . '", "' . $newTable . '", "' . $old_priv[4] . '", "' . $old_priv[5] . '", "' . $old_priv[6] . '");'; $GLOBALS['dbi']->query($newDb_col_privs_query); } // Finally FLUSH the new privileges $flush_query = "FLUSH PRIVILEGES;"; $GLOBALS['dbi']->query($flush_query); } }
/** * Returns the tracking table * * @return string tracking table */ private static function _getTrackingTable() { $cfgRelation = PMA_getRelationsParam(); return Util::backquote($cfgRelation['db']) . '.' . Util::backquote($cfgRelation['tracking']); }
/** * Outputs the content of a table in MediaWiki format * * @param string $db database name * @param string $table table name * @param string $crlf the end of line sequence * @param string $error_url the url to go back in case of error * @param string $sql_query SQL query for obtaining data * @param array $aliases Aliases of db/table/columns * * @return bool Whether it succeeded */ public function exportData($db, $table, $crlf, $error_url, $sql_query, $aliases = array()) { $db_alias = $db; $table_alias = $table; $this->initAlias($aliases, $db_alias, $table_alias); // Print data comment $output = $this->_exportComment("Table data for " . PMA\libraries\Util::backquote($table_alias)); // Begin the table construction // Use the "wikitable" class for style // Use the "sortable" class for allowing tables to be sorted by column $output .= "{| class=\"wikitable sortable\" style=\"text-align:center;\"" . $this->_exportCRLF(); // Add the table name if (isset($GLOBALS['mediawiki_caption'])) { $output .= "|+'''" . $table_alias . "'''" . $this->_exportCRLF(); } // Add the table headers if (isset($GLOBALS['mediawiki_headers'])) { // Get column names $column_names = $GLOBALS['dbi']->getColumnNames($db, $table); // Add column names as table headers if (!is_null($column_names)) { // Use '|-' for separating rows $output .= "|-" . $this->_exportCRLF(); // Use '!' for separating table headers foreach ($column_names as $column) { if (!empty($aliases[$db]['tables'][$table]['columns'][$column])) { $column = $aliases[$db]['tables'][$table]['columns'][$column]; } $output .= " ! " . $column . "" . $this->_exportCRLF(); } } } // Get the table data from the database $result = $GLOBALS['dbi']->query($sql_query, null, PMA\libraries\DatabaseInterface::QUERY_UNBUFFERED); $fields_cnt = $GLOBALS['dbi']->numFields($result); while ($row = $GLOBALS['dbi']->fetchRow($result)) { $output .= "|-" . $this->_exportCRLF(); // Use '|' for separating table columns for ($i = 0; $i < $fields_cnt; ++$i) { $output .= " | " . $row[$i] . "" . $this->_exportCRLF(); } } // End table construction $output .= "|}" . str_repeat($this->_exportCRLF(), 2); return PMA_exportOutputHandler($output); }
/** * Handles the whole import logic * * @param array &$sql_data 2-element array with sql data * * @return void */ public function doImport(&$sql_data = array()) { global $finished, $import_file, $compression, $charset_conversion, $table; global $ldi_local_option, $ldi_replace, $ldi_ignore, $ldi_terminated, $ldi_enclosed, $ldi_escaped, $ldi_new_line, $skip_queries, $ldi_columns; if ($import_file == 'none' || $compression != 'none' || $charset_conversion) { // We handle only some kind of data! $GLOBALS['message'] = PMA\libraries\Message::error(__('This plugin does not support compressed imports!')); $GLOBALS['error'] = true; return; } $sql = 'LOAD DATA'; if (isset($ldi_local_option)) { $sql .= ' LOCAL'; } $sql .= ' INFILE \'' . $GLOBALS['dbi']->escapeString($import_file) . '\''; if (isset($ldi_replace)) { $sql .= ' REPLACE'; } elseif (isset($ldi_ignore)) { $sql .= ' IGNORE'; } $sql .= ' INTO TABLE ' . PMA\libraries\Util::backquote($table); if (strlen($ldi_terminated) > 0) { $sql .= ' FIELDS TERMINATED BY \'' . $ldi_terminated . '\''; } if (strlen($ldi_enclosed) > 0) { $sql .= ' ENCLOSED BY \'' . $GLOBALS['dbi']->escapeString($ldi_enclosed) . '\''; } if (strlen($ldi_escaped) > 0) { $sql .= ' ESCAPED BY \'' . $GLOBALS['dbi']->escapeString($ldi_escaped) . '\''; } if (strlen($ldi_new_line) > 0) { if ($ldi_new_line == 'auto') { $ldi_new_line = PMA\libraries\Util::whichCrlf() == "\n" ? '\\n' : '\\r\\n'; } $sql .= ' LINES TERMINATED BY \'' . $ldi_new_line . '\''; } if ($skip_queries > 0) { $sql .= ' IGNORE ' . $skip_queries . ' LINES'; $skip_queries = 0; } if (strlen($ldi_columns) > 0) { $sql .= ' ('; $tmp = preg_split('/,( ?)/', $ldi_columns); $cnt_tmp = count($tmp); for ($i = 0; $i < $cnt_tmp; $i++) { if ($i > 0) { $sql .= ', '; } /* Trim also `, if user already included backquoted fields */ $sql .= PMA\libraries\Util::backquote(trim($tmp[$i], " \t\r\n\v`")); } // end for $sql .= ')'; } PMA_importRunQuery($sql, $sql, $sql_data); PMA_importRunQuery('', '', $sql_data); $finished = true; }
/** * Handles requests for executing a routine * * @return void */ function PMA_RTN_handleExecute() { global $_GET, $_POST, $_REQUEST, $GLOBALS, $db; /** * Handle all user requests other than the default of listing routines */ if (!empty($_REQUEST['execute_routine']) && !empty($_REQUEST['item_name'])) { // Build the queries $routine = PMA_RTN_getDataFromName($_REQUEST['item_name'], $_REQUEST['item_type'], false, true); if ($routine === false) { $message = __('Error in processing request:') . ' '; $message .= sprintf(PMA_RTE_getWord('not_found'), htmlspecialchars(PMA\libraries\Util::backquote($_REQUEST['item_name'])), htmlspecialchars(PMA\libraries\Util::backquote($db))); $message = Message::error($message); if ($GLOBALS['is_ajax_request']) { $response = PMA\libraries\Response::getInstance(); $response->setRequestStatus(false); $response->addJSON('message', $message); exit; } else { echo $message->getDisplay(); unset($_POST); } } $queries = array(); $end_query = array(); $args = array(); $all_functions = $GLOBALS['PMA_Types']->getAllFunctions(); for ($i = 0; $i < $routine['item_num_params']; $i++) { if (isset($_REQUEST['params'][$routine['item_param_name'][$i]])) { $value = $_REQUEST['params'][$routine['item_param_name'][$i]]; if (is_array($value)) { // is SET type $value = implode(',', $value); } $value = $GLOBALS['dbi']->escapeString($value); if (!empty($_REQUEST['funcs'][$routine['item_param_name'][$i]]) && in_array($_REQUEST['funcs'][$routine['item_param_name'][$i]], $all_functions)) { $queries[] = "SET @p{$i}=" . $_REQUEST['funcs'][$routine['item_param_name'][$i]] . "('{$value}');\n"; } else { $queries[] = "SET @p{$i}='{$value}';\n"; } $args[] = "@p{$i}"; } else { $args[] = "@p{$i}"; } if ($routine['item_type'] == 'PROCEDURE') { if ($routine['item_param_dir'][$i] == 'OUT' || $routine['item_param_dir'][$i] == 'INOUT') { $end_query[] = "@p{$i} AS " . PMA\libraries\Util::backquote($routine['item_param_name'][$i]); } } } if ($routine['item_type'] == 'PROCEDURE') { $queries[] = "CALL " . PMA\libraries\Util::backquote($routine['item_name']) . "(" . implode(', ', $args) . ");\n"; if (count($end_query)) { $queries[] = "SELECT " . implode(', ', $end_query) . ";\n"; } } else { $queries[] = "SELECT " . PMA\libraries\Util::backquote($routine['item_name']) . "(" . implode(', ', $args) . ") " . "AS " . PMA\libraries\Util::backquote($routine['item_name']) . ";\n"; } // Get all the queries as one SQL statement $multiple_query = implode("", $queries); $outcome = true; $affected = 0; // Execute query if (!$GLOBALS['dbi']->tryMultiQuery($multiple_query)) { $outcome = false; } // Generate output if ($outcome) { // Pass the SQL queries through the "pretty printer" $output = PMA\libraries\Util::formatSql(implode($queries, "\n")); // Display results $output .= "<fieldset><legend>"; $output .= sprintf(__('Execution results of routine %s'), PMA\libraries\Util::backquote(htmlspecialchars($routine['item_name']))); $output .= "</legend>"; $nbResultsetToDisplay = 0; do { $result = $GLOBALS['dbi']->storeResult(); $num_rows = $GLOBALS['dbi']->numRows($result); if ($result !== false && $num_rows > 0) { $output .= "<table><tr>"; foreach ($GLOBALS['dbi']->getFieldsMeta($result) as $field) { $output .= "<th>"; $output .= htmlspecialchars($field->name); $output .= "</th>"; } $output .= "</tr>"; $color_class = 'odd'; while ($row = $GLOBALS['dbi']->fetchAssoc($result)) { $output .= "<tr>" . browseRow($row, $color_class) . "</tr>"; $color_class = $color_class == 'odd' ? 'even' : 'odd'; } $output .= "</table>"; $nbResultsetToDisplay++; $affected = $num_rows; } if (!$GLOBALS['dbi']->moreResults()) { break; } $output .= "<br/>"; $GLOBALS['dbi']->freeResult($result); } while ($GLOBALS['dbi']->nextResult()); $output .= "</fieldset>"; $message = __('Your SQL query has been executed successfully.'); if ($routine['item_type'] == 'PROCEDURE') { $message .= '<br />'; // TODO : message need to be modified according to the // output from the routine $message .= sprintf(_ngettext('%d row affected by the last statement inside the ' . 'procedure.', '%d rows affected by the last statement inside the ' . 'procedure.', $affected), $affected); } $message = Message::success($message); if ($nbResultsetToDisplay == 0) { $notice = __('MySQL returned an empty result set (i.e. zero rows).'); $output .= Message::notice($notice)->getDisplay(); } } else { $output = ''; $message = Message::error(sprintf(__('The following query has failed: "%s"'), htmlspecialchars($multiple_query)) . '<br /><br />' . __('MySQL said: ') . $GLOBALS['dbi']->getError(null)); } // Print/send output if ($GLOBALS['is_ajax_request']) { $response = PMA\libraries\Response::getInstance(); $response->setRequestStatus($message->isSuccess()); $response->addJSON('message', $message->getDisplay() . $output); $response->addJSON('dialog', false); exit; } else { echo $message->getDisplay(), $output; if ($message->isError()) { // At least one query has failed, so shouldn't // execute any more queries, so we quit. exit; } unset($_POST); // Now deliberately fall through to displaying the routines list } return; } else { if (!empty($_GET['execute_dialog']) && !empty($_GET['item_name'])) { /** * Display the execute form for a routine. */ $routine = PMA_RTN_getDataFromName($_GET['item_name'], $_GET['item_type'], true, true); if ($routine !== false) { $form = PMA_RTN_getExecuteForm($routine); if ($GLOBALS['is_ajax_request'] == true) { $title = __("Execute routine") . " " . PMA\libraries\Util::backquote(htmlentities($_GET['item_name'], ENT_QUOTES)); $response = PMA\libraries\Response::getInstance(); $response->addJSON('message', $form); $response->addJSON('title', $title); $response->addJSON('dialog', true); } else { echo "\n\n<h2>" . __("Execute routine") . "</h2>\n\n"; echo $form; } exit; } else { if ($GLOBALS['is_ajax_request'] == true) { $message = __('Error in processing request:') . ' '; $message .= sprintf(PMA_RTE_getWord('not_found'), htmlspecialchars(PMA\libraries\Util::backquote($_REQUEST['item_name'])), htmlspecialchars(PMA\libraries\Util::backquote($db))); $message = Message::error($message); $response = PMA\libraries\Response::getInstance(); $response->setRequestStatus(false); $response->addJSON('message', $message); exit; } } } } }
/** * Loads relations for a given table into the $relations array * * @param array &$relations array of relations * @param string $oneTable the table * * @return void */ private function _loadRelationsForTable(&$relations, $oneTable) { $relations[$oneTable] = array(); $foreigners = PMA_getForeigners($GLOBALS['db'], $oneTable); foreach ($foreigners as $field => $foreigner) { // Foreign keys data if ($field == 'foreign_keys_data') { foreach ($foreigner as $oneKey) { $clauses = array(); // There may be multiple column relations foreach ($oneKey['index_list'] as $index => $oneField) { $clauses[] = Util::backquote($oneTable) . "." . Util::backquote($oneField) . " = " . Util::backquote($oneKey['ref_table_name']) . "." . Util::backquote($oneKey['ref_index_list'][$index]); } // Combine multiple column relations with AND $relations[$oneTable][$oneKey['ref_table_name']] = implode(" AND ", $clauses); } } else { // Internal relations $relations[$oneTable][$foreigner['foreign_table']] = Util::backquote($oneTable) . "." . Util::backquote($field) . " = " . Util::backquote($foreigner['foreign_table']) . "." . Util::backquote($foreigner['foreign_field']); } } }