Function based search - for unary functions

This commit is contained in:
Madhura Jayaratne 2011-07-28 12:06:15 +05:30
parent aed7270cb9
commit 47a8dcfc88
2 changed files with 161 additions and 7 deletions

View File

@ -3005,7 +3005,7 @@ function PMA_unsupportedDatatypes() {
return $no_support_types;
}
function PMA_getGISDatatypes() {
function PMA_getGISDatatypes($upper_case = false) {
$gis_data_types = array('geometry',
'point',
'linestring',
@ -3015,9 +3015,112 @@ function PMA_getGISDatatypes() {
'multipolygon',
'geometrycollection'
);
if ($upper_case) {
for ($i = 0; $i < count($gis_data_types); $i++) {
$gis_data_types[$i] = strtoupper($gis_data_types[$i]);
}
}
return $gis_data_types;
}
/**
* Returns the names and details of the functions
* that can be applied on geometry data typess.
*
* @param string $geom_type if provided the output is limited to the functions
* that are applicable to the provided geometry type.
* @param bool $binary if set to false functions that take two geometries
* as arguments will not be included.
* @param bool $display if set to true seperators will be added to the
* output array.
*
* @return array names and details of the functions that can be applied on
* geometry data typess.
*/
function PMA_getGISFunctions($geom_type = null, $binary = true, $display = false) {
// Unary functions common to all geomety types
$funcs = array();
if ($display) {
$funcs[] = array('name' => ' ');
}
$funcs[] = array('name' => 'Dimension', 'params' => 1, 'type' => 'int');
//$funcs[] = array('name' => 'Envelope', 'params' => 1, 'type' => 'Polygon');
$funcs[] = array('name' => 'GeometryType', 'params' => 1, 'type' => 'text');
$funcs[] = array('name' => 'SRID', 'params' => 1, 'type' => 'int');
$funcs[] = array('name' => 'IsEmpty', 'params' => 1, 'type' => 'int');
$funcs[] = array('name' => 'IsSimple', 'params' => 1, 'type' => 'int');
$geom_type = trim(strtolower($geom_type));
if ($display && $geom_type != 'geometry' && $geom_type != 'multipoint') {
$funcs[] = array('name' => '--------');
}
if ($geom_type == 'point') {
$funcs[] = array('name' => 'X', 'params' => 1, 'type' => 'float');
$funcs[] = array('name' => 'Y', 'params' => 1, 'type' => 'float');
} elseif ($geom_type == 'multipoint') {
// no fucntions here
} elseif ($geom_type == 'linestring') {
//$funcs[] = array('name' => 'EndPoint', 'params' => 1, 'type' => 'Point');
$funcs[] = array('name' => 'GLength', 'params' => 1, 'type' => 'float');
$funcs[] = array('name' => 'NumPoints', 'params' => 1, 'type' => 'int');
//$funcs[] = array('name' => 'StartPoint', 'params' => 1, 'type' => 'Point');
$funcs[] = array('name' => 'IsRing', 'params' => 1, 'type' => 'int');
} elseif ($geom_type == 'multilinestring') {
$funcs[] = array('name' => 'GLength', 'params' => 1, 'type' => 'float');
$funcs[] = array('name' => 'IsClosed', 'params' => 1, 'type' => 'int');
} elseif ($geom_type == 'polygon') {
$funcs[] = array('name' => 'Area', 'params' => 1, 'type' => 'float');
//$funcs[] = array('name' => 'ExteriorRing', 'params' => 1, 'type' => 'Linestring');
$funcs[] = array('name' => 'NumInteriorRings', 'params' => 1, 'type' => 'int');
} elseif ($geom_type == 'multipolygon') {
$funcs[] = array('name' => 'Area', 'params' => 1, 'type' => 'float');
//$funcs[] = array('name' => 'Centroid', 'params' => 1, 'type' => 'Point');
// Not yet implemented in MySQL
//$funcs[] = array('name' => 'PointOnSurface', 'params' => 1, 'type' => 'Point');
} elseif ($geom_type == 'geometrycollection') {
$funcs[] = array('name' => 'NumGeometries', 'params' => 1, 'type' => 'int');
}
// If we are asked for binary functions as well
if ($binary) {
if ($display) {
$funcs[] = array('name' => '--------');
}
$binary = array(
array('name' => 'Crosses', 'params' => 2, 'type' => 'int'),
array('name' => 'Contains', 'params' => 2, 'type' => 'int'),
array('name' => 'Disjoint', 'params' => 2, 'type' => 'int'),
array('name' => 'Equals', 'params' => 2, 'type' => 'int'),
array('name' => 'Intersects', 'params' => 2, 'type' => 'int'),
array('name' => 'Overlaps', 'params' => 2, 'type' => 'int'),
array('name' => 'Touches', 'params' => 2, 'type' => 'int'),
array('name' => 'Within', 'params' => 2, 'type' => 'int'),
);
// If MySQl version is greaeter than or equal 5.6.1, use the ST_ prefix.
if (PMA_MYSQL_INT_VERSION >= 50601) {
for ($i = 0; $i < count($binary); $i++) {
$binary[$i]['name'] = 'ST_' . $binary[$i]['name'];
}
}
$funcs = array_merge($funcs, $binary);
if ($display) {
$funcs[] = array('name' => '--------');
}
$funcs[] = array('name' => 'MBRContains', 'params' => 2, 'type' => 'int');
$funcs[] = array('name' => 'MBRDisjoint', 'params' => 2, 'type' => 'int');
$funcs[] = array('name' => 'MBREquals', 'params' => 2, 'type' => 'int');
$funcs[] = array('name' => 'MBRIntersects', 'params' => 2, 'type' => 'int');
$funcs[] = array('name' => 'MBROverlaps', 'params' => 2, 'type' => 'int');
$funcs[] = array('name' => 'MBRTouches', 'params' => 2, 'type' => 'int');
$funcs[] = array('name' => 'MBRWithin', 'params' => 2, 'type' => 'int');
}
return $funcs;
}
/**
* Creates a dropdown box with MySQL functions for a particular column.
*

View File

@ -35,6 +35,7 @@ if ($GLOBALS['cfg']['PropertiesIconic'] == true) {
$titles['Browse'] = __('Browse foreign values');
}
$geom_types = PMA_getGISDatatypes();
/**
* Not selection yet required -> displays the selection form
*/
@ -64,9 +65,14 @@ if (! isset($param) || $param[0] == '') {
$result = PMA_DBI_query('SHOW FULL FIELDS FROM ' . PMA_backquote($table) . ' FROM ' . PMA_backquote($db) . ';', null, PMA_DBI_QUERY_STORE);
$fields_cnt = PMA_DBI_num_rows($result);
$fields_list = $fields_null = $fields_type = $fields_collation = array();
$geom_column_present = false;
while ($row = PMA_DBI_fetch_assoc($result)) {
$fields_list[] = $row['Field'];
$type = $row['Type'];
// check whether table contains geometric columns
if (in_array($type, $geom_types)) {
$geom_column_present = true;
}
// reformat mysql query output
if (strncasecmp($type, 'set', 3) == 0
|| strncasecmp($type, 'enum', 4) == 0) {
@ -111,7 +117,13 @@ if (! isset($param) || $param[0] == '') {
<legend><?php echo __('Do a "query by example" (wildcard: "%")') ?></legend>
<table class="data">
<thead>
<tr><th><?php echo __('Column'); ?></th>
<tr><?php
// Display the Function column only if there is alteast one geomety colum
if ($geom_column_present) {
echo('<th>'); echo __('Function'); echo('</th>');
}
?>
<th><?php echo __('Column'); ?></th>
<th><?php echo __('Type'); ?></th>
<th><?php echo __('Collation'); ?></th>
<th><?php echo __('Operator'); ?></th>
@ -125,6 +137,27 @@ if (! isset($param) || $param[0] == '') {
for ($i = 0; $i < $fields_cnt; $i++) {
?>
<tr class="noclick <?php echo $odd_row ? 'odd' : 'even'; $odd_row = ! $odd_row; ?>">
<?php
// if 'Function' column is present
if ($geom_column_present) {
echo('<td>');
// if a geometry column
if (in_array($fields_type[$i], $geom_types)) {
echo('<select name="geom_func['. $i .']">');
// get the relevant list of functions
$funcs = PMA_getGISFunctions($fields_type[$i], false, true);
foreach ($funcs as $func) {
$name = $func['name'];
echo('<option value="' . htmlspecialchars($name) . '">'
. htmlspecialchars($name) . '</option>');
}
echo('</select>');
} else {
echo('&nbsp;');
}
echo('</td>');
}
?>
<th><?php echo htmlspecialchars($fields_list[$i]); ?></th>
<td><?php echo $fields_type[$i]; ?></td>
<td><?php echo $fields_collation[$i]; ?></td>
@ -360,13 +393,31 @@ else {
"= ''" => 1,
"!= ''" => 1
);
$geom_unary_operators = array(
'IsEmpty' => 1,
'IsSimple' => 1,
'IsRing' => 1,
'IsClosed' => 1,
);
$cnt_func = count($func);
reset($func);
while (list($i, $func_type) = each($func)) {
// If geometry funciton is set apply it to the field name
if (isset($geom_func[$i]) && trim($geom_func[$i]) != '') {
$backquoted_name = $geom_func[$i] . '(' . PMA_backquote($names[$i]) . ')';
// If the intended where clause is something like 'IsEmpty(`spatial_col_name`)'
if (isset($geom_unary_operators[$geom_func[$i]]) && trim($fields[$i]) == '') {
$w[] = $backquoted_name;
continue;
}
} else {
$backquoted_name = PMA_backquote($names[$i]);
}
list($charsets[$i]) = explode('_', $collations[$i]);
if (isset($unary_operators[$func_type])) {
$fields[$i] = '';
$w[] = PMA_backquote($names[$i]) . ' ' . $func_type;
$w[] = $backquoted_name . ' ' . $func_type;
} elseif (strncasecmp($types[$i], 'enum', 4) == 0) {
if (!empty($fields[$i])) {
@ -393,7 +444,7 @@ else {
$enum_where .= ', \'' . PMA_sqlAddSlashes($fields[$i][$e]) . '\'';
}
$w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' ' . $parens_open . $enum_where . $parens_close;
$w[] = $backquoted_name . ' ' . $func_type . ' ' . $parens_open . $enum_where . $parens_close;
}
} elseif ($fields[$i] != '') {
@ -425,12 +476,12 @@ else {
$value = $quot . PMA_sqlAddSlashes(trim($value)) . $quot;
if ($func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN')
$w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' ' . (isset($values[0]) ? $values[0] : '') . ' AND ' . (isset($values[1]) ? $values[1] : '');
$w[] = $backquoted_name . ' ' . $func_type . ' ' . (isset($values[0]) ? $values[0] : '') . ' AND ' . (isset($values[1]) ? $values[1] : '');
else
$w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' (' . implode(',', $values) . ')';
$w[] = $backquoted_name . ' ' . $func_type . ' (' . implode(',', $values) . ')';
}
else {
$w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' ' . $quot . PMA_sqlAddSlashes($fields[$i]) . $quot;;
$w[] = $backquoted_name . ' ' . $func_type . ' ' . $quot . PMA_sqlAddSlashes($fields[$i]) . $quot;;
}
} // end if