Converts a bit value to printable format;
in MySQL a BIT field can be from 1 to 64 bits so we need this
function because in PHP, decbin() supports only 32 bits
on 32-bit servers
/** * Get data row action * * @return void */ public function getDataRowAction() { $extra_data = array(); $row_info_query = 'SELECT * FROM `' . $_REQUEST['db'] . '`.`' . $_REQUEST['table'] . '` WHERE ' . $_REQUEST['where_clause']; $result = $this->dbi->query($row_info_query . ";", null, DatabaseInterface::QUERY_STORE); $fields_meta = $this->dbi->getFieldsMeta($result); while ($row = $this->dbi->fetchAssoc($result)) { // for bit fields we need to convert them to printable form $i = 0; foreach ($row as $col => $val) { if ($fields_meta[$i]->type == 'bit') { $row[$col] = Util::printableBitValue($val, $fields_meta[$i]->length); } $i++; } $extra_data['row_info'] = $row; } $this->response->addJSON($extra_data); }
/** * Get data cell for non numeric type fields * * @param string $column the relevant column in data row * @param string $class the html class for column * @param object $meta the meta-information about * the field * @param array $map the list of relations * @param array $_url_params the parameters for generate * url * @param boolean $condition_field the column should highlighted * or not * @param object|string $transformation_plugin the name of transformation * function * @param string $default_function the default transformation * function * @param string $transform_options the transformation parameters * @param boolean $is_field_truncated is data truncated due to * LimitChars * @param array $analyzed_sql_results the analyzed query * @param integer &$dt_result the link id associated to * the query which results * have to be displayed * @param integer $col_index the column index * * @return string $cell the prepared data cell, html content * * @access private * * @see _getTableBody() */ private function _getDataCellForNonNumericColumns($column, $class, $meta, $map, $_url_params, $condition_field, $transformation_plugin, $default_function, $transform_options, $is_field_truncated, $analyzed_sql_results, &$dt_result, $col_index) { $original_length = 0; $is_analyse = $this->__get('is_analyse'); $field_flags = $GLOBALS['dbi']->fieldFlags($dt_result, $col_index); $bIsText = gettype($transformation_plugin) === 'object' && strpos($transformation_plugin->getMIMEtype(), 'Text') === false; // disable inline grid editing // if binary fields are protected // or transformation plugin is of non text type // such as image if (stristr($field_flags, self::BINARY_FIELD) && ($GLOBALS['cfg']['ProtectBinary'] === 'all' || $GLOBALS['cfg']['ProtectBinary'] === 'noblob' && !stristr($meta->type, self::BLOB_FIELD) || $GLOBALS['cfg']['ProtectBinary'] === 'blob' && stristr($meta->type, self::BLOB_FIELD)) || $bIsText) { $class = str_replace('grid_edit', '', $class); } if (!isset($column) || is_null($column)) { $cell = $this->_buildNullDisplay($class, $condition_field, $meta); return $cell; } if ($column == '') { $cell = $this->_buildEmptyDisplay($class, $condition_field, $meta); return $cell; } // Cut all fields to $GLOBALS['cfg']['LimitChars'] // (unless it's a link-type transformation or binary) if (!(gettype($transformation_plugin) === "object" && strpos($transformation_plugin->getName(), 'Link') !== false) && !stristr($field_flags, self::BINARY_FIELD)) { list($is_field_truncated, $column, $original_length) = $this->_getPartialText($column); } $formatted = false; if (isset($meta->_type) && $meta->_type === MYSQLI_TYPE_BIT) { $column = Util::printableBitValue($column, $meta->length); // some results of PROCEDURE ANALYSE() are reported as // being BINARY but they are quite readable, // so don't treat them as BINARY } elseif (stristr($field_flags, self::BINARY_FIELD) && !(isset($is_analyse) && $is_analyse)) { // we show the BINARY or BLOB message and field's size // (or maybe use a transformation) $binary_or_blob = self::BLOB_FIELD; if ($meta->type === self::STRING_FIELD) { $binary_or_blob = self::BINARY_FIELD; } $column = $this->_handleNonPrintableContents($binary_or_blob, $column, $transformation_plugin, $transform_options, $default_function, $meta, $_url_params, $is_field_truncated); $class = $this->_addClass($class, $condition_field, $meta, '', $is_field_truncated, $transformation_plugin, $default_function); $result = strip_tags($column); // disable inline grid editing // if binary or blob data is not shown if (stristr($result, $binary_or_blob)) { $class = str_replace('grid_edit', '', $class); } $formatted = true; } if ($formatted) { $cell = $this->_buildValueDisplay($class, $condition_field, $column); return $cell; } // transform functions may enable no-wrapping: $function_nowrap = 'applyTransformationNoWrap'; $bool_nowrap = $default_function != $transformation_plugin && function_exists($transformation_plugin->{$function_nowrap}()) ? $transformation_plugin->{$function_nowrap}($transform_options) : false; // do not wrap if date field type $nowrap = preg_match('@DATE|TIME@i', $meta->type) || $bool_nowrap ? ' nowrap' : ''; $where_comparison = ' = \'' . Util::sqlAddSlashes($column) . '\''; $cell = $this->_getRowData($class, $condition_field, $analyzed_sql_results, $meta, $map, $column, $transformation_plugin, $default_function, $nowrap, $where_comparison, $transform_options, $is_field_truncated, $original_length); return $cell; }
/** * Outputs the content of a table in SQL 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()) { global $current_row, $sql_backquotes; $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, $sql_backquotes); // Do not export data for a VIEW, unless asked to export the view as a table // (For a VIEW, this is called only when exporting a single VIEW) if ($GLOBALS['dbi']->getTable($db, $table)->isView() && empty($GLOBALS['sql_views_as_tables'])) { $head = $this->_possibleCRLF() . $this->_exportComment() . $this->_exportComment('VIEW ' . ' ' . $formatted_table_name) . $this->_exportComment(__('Data:') . ' ' . __('None')) . $this->_exportComment() . $this->_possibleCRLF(); if (!PMA_exportOutputHandler($head)) { return false; } return true; } $result = $GLOBALS['dbi']->tryQuery($sql_query, null, DatabaseInterface::QUERY_UNBUFFERED); // a possible error: the table has crashed $tmp_error = $GLOBALS['dbi']->getError(); if ($tmp_error) { return PMA_exportOutputHandler($this->_exportComment(__('Error reading data:') . ' (' . $tmp_error . ')')); } if ($result == false) { $GLOBALS['dbi']->freeResult($result); return true; } $fields_cnt = $GLOBALS['dbi']->numFields($result); // Get field information $fields_meta = $GLOBALS['dbi']->getFieldsMeta($result); $field_flags = array(); for ($j = 0; $j < $fields_cnt; $j++) { $field_flags[$j] = $GLOBALS['dbi']->fieldFlags($result, $j); } $field_set = array(); for ($j = 0; $j < $fields_cnt; $j++) { $col_as = $fields_meta[$j]->name; if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) { $col_as = $aliases[$db]['tables'][$table]['columns'][$col_as]; } $field_set[$j] = Util::backquoteCompat($col_as, $compat, $sql_backquotes); } if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'UPDATE') { // update $schema_insert = 'UPDATE '; if (isset($GLOBALS['sql_ignore'])) { $schema_insert .= 'IGNORE '; } // avoid EOL blank $schema_insert .= Util::backquoteCompat($table_alias, $compat, $sql_backquotes) . ' SET'; } else { // insert or replace if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'REPLACE') { $sql_command = 'REPLACE'; } else { $sql_command = 'INSERT'; } // delayed inserts? if (isset($GLOBALS['sql_delayed'])) { $insert_delayed = ' DELAYED'; } else { $insert_delayed = ''; } // insert ignore? if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'INSERT' && isset($GLOBALS['sql_ignore'])) { $insert_delayed .= ' IGNORE'; } //truncate table before insert if (isset($GLOBALS['sql_truncate']) && $GLOBALS['sql_truncate'] && $sql_command == 'INSERT') { $truncate = 'TRUNCATE TABLE ' . Util::backquoteCompat($table_alias, $compat, $sql_backquotes) . ";"; $truncatehead = $this->_possibleCRLF() . $this->_exportComment() . $this->_exportComment(__('Truncate table before insert') . ' ' . $formatted_table_name) . $this->_exportComment() . $crlf; PMA_exportOutputHandler($truncatehead); PMA_exportOutputHandler($truncate); } // scheme for inserting fields if ($GLOBALS['sql_insert_syntax'] == 'complete' || $GLOBALS['sql_insert_syntax'] == 'both') { $fields = implode(', ', $field_set); $schema_insert = $sql_command . $insert_delayed . ' INTO ' . Util::backquoteCompat($table_alias, $compat, $sql_backquotes) . ' (' . $fields . ') VALUES'; } else { $schema_insert = $sql_command . $insert_delayed . ' INTO ' . Util::backquoteCompat($table_alias, $compat, $sql_backquotes) . ' VALUES'; } } //\x08\\x09, not required $search = array("", "\n", "\r", ""); $replace = array('\\0', '\\n', '\\r', '\\Z'); $current_row = 0; $query_size = 0; if (($GLOBALS['sql_insert_syntax'] == 'extended' || $GLOBALS['sql_insert_syntax'] == 'both') && (!isset($GLOBALS['sql_type']) || $GLOBALS['sql_type'] != 'UPDATE')) { $separator = ','; $schema_insert .= $crlf; } else { $separator = ';'; } while ($row = $GLOBALS['dbi']->fetchRow($result)) { if ($current_row == 0) { $head = $this->_possibleCRLF() . $this->_exportComment() . $this->_exportComment(__('Dumping data for table') . ' ' . $formatted_table_name) . $this->_exportComment() . $crlf; if (!PMA_exportOutputHandler($head)) { return false; } } // We need to SET IDENTITY_INSERT ON for MSSQL if (isset($GLOBALS['sql_compatibility']) && $GLOBALS['sql_compatibility'] == 'MSSQL' && $current_row == 0) { if (!PMA_exportOutputHandler('SET IDENTITY_INSERT ' . Util::backquoteCompat($table_alias, $compat, $sql_backquotes) . ' ON ;' . $crlf)) { return false; } } $current_row++; $values = array(); for ($j = 0; $j < $fields_cnt; $j++) { // NULL if (!isset($row[$j]) || is_null($row[$j])) { $values[] = 'NULL'; } elseif ($fields_meta[$j]->numeric && $fields_meta[$j]->type != 'timestamp' && !$fields_meta[$j]->blob) { // a number // timestamp is numeric on some MySQL 4.1, BLOBs are // sometimes numeric $values[] = $row[$j]; } elseif (stristr($field_flags[$j], 'BINARY') !== false && isset($GLOBALS['sql_hex_for_binary'])) { // a true BLOB // - mysqldump only generates hex data when the --hex-blob // option is used, for fields having the binary attribute // no hex is generated // - a TEXT field returns type blob but a real blob // returns also the 'binary' flag // empty blobs need to be different, but '0' is also empty // :-( if (empty($row[$j]) && $row[$j] != '0') { $values[] = '\'\''; } else { $values[] = '0x' . bin2hex($row[$j]); } } elseif ($fields_meta[$j]->type == 'bit') { // detection of 'bit' works only on mysqli extension $values[] = "b'" . Util::sqlAddSlashes(Util::printableBitValue($row[$j], $fields_meta[$j]->length)) . "'"; } elseif (!empty($GLOBALS['exporting_metadata']) && $row[$j] == '@LAST_PAGE') { $values[] = '@LAST_PAGE'; } else { // something else -> treat as a string $values[] = '\'' . str_replace($search, $replace, Util::sqlAddSlashes($row[$j])) . '\''; } // end if } // end for // should we make update? if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'UPDATE') { $insert_line = $schema_insert; for ($i = 0; $i < $fields_cnt; $i++) { if (0 == $i) { $insert_line .= ' '; } if ($i > 0) { // avoid EOL blank $insert_line .= ','; } $insert_line .= $field_set[$i] . ' = ' . $values[$i]; } list($tmp_unique_condition, $tmp_clause_is_unique) = Util::getUniqueCondition($result, $fields_cnt, $fields_meta, $row, false, false, null); $insert_line .= ' WHERE ' . $tmp_unique_condition; unset($tmp_unique_condition, $tmp_clause_is_unique); } else { // Extended inserts case if ($GLOBALS['sql_insert_syntax'] == 'extended' || $GLOBALS['sql_insert_syntax'] == 'both') { if ($current_row == 1) { $insert_line = $schema_insert . '(' . implode(', ', $values) . ')'; } else { $insert_line = '(' . implode(', ', $values) . ')'; $insertLineSize = mb_strlen($insert_line); $sql_max_size = $GLOBALS['sql_max_query_size']; if (isset($sql_max_size) && $sql_max_size > 0 && $query_size + $insertLineSize > $sql_max_size) { if (!PMA_exportOutputHandler(';' . $crlf)) { return false; } $query_size = 0; $current_row = 1; $insert_line = $schema_insert . $insert_line; } } $query_size += mb_strlen($insert_line); // Other inserts case } else { $insert_line = $schema_insert . '(' . implode(', ', $values) . ')'; } } unset($values); if (!PMA_exportOutputHandler(($current_row == 1 ? '' : $separator . $crlf) . $insert_line)) { return false; } } // end while if ($current_row > 0) { if (!PMA_exportOutputHandler(';' . $crlf)) { return false; } } // We need to SET IDENTITY_INSERT OFF for MSSQL if (isset($GLOBALS['sql_compatibility']) && $GLOBALS['sql_compatibility'] == 'MSSQL' && $current_row > 0) { $outputSucceeded = PMA_exportOutputHandler($crlf . 'SET IDENTITY_INSERT ' . Util::backquoteCompat($table_alias, $compat, $sql_backquotes) . ' OFF;' . $crlf); if (!$outputSucceeded) { return false; } } $GLOBALS['dbi']->freeResult($result); return true; }