PMA\libraries\Util::getUniqueCondition PHP Method

getUniqueCondition() public static method

Function to generate unique condition for specified row.
public static getUniqueCondition ( resource $handle, integer $fields_cnt, array $fields_meta, array $row, boolean $force_unique = false, string | boolean $restrict_to_table = false, array $analyzed_sql_results = null ) : array
$handle resource current query result
$fields_cnt integer number of fields
$fields_meta array meta information about fields
$row array current row
$force_unique boolean generate condition only on pk or unique
$restrict_to_table string | boolean restrict the unique condition to this table or false if none
$analyzed_sql_results array the analyzed query
return array the calculated condition and whether condition is unique
    public static function getUniqueCondition($handle, $fields_cnt, $fields_meta, $row, $force_unique = false, $restrict_to_table = false, $analyzed_sql_results = null)
    {
        $primary_key = '';
        $unique_key = '';
        $nonprimary_condition = '';
        $preferred_condition = '';
        $primary_key_array = array();
        $unique_key_array = array();
        $nonprimary_condition_array = array();
        $condition_array = array();
        for ($i = 0; $i < $fields_cnt; ++$i) {
            $con_val = '';
            $field_flags = $GLOBALS['dbi']->fieldFlags($handle, $i);
            $meta = $fields_meta[$i];
            // do not use a column alias in a condition
            if (!isset($meta->orgname) || strlen($meta->orgname) === 0) {
                $meta->orgname = $meta->name;
                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->orgname = $expr->column;
                            break;
                        }
                    }
                }
            }
            // Do not use a table alias in a condition.
            // Test case is:
            // select * from galerie x WHERE
            //(select count(*) from galerie y where y.datum=x.datum)>1
            //
            // But orgtable is present only with mysqli extension so the
            // fix is only for mysqli.
            // Also, do not use the original table name if we are dealing with
            // a view because this view might be updatable.
            // (The isView() verification should not be costly in most cases
            // because there is some caching in the function).
            if (isset($meta->orgtable) && $meta->table != $meta->orgtable && !$GLOBALS['dbi']->getTable($GLOBALS['db'], $meta->table)->isView()) {
                $meta->table = $meta->orgtable;
            }
            // If this field is not from the table which the unique clause needs
            // to be restricted to.
            if ($restrict_to_table && $restrict_to_table != $meta->table) {
                continue;
            }
            // to fix the bug where float fields (primary or not)
            // can't be matched because of the imprecision of
            // floating comparison, use CONCAT
            // (also, the syntax "CONCAT(field) IS NULL"
            // that we need on the next "if" will work)
            if ($meta->type == 'real') {
                $con_key = 'CONCAT(' . self::backquote($meta->table) . '.' . self::backquote($meta->orgname) . ')';
            } else {
                $con_key = self::backquote($meta->table) . '.' . self::backquote($meta->orgname);
            }
            // end if... else...
            $condition = ' ' . $con_key . ' ';
            if (!isset($row[$i]) || is_null($row[$i])) {
                $con_val = 'IS NULL';
            } else {
                // timestamp is numeric on some MySQL 4.1
                // for real we use CONCAT above and it should compare to string
                if ($meta->numeric && $meta->type != 'timestamp' && $meta->type != 'real') {
                    $con_val = '= ' . $row[$i];
                } elseif (($meta->type == 'blob' || $meta->type == 'string') && stristr($field_flags, 'BINARY') && !empty($row[$i])) {
                    // hexify only if this is a true not empty BLOB or a BINARY
                    // do not waste memory building a too big condition
                    if (mb_strlen($row[$i]) < 1000) {
                        // use a CAST if possible, to avoid problems
                        // if the field contains wildcard characters % or _
                        $con_val = '= CAST(0x' . bin2hex($row[$i]) . ' AS BINARY)';
                    } elseif ($fields_cnt == 1) {
                        // when this blob is the only field present
                        // try settling with length comparison
                        $condition = ' CHAR_LENGTH(' . $con_key . ') ';
                        $con_val = ' = ' . mb_strlen($row[$i]);
                    } else {
                        // this blob won't be part of the final condition
                        $con_val = null;
                    }
                } elseif (in_array($meta->type, self::getGISDatatypes()) && !empty($row[$i])) {
                    // do not build a too big condition
                    if (mb_strlen($row[$i]) < 5000) {
                        $condition .= '=0x' . bin2hex($row[$i]) . ' AND';
                    } else {
                        $condition = '';
                    }
                } elseif ($meta->type == 'bit') {
                    $con_val = "= b'" . self::printableBitValue($row[$i], $meta->length) . "'";
                } else {
                    $con_val = '= \'' . $GLOBALS['dbi']->escapeString($row[$i]) . '\'';
                }
            }
            if ($con_val != null) {
                $condition .= $con_val . ' AND';
                if ($meta->primary_key > 0) {
                    $primary_key .= $condition;
                    $primary_key_array[$con_key] = $con_val;
                } elseif ($meta->unique_key > 0) {
                    $unique_key .= $condition;
                    $unique_key_array[$con_key] = $con_val;
                }
                $nonprimary_condition .= $condition;
                $nonprimary_condition_array[$con_key] = $con_val;
            }
        }
        // end for
        // Correction University of Virginia 19991216:
        // prefer primary or unique keys for condition,
        // but use conjunction of all values if no primary key
        $clause_is_unique = true;
        if ($primary_key) {
            $preferred_condition = $primary_key;
            $condition_array = $primary_key_array;
        } elseif ($unique_key) {
            $preferred_condition = $unique_key;
            $condition_array = $unique_key_array;
        } elseif (!$force_unique) {
            $preferred_condition = $nonprimary_condition;
            $condition_array = $nonprimary_condition_array;
            $clause_is_unique = false;
        }
        $where_clause = trim(preg_replace('|\\s?AND$|', '', $preferred_condition));
        return array($where_clause, $clause_is_unique, $condition_array);
    }

