1<?php 2 3 /** 4 * List indexes on a table 5 * 6 * $Id: indexes.php,v 1.46 2008/01/08 22:50:29 xzilla Exp $ 7 */ 8 9 // Include application functions 10 include_once('./libraries/lib.inc.php'); 11 include_once('./classes/class.select.php'); 12 13 $action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; 14 15 /** 16 * Show confirmation of cluster index and perform actual cluster 17 */ 18 function doClusterIndex($confirm) { 19 global $data, $misc, $action; 20 global $lang; 21 22 if ($confirm) { 23 // Default analyze to on 24 $_REQUEST['analyze'] = true; 25 26 $misc->printTrail('index'); 27 $misc->printTitle($lang['strclusterindex'],'pg.index.cluster'); 28 29 echo "<p>", sprintf($lang['strconfcluster'], $misc->printVal($_REQUEST['index'])), "</p>\n"; 30 31 echo "<form action=\"indexes.php\" method=\"post\">\n"; 32 echo "<p><input type=\"checkbox\" id=\"analyze\" name=\"analyze\"", (isset($_REQUEST['analyze']) ? ' checked="checked"' : ''), " /><label for=\"analyze\">{$lang['stranalyze']}</label></p>\n"; 33 echo "<input type=\"hidden\" name=\"action\" value=\"cluster_index\" />\n"; 34 echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; 35 echo "<input type=\"hidden\" name=\"index\" value=\"", htmlspecialchars($_REQUEST['index']), "\" />\n"; 36 echo $misc->form; 37 echo "<input type=\"submit\" name=\"cluster\" value=\"{$lang['strclusterindex']}\" />\n"; 38 echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; 39 echo "</form>\n"; 40 } 41 else { 42 $status = $data->clusterIndex($_POST['table'], $_POST['index']); 43 if ($status == 0) 44 if (isset($_POST['analyze'])){ 45 $status = $data->analyzeDB($_POST['table']); 46 if ($status == 0) 47 doDefault($lang['strclusteredgood'] . ' ' . $lang['stranalyzegood']); 48 else 49 doDefault($lang['stranalyzebad']); 50 } else 51 doDefault($lang['strclusteredgood']); 52 else 53 doDefault($lang['strclusteredbad']); 54 } 55 56 } 57 58 function doReindex() { 59 global $data, $lang; 60 61 $status = $data->reindex('INDEX', $_REQUEST['index']); 62 if ($status == 0) 63 doDefault($lang['strreindexgood']); 64 else 65 doDefault($lang['strreindexbad']); 66 } 67 68 /** 69 * Displays a screen where they can enter a new index 70 */ 71 function doCreateIndex($msg = '') { 72 global $data, $misc; 73 global $lang; 74 75 if (!isset($_POST['formIndexName'])) $_POST['formIndexName'] = ''; 76 if (!isset($_POST['formIndexType'])) $_POST['formIndexType'] = null; 77 if (!isset($_POST['formCols'])) $_POST['formCols'] = ''; 78 if (!isset($_POST['formWhere'])) $_POST['formWhere'] = ''; 79 if (!isset($_POST['formSpc'])) $_POST['formSpc'] = ''; 80 81 $attrs = $data->getTableAttributes($_REQUEST['table']); 82 // Fetch all tablespaces from the database 83 if ($data->hasTablespaces()) $tablespaces = $data->getTablespaces(); 84 85 $misc->printTrail('table'); 86 $misc->printTitle($lang['strcreateindex'],'pg.index.create'); 87 $misc->printMsg($msg); 88 89 $selColumns = new XHTML_select("TableColumnList",true,10); 90 $selColumns->set_style("width: 10em;"); 91 92 if ($attrs->recordCount() > 0) { 93 while (!$attrs->EOF) { 94 $XHTML_Option = new XHTML_Option($attrs->fields['attname']); 95 $selColumns->add($XHTML_Option); 96 $attrs->moveNext(); 97 } 98 } 99 100 $selIndex = new XHTML_select("IndexColumnList[]", true, 10); 101 $selIndex->set_style("width: 10em;"); 102 $selIndex->set_attribute("id", "IndexColumnList"); 103 $buttonAdd = new XHTML_Button("add", ">>"); 104 $buttonAdd->set_attribute("onclick", "buttonPressed(this);"); 105 $buttonAdd->set_attribute("type", "button"); 106 107 $buttonRemove = new XHTML_Button("remove", "<<"); 108 $buttonRemove->set_attribute("onclick", "buttonPressed(this);"); 109 $buttonRemove->set_attribute("type", "button"); 110 111 echo "<form onsubmit=\"doSelectAll();\" name=\"formIndex\" action=\"indexes.php\" method=\"post\">\n"; 112 113 114 echo "<table>\n"; 115 echo "<tr><th class=\"data required\" colspan=\"3\">{$lang['strindexname']}</th></tr>"; 116 echo "<tr>"; 117 echo "<td class=\"data1\" colspan=\"3\"><input type=\"text\" name=\"formIndexName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", 118 htmlspecialchars($_POST['formIndexName']), "\" /></td></tr>"; 119 echo "<tr><th class=\"data\">{$lang['strtablecolumnlist']}</th><th class=\"data\"> </th>"; 120 echo "<th class=\"data required\">{$lang['strindexcolumnlist']}</th></tr>\n"; 121 echo "<tr><td class=\"data1\">" . $selColumns->fetch() . "</td>\n"; 122 echo "<td class=\"data1\">" . $buttonRemove->fetch() . $buttonAdd->fetch() . "</td>"; 123 echo "<td class=\"data1\">" . $selIndex->fetch() . "</td></tr>\n"; 124 echo "</table>\n"; 125 126 echo "<table> \n"; 127 echo "<tr>"; 128 echo "<th class=\"data left required\" scope=\"row\">{$lang['strindextype']}</th>"; 129 echo "<td class=\"data1\"><select name=\"formIndexType\">"; 130 foreach ($data->typIndexes as $v) { 131 echo "<option value=\"", htmlspecialchars($v), "\"", 132 ($v == $_POST['formIndexType']) ? ' selected="selected"' : '', ">", htmlspecialchars($v), "</option>\n"; 133 } 134 echo "</select></td></tr>\n"; 135 echo "<tr>"; 136 echo "<th class=\"data left\" scope=\"row\"><label for=\"formUnique\">{$lang['strunique']}</label></th>"; 137 echo "<td class=\"data1\"><input type=\"checkbox\" id=\"formUnique\" name=\"formUnique\"", (isset($_POST['formUnique']) ? 'checked="checked"' : ''), " /></td>"; 138 echo "</tr>"; 139 echo "<tr>"; 140 echo "<th class=\"data left\" scope=\"row\">{$lang['strwhere']}</th>"; 141 echo "<td class=\"data1\">(<input name=\"formWhere\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", 142 htmlspecialchars($_POST['formWhere']), "\" />)</td>"; 143 echo "</tr>"; 144 145 // Tablespace (if there are any) 146 if ($data->hasTablespaces() && $tablespaces->recordCount() > 0) { 147 echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strtablespace']}</th>\n"; 148 echo "\t\t<td class=\"data1\">\n\t\t\t<select name=\"formSpc\">\n"; 149 // Always offer the default (empty) option 150 echo "\t\t\t\t<option value=\"\"", 151 ($_POST['formSpc'] == '') ? ' selected="selected"' : '', "></option>\n"; 152 // Display all other tablespaces 153 while (!$tablespaces->EOF) { 154 $spcname = htmlspecialchars($tablespaces->fields['spcname']); 155 echo "\t\t\t\t<option value=\"{$spcname}\"", 156 ($spcname == $_POST['formSpc']) ? ' selected="selected"' : '', ">{$spcname}</option>\n"; 157 $tablespaces->moveNext(); 158 } 159 echo "\t\t\t</select>\n\t\t</td>\n\t</tr>\n"; 160 } 161 162 if ($data->hasConcurrentIndexBuild()) { 163 echo "<tr>"; 164 echo "<th class=\"data left\" scope=\"row\"><label for=\"formConcur\">{$lang['strconcurrently']}</label></th>"; 165 echo "<td class=\"data1\"><input type=\"checkbox\" id=\"formConcur\" name=\"formConcur\"", (isset($_POST['formConcur']) ? 'checked="checked"' : ''), " /></td>"; 166 echo "</tr>"; 167 } 168 169 echo "</table>"; 170 171 echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create_index\" />\n"; 172 echo $misc->form; 173 echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; 174 echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; 175 echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; 176 echo "</form>\n"; 177 } 178 179 /** 180 * Actually creates the new index in the database 181 * @@ Note: this function can't handle columns with commas in them 182 */ 183 function doSaveCreateIndex() { 184 global $data; 185 global $lang; 186 187 // Handle databases that don't have partial indexes 188 if (!isset($_POST['formWhere'])) $_POST['formWhere'] = ''; 189 // Default tablespace to null if it isn't set 190 if (!isset($_POST['formSpc'])) $_POST['formSpc'] = null; 191 192 // Check that they've given a name and at least one column 193 if ($_POST['formIndexName'] == '') doCreateIndex($lang['strindexneedsname']); 194 elseif (!isset($_POST['IndexColumnList']) || $_POST['IndexColumnList'] == '') doCreateIndex($lang['strindexneedscols']); 195 else { 196 $status = $data->createIndex($_POST['formIndexName'], $_POST['table'], $_POST['IndexColumnList'], 197 $_POST['formIndexType'], isset($_POST['formUnique']), $_POST['formWhere'], $_POST['formSpc'], 198 isset($_POST['formConcur'])); 199 if ($status == 0) 200 doDefault($lang['strindexcreated']); 201 else 202 doCreateIndex($lang['strindexcreatedbad']); 203 } 204 } 205 206 /** 207 * Show confirmation of drop index and perform actual drop 208 */ 209 function doDropIndex($confirm) { 210 global $data, $misc; 211 global $lang; 212 213 if ($confirm) { 214 $misc->printTrail('index'); 215 $misc->printTitle($lang['strdrop'],'pg.index.drop'); 216 217 echo "<p>", sprintf($lang['strconfdropindex'], $misc->printVal($_REQUEST['index'])), "</p>\n"; 218 219 echo "<form action=\"indexes.php\" method=\"post\">\n"; 220 echo "<input type=\"hidden\" name=\"action\" value=\"drop_index\" />\n"; 221 echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; 222 echo "<input type=\"hidden\" name=\"index\" value=\"", htmlspecialchars($_REQUEST['index']), "\" />\n"; 223 echo $misc->form; 224 echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; 225 echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; 226 echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; 227 echo "</form>\n"; 228 } 229 else { 230 $status = $data->dropIndex($_POST['index'], isset($_POST['cascade'])); 231 if ($status == 0) 232 doDefault($lang['strindexdropped']); 233 else 234 doDefault($lang['strindexdroppedbad']); 235 } 236 237 } 238 239 function doDefault($msg = '') { 240 global $data, $misc; 241 global $lang; 242 243 function indPre(&$rowdata, $actions) { 244 global $data, $lang; 245 246 if ($data->phpBool($rowdata->fields['indisprimary'])) { 247 $rowdata->fields['+constraints'] = $lang['strprimarykey']; 248 $actions['drop']['disable'] = true; 249 } 250 elseif ($data->phpBool($rowdata->fields['indisunique'])) { 251 $rowdata->fields['+constraints'] = $lang['struniquekey']; 252 $actions['drop']['disable'] = true; 253 } 254 else 255 $rowdata->fields['+constraints'] = ''; 256 257 return $actions; 258 } 259 260 $misc->printTrail('table'); 261 $misc->printTabs('table','indexes'); 262 $misc->printMsg($msg); 263 264 $indexes = $data->getIndexes($_REQUEST['table']); 265 266 $columns = array( 267 'index' => array( 268 'title' => $lang['strname'], 269 'field' => field('indname'), 270 ), 271 'definition' => array( 272 'title' => $lang['strdefinition'], 273 'field' => field('inddef'), 274 ), 275 'constraints' => array( 276 'title' => $lang['strconstraints'], 277 'field' => field('+constraints'), 278 'type' => 'verbatim', 279 'params'=> array('align' => 'center'), 280 ), 281 'clustered' => array( 282 'title' => $lang['strclustered'], 283 'field' => field('indisclustered'), 284 'type' => 'yesno', 285 ), 286 'actions' => array( 287 'title' => $lang['stractions'], 288 ), 289 'comment' => array( 290 'title' => $lang['strcomment'], 291 'field' => field('idxcomment'), 292 ), 293 ); 294 295 $actions = array( 296 'cluster' => array( 297 'content' => $lang['strclusterindex'], 298 'attr'=> array ( 299 'href' => array ( 300 'url' => 'indexes.php', 301 'urlvars' => array ( 302 'action' => 'confirm_cluster_index', 303 'table' => $_REQUEST['table'], 304 'index' => field('indname') 305 ) 306 ) 307 ) 308 ), 309 'reindex' => array( 310 'content' => $lang['strreindex'], 311 'attr'=> array ( 312 'href' => array ( 313 'url' => 'indexes.php', 314 'urlvars' => array ( 315 'action' => 'reindex', 316 'table' => $_REQUEST['table'], 317 'index' => field('indname') 318 ) 319 ) 320 ) 321 ), 322 'drop' => array( 323 'content' => $lang['strdrop'], 324 'attr'=> array ( 325 'href' => array ( 326 'url' => 'indexes.php', 327 'urlvars' => array ( 328 'action' => 'confirm_drop_index', 329 'table' => $_REQUEST['table'], 330 'index' => field('indname') 331 ) 332 ) 333 ) 334 ) 335 ); 336 337 $misc->printTable($indexes, $columns, $actions, 'indexes-indexes', $lang['strnoindexes'], 'indPre'); 338 339 $misc->printNavLinks(array ( 340 'create' => array ( 341 'attr'=> array ( 342 'href' => array ( 343 'url' => 'indexes.php', 344 'urlvars' => array ( 345 'action' => 'create_index', 346 'server' => $_REQUEST['server'], 347 'database' => $_REQUEST['database'], 348 'schema' => $_REQUEST['schema'], 349 'table' => $_REQUEST['table'] 350 ) 351 ) 352 ), 353 'content' => $lang['strcreateindex'] 354 ) 355 ), 'indexes-indexes', get_defined_vars()); 356 } 357 358 function doTree() { 359 global $misc, $data; 360 361 $indexes = $data->getIndexes($_REQUEST['table']); 362 363 $reqvars = $misc->getRequestVars('table'); 364 365 function getIcon($f) { 366 if ($f['indisprimary'] == 't') 367 return 'PrimaryKey'; 368 if ($f['indisunique'] == 't') 369 return 'UniqueConstraint'; 370 return 'Index'; 371 } 372 373 $attrs = array( 374 'text' => field('indname'), 375 'icon' => callback('getIcon'), 376 ); 377 378 $misc->printTree($indexes, $attrs, 'indexes'); 379 exit; 380 } 381 382 if ($action == 'tree') doTree(); 383 384 $misc->printHeader($lang['strindexes'], "<script src=\"indexes.js\" type=\"text/javascript\"></script>"); 385 386 if ($action == 'create_index' || $action == 'save_create_index') 387 echo "<body onload=\"init();\">"; 388 else 389 $misc->printBody(); 390 391 switch ($action) { 392 case 'cluster_index': 393 if (isset($_POST['cluster'])) doClusterIndex(false); 394 else doDefault(); 395 break; 396 case 'confirm_cluster_index': 397 doClusterIndex(true); 398 break; 399 case 'reindex': 400 doReindex(); 401 break; 402 case 'save_create_index': 403 if (isset($_POST['cancel'])) doDefault(); 404 else doSaveCreateIndex(); 405 break; 406 case 'create_index': 407 doCreateIndex(); 408 break; 409 case 'drop_index': 410 if (isset($_POST['drop'])) doDropIndex(false); 411 else doDefault(); 412 break; 413 case 'confirm_drop_index': 414 doDropIndex(true); 415 break; 416 default: 417 doDefault(); 418 break; 419 } 420 421 $misc->printFooter(); 422 423?> 424