/** * return html for Print View Columns * * @param bool $tbl_is_view whether table is a view * @param array $columns columns list * @param array $analyzed_sql analyzed sql * @param bool $have_rel have relation? * @param array $res_rel relations array * @param string $db database name * @param string $table table name * @param array $cfgRelation config from PMA_getRelationsParam * * @return string */ function PMA_getHtmlForPrintViewColumns($tbl_is_view, $columns, $analyzed_sql, $have_rel, $res_rel, $db, $table, $cfgRelation) { $html = ''; $primary = PMA_Index::getPrimary($table, $db); foreach ($columns as $row) { $extracted_columnspec = PMA_Util::extractColumnSpec($row['Type']); $type = $extracted_columnspec['print_type']; if (!isset($row['Default'])) { if ($row['Null'] != '' && $row['Null'] != 'NO') { $row['Default'] = '<i>NULL</i>'; } } else { $row['Default'] = htmlspecialchars($row['Default']); } $field_name = htmlspecialchars($row['Field']); if (!$tbl_is_view) { // here, we have a TIMESTAMP that SHOW FULL COLUMNS reports as having // the NULL attribute, but SHOW CREATE TABLE says the contrary. // Believe the latter. /** * @todo merge this logic with the one in tbl_structure.php * or move it in a function similar to $GLOBALS['dbi']->getColumnsFull() * but based on SHOW CREATE TABLE because information_schema * cannot be trusted in this case (MySQL bug) */ $analyzed_for_field = $analyzed_sql[0]['create_table_fields'][$field_name]; if (!empty($analyzed_for_field['type']) && $analyzed_for_field['type'] == 'TIMESTAMP' && $analyzed_for_field['timestamp_not_null']) { $row['Null'] = ''; } } $html .= "\n"; $html .= '<tr><td>'; $html .= ' ' . $field_name . "\n"; if ($primary && $primary->hasColumn($field_name)) { $html .= ' <em>(' . __('Primary') . ')</em>'; } $html .= "\n"; $html .= '</td>'; $html .= '<td>' . htmlspecialchars($type) . '<bdo dir="ltr"></bdo></td>'; $html .= '<td>'; $html .= $row['Null'] == '' || $row['Null'] == 'NO' ? __('No') : __('Yes'); $html .= ' </td>'; $html .= '<td>'; if (isset($row['Default'])) { $html .= $row['Default']; } $html .= ' </td>'; if ($have_rel) { $html .= ' <td>'; $foreigner = PMA_searchColumnInForeigners($res_rel, $field_name); if ($foreigner) { $html .= htmlspecialchars($foreigner['foreign_table'] . ' -> ' . $foreigner['foreign_field']); } $html .= ' </td>' . "\n"; } $html .= ' <td>'; $comments = PMA_getComments($db, $table); if (isset($comments[$field_name])) { $html .= htmlspecialchars($comments[$field_name]); } $html .= ' </td>' . "\n"; if ($cfgRelation['mimework']) { $mime_map = PMA_getMIME($db, $table, true); $html .= ' <td>'; if (isset($mime_map[$field_name])) { $html .= htmlspecialchars(str_replace('_', '/', $mime_map[$field_name]['mimetype'])); } $html .= ' </td>' . "\n"; } $html .= '</tr>'; } // end foreach return $html; }
/** * Removes a foreign relation * * @param string $T1 foreign db.table * @param string $F1 foreign field * @param string $T2 master db.table * @param string $F2 master field * * @return array array of success/failure and message */ function PMA_removeRelation($T1, $F1, $T2, $F2) { list($DB1, $T1) = explode(".", $T1); list($DB2, $T2) = explode(".", $T2); $tables = $GLOBALS['dbi']->getTablesFull($DB1, $T1); $type_T1 = mb_strtoupper($tables[$T1]['ENGINE']); $tables = $GLOBALS['dbi']->getTablesFull($DB2, $T2); $type_T2 = mb_strtoupper($tables[$T2]['ENGINE']); if (PMA_Util::isForeignKeySupported($type_T1) && PMA_Util::isForeignKeySupported($type_T2) && $type_T1 == $type_T2) { // InnoDB $existrel_foreign = PMA_getForeigners($DB2, $T2, '', 'foreign'); $foreigner = PMA_searchColumnInForeigners($existrel_foreign, $F2); if (isset($foreigner['constraint'])) { $upd_query = 'ALTER TABLE ' . PMA_Util::backquote($DB2) . '.' . PMA_Util::backquote($T2) . ' DROP FOREIGN KEY ' . PMA_Util::backquote($foreigner['constraint']) . ';'; if ($GLOBALS['dbi']->query($upd_query)) { return array(true, __('FOREIGN KEY relation has been removed.')); } $error = $GLOBALS['dbi']->getError(); return array(false, __('Error: FOREIGN KEY relation could not be removed!') . "<br/>" . $error); } } // internal relations $delete_query = "DELETE FROM " . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . "." . $GLOBALS['cfgRelation']['relation'] . " WHERE " . "master_db = '" . PMA_Util::sqlAddSlashes($DB2) . "'" . " AND master_table = '" . PMA_Util::sqlAddSlashes($T2) . "'" . " AND master_field = '" . PMA_Util::sqlAddSlashes($F2) . "'" . " AND foreign_db = '" . PMA_Util::sqlAddSlashes($DB1) . "'" . " AND foreign_table = '" . PMA_Util::sqlAddSlashes($T1) . "'" . " AND foreign_field = '" . PMA_Util::sqlAddSlashes($F1) . "'"; $result = PMA_queryAsControlUser($delete_query, false, PMA_DatabaseInterface::QUERY_STORE); if (!$result) { $error = $GLOBALS['dbi']->getError($GLOBALS['controllink']); return array(false, __('Error: Internal relation could not be removed!') . "<br/>" . $error); } return array(true, __('Internal relation has been removed.')); }
/** * Check child table references and foreign key for a table column. * * @param string $db name of master table db. * @param string $table name of master table. * @param string $column name of master table column. * @param array $foreigners_full foreiners array for the whole table. * @param array $child_references_full child references for the whole table. * * @return array $column_status telling about references if foreign key. */ function PMA_checkChildForeignReferences($db, $table, $column, $foreigners_full = null, $child_references_full = null) { $column_status = array(); $column_status['isEditable'] = false; $column_status['isReferenced'] = false; $column_status['isForeignKey'] = false; $column_status['references'] = array(); $foreigners = array(); if ($foreigners_full !== null) { if (isset($foreigners_full[$column])) { $foreigners[$column] = $foreigners_full[$column]; } if (isset($foreigners_full['foreign_keys_data'])) { $foreigners['foreign_keys_data'] = $foreigners_full['foreign_keys_data']; } } else { $foreigners = PMA_getForeigners($db, $table, $column, 'foreign'); } $foreigner = PMA_searchColumnInForeigners($foreigners, $column); $child_references = array(); if ($child_references_full !== null) { if (isset($child_references_full[$column])) { $child_references = $child_references_full[$column]; } } else { $child_references = PMA_getChildReferences($db, $table, $column); } if (sizeof($child_references, 0) > 0 || $foreigner) { if (sizeof($child_references, 0) > 0) { $column_status['isReferenced'] = true; foreach ($child_references as $row => $columns) { array_push($column_status['references'], PMA_Util::backquote($columns['table_schema']) . '.' . PMA_Util::backquote($columns['table_name'])); } } if ($foreigner) { $column_status['isForeignKey'] = true; } } else { $column_status['isEditable'] = true; } return $column_status; }
/** * Display option in the cell according to user choices * * @param array $map all Relations to foreign tables for a given * table or optionally a given column in a table * @param string $relation_field relation field * @param string $where_comparison string that contain relation field value * @param string $dispval display value from the foreign table * @param string $relation_field_value relation field value * * @return string $output HTML <a> tag */ function PMA_getLinkForRelationalDisplayField($map, $relation_field, $where_comparison, $dispval, $relation_field_value) { $foreigner = PMA_searchColumnInForeigners($map, $relation_field); if ('K' == $_SESSION['tmpval']['relational_display']) { // 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($relation_field_value) . '"'; } $_url_params = array('db' => $foreigner['foreign_db'], 'table' => $foreigner['foreign_table'], 'pos' => '0', 'sql_query' => 'SELECT * FROM ' . PMA_Util::backquote($foreigner['foreign_db']) . '.' . PMA_Util::backquote($foreigner['foreign_table']) . ' WHERE ' . PMA_Util::backquote($foreigner['foreign_field']) . $where_comparison); $output = '<a href="sql.php' . PMA_URL_getCommon($_url_params) . '"' . $title . '>'; if ('D' == $_SESSION['tmpval']['relational_display']) { // user chose "relational display field" in the // display options, so show display field in the cell $output .= !empty($dispval) ? htmlspecialchars($dispval) : ''; } else { // otherwise display data in the cell $output .= htmlspecialchars($relation_field_value); } $output .= '</a>'; return $output; }
if (isset($pk_array[$row['Field']])) { echo ' <em>(', __('Primary'), ')</em>'; } echo '</td>'; echo '<td', PMA\libraries\Util::getClassForType($extracted_columnspec['type']), ' lang="en" dir="ltr">', $type, '</td>'; echo '<td>'; echo $row['Null'] == 'NO' ? __('No') : __('Yes'); echo '</td>'; echo '<td class="nowrap">'; if (isset($row['Default'])) { echo $row['Default']; } echo '</td>'; if ($have_rel) { echo ' <td>'; if ($foreigner = PMA_searchColumnInForeigners($res_rel, $column_name)) { echo htmlspecialchars($foreigner['foreign_table'] . ' -> ' . $foreigner['foreign_field']); } echo '</td>', "\n"; } echo ' <td>'; if (isset($comments[$column_name])) { echo htmlspecialchars($comments[$column_name]); } echo '</td>', "\n"; if ($cfgRelation['mimework']) { $mime_map = PMA_getMIME($db, $table, true); echo ' <td>'; if (isset($mime_map[$column_name])) { echo htmlspecialchars(str_replace('_', '/', $mime_map[$column_name]['mimetype'])); }
/** * Returns $table's CREATE definition * * @param string $db the database name * @param string $table the table name * @param string $crlf the end of line sequence * @param string $error_url the url to go back in case of error * @param bool $do_relation whether to include relation comments * @param bool $do_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 * PMA_exportStructure() also for other * @param bool $do_mime whether to include mime comments * @param bool $show_dates whether to include creation/update/check dates * @param bool $add_semicolon whether to add semicolon and end-of-line at * the end * @param bool $view whether we're handling a view * @param array $aliases Aliases of db/table/columns * * @return bool true */ public function getTableDef($db, $table, $crlf, $error_url, $do_relation, $do_comments, $do_mime, $show_dates = false, $add_semicolon = true, $view = false, $aliases = array()) { global $cfgRelation; $db_alias = $db; $table_alias = $table; $this->initAlias($aliases, $db_alias, $table_alias); /** * Gets fields properties */ $GLOBALS['dbi']->selectDb($db); // Check if we can use Relations list($res_rel, $have_rel) = PMA_getRelationsAndStatus($do_relation && !empty($cfgRelation['relation']), $db, $table); /** * Displays the table structure */ $GLOBALS['odt_buffer'] .= '<table:table table:name="' . htmlspecialchars($table_alias) . '_structure">'; $columns_cnt = 4; if ($do_relation && $have_rel) { $columns_cnt++; } if ($do_comments) { $columns_cnt++; } if ($do_mime && $cfgRelation['mimework']) { $columns_cnt++; } $GLOBALS['odt_buffer'] .= '<table:table-column' . ' table:number-columns-repeated="' . $columns_cnt . '"/>'; /* Header */ $GLOBALS['odt_buffer'] .= '<table:table-row>' . '<table:table-cell office:value-type="string">' . '<text:p>' . __('Column') . '</text:p>' . '</table:table-cell>' . '<table:table-cell office:value-type="string">' . '<text:p>' . __('Type') . '</text:p>' . '</table:table-cell>' . '<table:table-cell office:value-type="string">' . '<text:p>' . __('Null') . '</text:p>' . '</table:table-cell>' . '<table:table-cell office:value-type="string">' . '<text:p>' . __('Default') . '</text:p>' . '</table:table-cell>'; if ($do_relation && $have_rel) { $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . __('Links to') . '</text:p>' . '</table:table-cell>'; } if ($do_comments) { $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . __('Comments') . '</text:p>' . '</table:table-cell>'; $comments = PMA_getComments($db, $table); } if ($do_mime && $cfgRelation['mimework']) { $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . __('MIME type') . '</text:p>' . '</table:table-cell>'; $mime_map = PMA_getMIME($db, $table, true); } $GLOBALS['odt_buffer'] .= '</table:table-row>'; $columns = $GLOBALS['dbi']->getColumns($db, $table); foreach ($columns as $column) { $col_as = $field_name = $column['Field']; if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) { $col_as = $aliases[$db]['tables'][$table]['columns'][$col_as]; } $GLOBALS['odt_buffer'] .= $this->formatOneColumnDefinition($column, $col_as); if ($do_relation && $have_rel) { $foreigner = PMA_searchColumnInForeigners($res_rel, $field_name); if ($foreigner) { $rtable = $foreigner['foreign_table']; $rfield = $foreigner['foreign_field']; if (!empty($aliases[$db]['tables'][$rtable]['columns'][$rfield])) { $rfield = $aliases[$db]['tables'][$rtable]['columns'][$rfield]; } if (!empty($aliases[$db]['tables'][$rtable]['alias'])) { $rtable = $aliases[$db]['tables'][$rtable]['alias']; } $relation = htmlspecialchars($rtable . ' (' . $rfield . ')'); $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . htmlspecialchars($relation) . '</text:p>' . '</table:table-cell>'; } } if ($do_comments) { if (isset($comments[$field_name])) { $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . htmlspecialchars($comments[$field_name]) . '</text:p>' . '</table:table-cell>'; } else { $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p></text:p>' . '</table:table-cell>'; } } if ($do_mime && $cfgRelation['mimework']) { if (isset($mime_map[$field_name])) { $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . htmlspecialchars(str_replace('_', '/', $mime_map[$field_name]['mimetype'])) . '</text:p>' . '</table:table-cell>'; } else { $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p></text:p>' . '</table:table-cell>'; } } $GLOBALS['odt_buffer'] .= '</table:table-row>'; } // end foreach $GLOBALS['odt_buffer'] .= '</table:table>'; return true; }
/** * Generates data dictionary pages. * * @param array $alltables Tables to document. * * @return void */ public function dataDictionaryDoc($alltables) { // TOC $this->diagram->addpage($this->orientation); $this->diagram->Cell(0, 9, __('Table of contents'), 1, 0, 'C'); $this->diagram->Ln(15); $i = 1; foreach ($alltables as $table) { $this->diagram->PMA_links['doc'][$table]['-'] = $this->diagram->AddLink(); $this->diagram->SetX(10); // $this->diagram->Ln(1); $this->diagram->Cell(0, 6, __('Page number:') . ' {' . sprintf("%02d", $i) . '}', 0, 0, 'R', 0, $this->diagram->PMA_links['doc'][$table]['-']); $this->diagram->SetX(10); $this->diagram->Cell(0, 6, $i . ' ' . $table, 0, 1, 'L', 0, $this->diagram->PMA_links['doc'][$table]['-']); // $this->diagram->Ln(1); $fields = $GLOBALS['dbi']->getColumns($this->db, $table); foreach ($fields as $row) { $this->diagram->SetX(20); $field_name = $row['Field']; $this->diagram->PMA_links['doc'][$table][$field_name] = $this->diagram->AddLink(); //$this->diagram->Cell( // 0, 6, $field_name, 0, 1, // 'L', 0, $this->diagram->PMA_links['doc'][$table][$field_name] //); } $i++; } $this->diagram->PMA_links['RT']['-'] = $this->diagram->AddLink(); $this->diagram->SetX(10); $this->diagram->Cell(0, 6, __('Page number:') . ' {00}', 0, 0, 'R', 0, $this->diagram->PMA_links['RT']['-']); $this->diagram->SetX(10); $this->diagram->Cell(0, 6, $i . ' ' . __('Relational schema'), 0, 1, 'L', 0, $this->diagram->PMA_links['RT']['-']); $z = 0; foreach ($alltables as $table) { $z++; $this->diagram->SetAutoPageBreak(true, 15); $this->diagram->addpage($this->orientation); $this->diagram->Bookmark($table); $this->diagram->SetAlias('{' . sprintf("%02d", $z) . '}', $this->diagram->PageNo()); $this->diagram->PMA_links['RT'][$table]['-'] = $this->diagram->AddLink(); $this->diagram->SetLink($this->diagram->PMA_links['doc'][$table]['-'], -1); $this->diagram->SetFont($this->_ff, 'B', 18); $this->diagram->Cell(0, 8, $z . ' ' . $table, 1, 1, 'C', 0, $this->diagram->PMA_links['RT'][$table]['-']); $this->diagram->SetFont($this->_ff, '', 8); $this->diagram->ln(); $cfgRelation = PMA_getRelationsParam(); $comments = PMA_getComments($this->db, $table); if ($cfgRelation['mimework']) { $mime_map = PMA_getMIME($this->db, $table, true); } /** * Gets table information */ $showtable = $GLOBALS['dbi']->getTable($this->db, $table)->getStatusInfo(); $show_comment = isset($showtable['Comment']) ? $showtable['Comment'] : ''; $create_time = isset($showtable['Create_time']) ? PMA_Util::localisedDate(strtotime($showtable['Create_time'])) : ''; $update_time = isset($showtable['Update_time']) ? PMA_Util::localisedDate(strtotime($showtable['Update_time'])) : ''; $check_time = isset($showtable['Check_time']) ? PMA_Util::localisedDate(strtotime($showtable['Check_time'])) : ''; /** * Gets fields properties */ $columns = $GLOBALS['dbi']->getColumns($this->db, $table); // Check if we can use Relations if (!empty($cfgRelation['relation'])) { // Find which tables are related with the current one and write it in // an array $res_rel = PMA_getForeigners($this->db, $table); } // end if /** * Displays the comments of the table if MySQL >= 3.23 */ $break = false; if (!empty($show_comment)) { $this->diagram->Cell(0, 3, __('Table comments:') . ' ' . $show_comment, 0, 1); $break = true; } if (!empty($create_time)) { $this->diagram->Cell(0, 3, __('Creation:') . ' ' . $create_time, 0, 1); $break = true; } if (!empty($update_time)) { $this->diagram->Cell(0, 3, __('Last update:') . ' ' . $update_time, 0, 1); $break = true; } if (!empty($check_time)) { $this->diagram->Cell(0, 3, __('Last check:') . ' ' . $check_time, 0, 1); $break = true; } if ($break == true) { $this->diagram->Cell(0, 3, '', 0, 1); $this->diagram->Ln(); } $this->diagram->SetFont($this->_ff, 'B'); if (isset($this->orientation) && $this->orientation == 'L') { $this->diagram->Cell(25, 8, __('Column'), 1, 0, 'C'); $this->diagram->Cell(20, 8, __('Type'), 1, 0, 'C'); $this->diagram->Cell(20, 8, __('Attributes'), 1, 0, 'C'); $this->diagram->Cell(10, 8, __('Null'), 1, 0, 'C'); $this->diagram->Cell(20, 8, __('Default'), 1, 0, 'C'); $this->diagram->Cell(25, 8, __('Extra'), 1, 0, 'C'); $this->diagram->Cell(45, 8, __('Links to'), 1, 0, 'C'); if ($this->paper == 'A4') { $comments_width = 67; } else { // this is really intended for 'letter' /** * @todo find optimal width for all formats */ $comments_width = 50; } $this->diagram->Cell($comments_width, 8, __('Comments'), 1, 0, 'C'); $this->diagram->Cell(45, 8, 'MIME', 1, 1, 'C'); $this->diagram->SetWidths(array(25, 20, 20, 10, 20, 25, 45, $comments_width, 45)); } else { $this->diagram->Cell(20, 8, __('Column'), 1, 0, 'C'); $this->diagram->Cell(20, 8, __('Type'), 1, 0, 'C'); $this->diagram->Cell(20, 8, __('Attributes'), 1, 0, 'C'); $this->diagram->Cell(10, 8, __('Null'), 1, 0, 'C'); $this->diagram->Cell(15, 8, __('Default'), 1, 0, 'C'); $this->diagram->Cell(15, 8, __('Extra'), 1, 0, 'C'); $this->diagram->Cell(30, 8, __('Links to'), 1, 0, 'C'); $this->diagram->Cell(30, 8, __('Comments'), 1, 0, 'C'); $this->diagram->Cell(30, 8, 'MIME', 1, 1, 'C'); $this->diagram->SetWidths(array(20, 20, 20, 10, 15, 15, 30, 30, 30)); } $this->diagram->SetFont($this->_ff, ''); foreach ($columns as $row) { $extracted_columnspec = PMA_Util::extractColumnSpec($row['Type']); $type = $extracted_columnspec['print_type']; $attribute = $extracted_columnspec['attribute']; if (!isset($row['Default'])) { if ($row['Null'] != '' && $row['Null'] != 'NO') { $row['Default'] = 'NULL'; } } $field_name = $row['Field']; // $this->diagram->Ln(); $this->diagram->PMA_links['RT'][$table][$field_name] = $this->diagram->AddLink(); $this->diagram->Bookmark($field_name, 1, -1); $this->diagram->SetLink($this->diagram->PMA_links['doc'][$table][$field_name], -1); $foreigner = PMA_searchColumnInForeigners($res_rel, $field_name); $linksTo = ''; if ($foreigner) { $linksTo = '-> '; if ($foreigner['foreign_db'] != $this->db) { $linksTo .= $foreigner['foreign_db'] . '.'; } $linksTo .= $foreigner['foreign_table'] . '.' . $foreigner['foreign_field']; if (isset($foreigner['on_update'])) { // not set for internal $linksTo .= "\n" . 'ON UPDATE ' . $foreigner['on_update']; $linksTo .= "\n" . 'ON DELETE ' . $foreigner['on_delete']; } } $this->diagram_row = array($field_name, $type, $attribute, $row['Null'] == '' || $row['Null'] == 'NO' ? __('No') : __('Yes'), isset($row['Default']) ? $row['Default'] : '', $row['Extra'], $linksTo, isset($comments[$field_name]) ? $comments[$field_name] : '', isset($mime_map) && isset($mime_map[$field_name]) ? str_replace('_', '/', $mime_map[$field_name]['mimetype']) : ''); $links = array(); $links[0] = $this->diagram->PMA_links['RT'][$table][$field_name]; if ($foreigner && isset($this->diagram->PMA_links['doc'][$foreigner['foreign_table']][$foreigner['foreign_field']])) { $links[6] = $this->diagram->PMA_links['doc'][$foreigner['foreign_table']][$foreigner['foreign_field']]; } else { unset($links[6]); } $this->diagram->Row($this->diagram_row, $links); } // end foreach $this->diagram->SetFont($this->_ff, '', 14); } //end each }
/** * Gives the relation string and * also substitutes with alias if required * in this format: * [Foreign Table] ([Foreign Field]) * * @param array $res_rel the foreigners array * @param string $field_name the field name * @param string $db the field name * @param array $aliases Alias information for db/table/column * * @return string the Relation string */ public function getRelationString($res_rel, $field_name, $db, $aliases = array()) { $relation = ''; $foreigner = PMA_searchColumnInForeigners($res_rel, $field_name); if ($foreigner) { $ftable = $foreigner['foreign_table']; $ffield = $foreigner['foreign_field']; if (!empty($aliases[$db]['tables'][$ftable]['columns'][$ffield])) { $ffield = $aliases[$db]['tables'][$ftable]['columns'][$ffield]; } if (!empty($aliases[$db]['tables'][$ftable]['alias'])) { $ftable = $aliases[$db]['tables'][$ftable]['alias']; } $relation = $ftable . ' (' . $ffield . ')'; } return $relation; }
/** * Creates the HTML content for: * 1) Browsing foreign data for a column. * 2) Creating elements for search criteria input on columns. * * @param array $foreignData Foreign keys data * @param string $column_name Column name * @param string $column_type Column type * @param int $column_index Column index * @param array $titles Selected title * @param int $foreignMaxLimit Max limit of displaying foreign elements * @param array $criteriaValues Array of search criteria inputs * @param bool $in_fbs Whether we are in 'function based search' * @param bool $in_zoom_search_edit Whether we are in zoom search edit * * @return string HTML content for viewing foreign data and elements * for search criteria input. */ private function _getInputbox($foreignData, $column_name, $column_type, $column_index, $titles, $foreignMaxLimit, $criteriaValues, $in_fbs = false, $in_zoom_search_edit = false) { $str = ''; $column_type = (string) $column_type; $column_id = $in_zoom_search_edit ? 'edit_fieldID_' : 'fieldID_'; // Get inputbox based on different column types // (Foreign key, geometrical, enum) if ($this->_foreigners && PMA_searchColumnInForeigners($this->_foreigners, $column_name)) { $str .= $this->_getForeignKeyInputBox($foreignData, $column_name, $column_index, $titles, $foreignMaxLimit, $criteriaValues, $column_id); } elseif (in_array($column_type, PMA_Util::getGISDatatypes())) { $str .= $this->_getGeometricalInputBox($column_index, $in_fbs); } elseif (strncasecmp($column_type, 'enum', 4) == 0 || strncasecmp($column_type, 'set', 3) == 0 && $in_zoom_search_edit) { $str .= $this->_getEnumSetInputBox($column_index, $criteriaValues, $column_type, $column_id, $in_zoom_search_edit = false); } else { // other cases $the_class = 'textfield'; /** @var PMA_String $pmaString */ $pmaString = $GLOBALS['PMA_String']; if ($column_type == 'date') { $the_class .= ' datefield'; } elseif ($column_type == 'datetime' || $pmaString->substr($column_type, 0, 9) == 'timestamp') { $the_class .= ' datetimefield'; } elseif ($pmaString->substr($column_type, 0, 3) == 'bit') { $the_class .= ' bit'; } $str .= '<input type="text" name="criteriaValues[' . $column_index . ']"' . ' size="40" class="' . $the_class . '" id="' . $column_id . $column_index . '"' . (isset($criteriaValues[$column_index]) && is_string($criteriaValues[$column_index]) ? ' value="' . $criteriaValues[$column_index] . '"' : '') . ' />'; } return $str; }
/** * Test for PMA_searchColumnInForeigners * * @return void */ public function testPMASearchColumnInForeigners() { $foreigners = array('value' => array('master_field' => 'value', 'foreign_db' => 'GSoC14', 'foreign_table' => 'test', 'foreign_field' => 'value'), 'foreign_keys_data' => array(0 => array('constraint' => 'ad', 'index_list' => array('id', 'value'), 'ref_db_name' => 'GSoC14', 'ref_table_name' => 'table_1', 'ref_index_list' => array('id', 'value'), 'on_delete' => 'CASCADE', 'on_update' => 'CASCADE'))); $foreigner = PMA_searchColumnInForeigners($foreigners, 'id'); $expected = array(); $expected['foreign_field'] = 'id'; $expected['foreign_db'] = 'GSoC14'; $expected['foreign_table'] = 'table_1'; $expected['constraint'] = 'ad'; $expected['on_delete'] = 'CASCADE'; $expected['on_update'] = 'CASCADE'; $this->assertEquals($expected, $foreigner); }
/** * Generates data dictionary pages. * * @param array $alltables Tables to document. * * @return void */ public function dataDictionaryDoc($alltables) { global $pdf; // TOC $pdf->addpage($this->orientation); $pdf->Cell(0, 9, __('Table of contents'), 1, 0, 'C'); $pdf->Ln(15); $i = 1; foreach ($alltables as $table) { $pdf->PMA_links['doc'][$table]['-'] = $pdf->AddLink(); $pdf->SetX(10); // $pdf->Ln(1); $pdf->Cell(0, 6, __('Page number:') . ' {' . sprintf("%02d", $i) . '}', 0, 0, 'R', 0, $pdf->PMA_links['doc'][$table]['-']); $pdf->SetX(10); $pdf->Cell(0, 6, $i . ' ' . $table, 0, 1, 'L', 0, $pdf->PMA_links['doc'][$table]['-']); // $pdf->Ln(1); $fields = $GLOBALS['dbi']->getColumns($GLOBALS['db'], $table); foreach ($fields as $row) { $pdf->SetX(20); $field_name = $row['Field']; $pdf->PMA_links['doc'][$table][$field_name] = $pdf->AddLink(); //$pdf->Cell( // 0, 6, $field_name, 0, 1, // 'L', 0, $pdf->PMA_links['doc'][$table][$field_name] //); } $i++; } $pdf->PMA_links['RT']['-'] = $pdf->AddLink(); $pdf->SetX(10); $pdf->Cell(0, 6, __('Page number:') . ' {00}', 0, 0, 'R', 0, $pdf->PMA_links['RT']['-']); $pdf->SetX(10); $pdf->Cell(0, 6, $i . ' ' . __('Relational schema'), 0, 1, 'L', 0, $pdf->PMA_links['RT']['-']); $z = 0; foreach ($alltables as $table) { $z++; $pdf->SetAutoPageBreak(true, 15); $pdf->addpage($this->orientation); $pdf->Bookmark($table); $pdf->SetAlias('{' . sprintf("%02d", $z) . '}', $pdf->PageNo()); $pdf->PMA_links['RT'][$table]['-'] = $pdf->AddLink(); $pdf->SetLink($pdf->PMA_links['doc'][$table]['-'], -1); $pdf->SetFont($this->_ff, 'B', 18); $pdf->Cell(0, 8, $z . ' ' . $table, 1, 1, 'C', 0, $pdf->PMA_links['RT'][$table]['-']); $pdf->SetFont($this->_ff, '', 8); $pdf->ln(); $cfgRelation = PMA_getRelationsParam(); $comments = PMA_getComments($GLOBALS['db'], $table); if ($cfgRelation['mimework']) { $mime_map = PMA_getMIME($GLOBALS['db'], $table, true); } /** * Gets table informations */ $showtable = PMA_Table::sGetStatusInfo($GLOBALS['db'], $table); $show_comment = isset($showtable['Comment']) ? $showtable['Comment'] : ''; $create_time = isset($showtable['Create_time']) ? PMA_Util::localisedDate(strtotime($showtable['Create_time'])) : ''; $update_time = isset($showtable['Update_time']) ? PMA_Util::localisedDate(strtotime($showtable['Update_time'])) : ''; $check_time = isset($showtable['Check_time']) ? PMA_Util::localisedDate(strtotime($showtable['Check_time'])) : ''; /** * Gets table keys and retains them */ $result = $GLOBALS['dbi']->query('SHOW KEYS FROM ' . PMA_Util::backquote($table) . ';'); $primary = ''; $indexes = array(); $lastIndex = ''; $indexes_info = array(); $indexes_data = array(); $pk_array = array(); // will be use to emphasis prim. keys in the table // view while ($row = $GLOBALS['dbi']->fetchAssoc($result)) { // Backups the list of primary keys if ($row['Key_name'] == 'PRIMARY') { $primary .= $row['Column_name'] . ', '; $pk_array[$row['Column_name']] = 1; } // Retains keys informations if ($row['Key_name'] != $lastIndex) { $indexes[] = $row['Key_name']; $lastIndex = $row['Key_name']; } $indexes_info[$row['Key_name']]['Sequences'][] = $row['Seq_in_index']; $indexes_info[$row['Key_name']]['Non_unique'] = $row['Non_unique']; if (isset($row['Cardinality'])) { $indexes_info[$row['Key_name']]['Cardinality'] = $row['Cardinality']; } // I don't know what does following column mean.... // $indexes_info[$row['Key_name']]['Packed'] = $row['Packed']; $indexes_info[$row['Key_name']]['Comment'] = $row['Comment']; $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Column_name'] = $row['Column_name']; if (isset($row['Sub_part'])) { $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Sub_part'] = $row['Sub_part']; } } // end while if ($result) { $GLOBALS['dbi']->freeResult($result); } /** * Gets fields properties */ $columns = $GLOBALS['dbi']->getColumns($GLOBALS['db'], $table); // Check if we can use Relations if (!empty($cfgRelation['relation'])) { // Find which tables are related with the current one and write it in // an array $res_rel = PMA_getForeigners($GLOBALS['db'], $table); } // end if /** * Displays the comments of the table if MySQL >= 3.23 */ $break = false; if (!empty($show_comment)) { $pdf->Cell(0, 3, __('Table comments:') . ' ' . $show_comment, 0, 1); $break = true; } if (!empty($create_time)) { $pdf->Cell(0, 3, __('Creation:') . ' ' . $create_time, 0, 1); $break = true; } if (!empty($update_time)) { $pdf->Cell(0, 3, __('Last update:') . ' ' . $update_time, 0, 1); $break = true; } if (!empty($check_time)) { $pdf->Cell(0, 3, __('Last check:') . ' ' . $check_time, 0, 1); $break = true; } if ($break == true) { $pdf->Cell(0, 3, '', 0, 1); $pdf->Ln(); } $pdf->SetFont($this->_ff, 'B'); if (isset($this->orientation) && $this->orientation == 'L') { $pdf->Cell(25, 8, __('Column'), 1, 0, 'C'); $pdf->Cell(20, 8, __('Type'), 1, 0, 'C'); $pdf->Cell(20, 8, __('Attributes'), 1, 0, 'C'); $pdf->Cell(10, 8, __('Null'), 1, 0, 'C'); $pdf->Cell(20, 8, __('Default'), 1, 0, 'C'); $pdf->Cell(25, 8, __('Extra'), 1, 0, 'C'); $pdf->Cell(45, 8, __('Links to'), 1, 0, 'C'); if ($this->paper == 'A4') { $comments_width = 67; } else { // this is really intended for 'letter' /** * @todo find optimal width for all formats */ $comments_width = 50; } $pdf->Cell($comments_width, 8, __('Comments'), 1, 0, 'C'); $pdf->Cell(45, 8, 'MIME', 1, 1, 'C'); $pdf->SetWidths(array(25, 20, 20, 10, 20, 25, 45, $comments_width, 45)); } else { $pdf->Cell(20, 8, __('Column'), 1, 0, 'C'); $pdf->Cell(20, 8, __('Type'), 1, 0, 'C'); $pdf->Cell(20, 8, __('Attributes'), 1, 0, 'C'); $pdf->Cell(10, 8, __('Null'), 1, 0, 'C'); $pdf->Cell(15, 8, __('Default'), 1, 0, 'C'); $pdf->Cell(15, 8, __('Extra'), 1, 0, 'C'); $pdf->Cell(30, 8, __('Links to'), 1, 0, 'C'); $pdf->Cell(30, 8, __('Comments'), 1, 0, 'C'); $pdf->Cell(30, 8, 'MIME', 1, 1, 'C'); $pdf->SetWidths(array(20, 20, 20, 10, 15, 15, 30, 30, 30)); } $pdf->SetFont($this->_ff, ''); foreach ($columns as $row) { $extracted_columnspec = PMA_Util::extractColumnSpec($row['Type']); $type = $extracted_columnspec['print_type']; $attribute = $extracted_columnspec['attribute']; if (!isset($row['Default'])) { if ($row['Null'] != '' && $row['Null'] != 'NO') { $row['Default'] = 'NULL'; } } $field_name = $row['Field']; // $pdf->Ln(); $pdf->PMA_links['RT'][$table][$field_name] = $pdf->AddLink(); $pdf->Bookmark($field_name, 1, -1); $pdf->SetLink($pdf->PMA_links['doc'][$table][$field_name], -1); $foreigner = PMA_searchColumnInForeigners($res_rel, $field_name); $pdf_row = array($field_name, $type, $attribute, $row['Null'] == '' || $row['Null'] == 'NO' ? __('No') : __('Yes'), isset($row['Default']) ? $row['Default'] : '', $row['Extra'], $foreigner ? $foreigner['foreign_table'] . ' -> ' . $foreigner['foreign_field'] : '', isset($comments[$field_name]) ? $comments[$field_name] : '', isset($mime_map) && isset($mime_map[$field_name]) ? str_replace('_', '/', $mime_map[$field_name]['mimetype']) : ''); $links = array(); $links[0] = $pdf->PMA_links['RT'][$table][$field_name]; if ($foreigner && isset($pdf->PMA_links['doc'][$foreigner['foreign_table']][$foreigner['foreign_field']])) { $links[6] = $pdf->PMA_links['doc'][$foreigner['foreign_table']][$foreigner['foreign_field']]; } else { unset($links[6]); } $pdf->Row($pdf_row, $links); } // end foreach $pdf->SetFont($this->_ff, '', 14); } //end each }
/** * Removes a foreign relation * * @param string $T1 foreign db.table * @param string $F1 foreign field * @param string $T2 master db.table * @param string $F2 master field * * @return void */ function PMA_removeRelation($T1, $F1, $T2, $F2) { /** @var PMA_String $pmaString */ $pmaString = $GLOBALS['PMA_String']; list($DB1, $T1) = explode(".", $T1); list($DB2, $T2) = explode(".", $T2); $tables = $GLOBALS['dbi']->getTablesFull($DB1, $T1); $type_T1 = $pmaString->strtoupper($tables[$T1]['ENGINE']); $tables = $GLOBALS['dbi']->getTablesFull($DB2, $T2); $type_T2 = $pmaString->strtoupper($tables[$T2]['ENGINE']); $try_to_delete_internal_relation = false; if (PMA_Util::isForeignKeySupported($type_T1) && PMA_Util::isForeignKeySupported($type_T2) && $type_T1 == $type_T2) { // InnoDB $existrel_foreign = PMA_getForeigners($DB2, $T2, '', 'foreign'); $foreigner = PMA_searchColumnInForeigners($existrel_foreign, $F2); if (isset($foreigner['constraint'])) { $upd_query = 'ALTER TABLE ' . PMA_Util::backquote($DB2) . '.' . PMA_Util::backquote($T2) . ' DROP FOREIGN KEY ' . PMA_Util::backquote($foreigner['constraint']) . ';'; $upd_rs = $GLOBALS['dbi']->query($upd_query); } else { // there can be an internal relation even if InnoDB $try_to_delete_internal_relation = true; } } else { $try_to_delete_internal_relation = true; } if ($try_to_delete_internal_relation) { // internal relations PMA_queryAsControlUser('DELETE FROM ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.' . $GLOBALS['cfgRelation']['relation'] . ' WHERE ' . 'master_db = \'' . PMA_Util::sqlAddSlashes($DB2) . '\'' . ' AND master_table = \'' . PMA_Util::sqlAddSlashes($T2) . '\'' . ' AND master_field = \'' . PMA_Util::sqlAddSlashes($F2) . '\'' . ' AND foreign_db = \'' . PMA_Util::sqlAddSlashes($DB1) . '\'' . ' AND foreign_table = \'' . PMA_Util::sqlAddSlashes($T1) . '\'' . ' AND foreign_field = \'' . PMA_Util::sqlAddSlashes($F1) . '\'', false, PMA_DatabaseInterface::QUERY_STORE); } }