Usage Example

Ejemplo n.º 1
0
 /**
  * Zoom submit action
  *
  * @param string $dataLabel Data label
  * @param string $goto      Goto
  *
  * @return void
  */
 public function zoomSubmitAction($dataLabel, $goto)
 {
     //Query generation part
     $sql_query = $this->_buildSqlQuery();
     $sql_query .= ' LIMIT ' . $_POST['maxPlotLimit'];
     //Query execution part
     $result = $this->dbi->query($sql_query . ";", null, DatabaseInterface::QUERY_STORE);
     $fields_meta = $this->dbi->getFieldsMeta($result);
     $data = array();
     while ($row = $this->dbi->fetchAssoc($result)) {
         //Need a row with indexes as 0,1,2 for the getUniqueCondition
         // hence using a temporary array
         $tmpRow = array();
         foreach ($row as $val) {
             $tmpRow[] = $val;
         }
         //Get unique condition on each row (will be needed for row update)
         $uniqueCondition = Util::getUniqueCondition($result, count($this->_columnNames), $fields_meta, $tmpRow, true, false, null);
         //Append it to row array as where_clause
         $row['where_clause'] = $uniqueCondition[0];
         $tmpData = array($_POST['criteriaColumnNames'][0] => $row[$_POST['criteriaColumnNames'][0]], $_POST['criteriaColumnNames'][1] => $row[$_POST['criteriaColumnNames'][1]], 'where_clause' => $uniqueCondition[0]);
         $tmpData[$dataLabel] = $dataLabel ? $row[$dataLabel] : '';
         $data[] = $tmpData;
     }
     unset($tmpData);
     //Displays form for point data and scatter plot
     $titles = array('Browse' => Util::getIcon('b_browse.png', __('Browse foreign values')));
     $this->response->addHTML(Template::get('table/search/zoom_result_form')->render(array('_db' => $this->db, '_table' => $this->table, '_columnNames' => $this->_columnNames, '_foreigners' => $this->_foreigners, '_columnNullFlags' => $this->_columnNullFlags, '_columnTypes' => $this->_columnTypes, 'titles' => $titles, 'goto' => $goto, 'data' => $data)));
 }
All Usage Examples Of PMA\libraries\Util::getUniqueCondition
Util