* Allows tabs in textareas on IE: http://devilock.mine.nu/textarea_tab.html
* add help links everywhere. fix formatting of help links.
* Deal with named parameters that have ',' in the type name
-
+* make sure composite types are found in the find feature
* New fast navigation bar. A breadcrumb style navigation bar for fast
jumping between areas.
* Much improved grant/revoke feature
+* Allow creating and viewing composite types
Translations
* Arabic from Zaki
* A class that implements the DB interface for Postgres
* Note: This class uses ADODB and returns RecordSets.
*
- * $Id: Postgres.php,v 1.241 2004/07/19 03:01:53 chriskl Exp $
+ * $Id: Postgres.php,v 1.242 2004/08/03 09:20:15 chriskl Exp $
*/
// @@@ THOUGHT: What about inherits? ie. use of ONLY???
'drop_type' => 'sql-droptype.htm',
'operators' => 'xoper.htm',
'managing_databases' => 'managing-databases.htm',
+ 'users' => 'security17760.htm',
+ 'groups' => 'security17760.htm',
'create_database' => 'sql-createdatabase.htm',
'drop_database' => 'sql-dropdatabase.htm',
'constraints' => 'ddl-constraints.htm'
function hasTablespaces() { return false; }
function hasSignals() { return false; }
function hasNamedParams() { return false; }
+ function hasUserAndDbVariables() { return false; }
+ function hasCompositeTypes() { return false; }
}
* A class that implements the DB interface for Postgres
* Note: This class uses ADODB and returns RecordSets.
*
- * $Id: Postgres71.php,v 1.64 2004/07/10 08:51:01 chriskl Exp $
+ * $Id: Postgres71.php,v 1.65 2004/08/03 09:20:15 chriskl Exp $
*/
// @@@ THOUGHT: What about inherits? ie. use of ONLY???
'drop_type' => 'sql-droptype.html',
'operators' => 'xoper.html',
'managing_databases' => 'managing-databases.html',
+ 'users' => 'user-manag.html#DATABASE-USERS',
+ 'groups' => 'groups.html',
'create_database' => 'sql-createdatabase.html',
'drop_database' => 'sql-dropdatabase.html',
'constraints' => 'ddl-constraints.html'
* A class that implements the DB interface for Postgres
* Note: This class uses ADODB and returns RecordSets.
*
- * $Id: Postgres73.php,v 1.133 2004/07/22 13:29:19 jollytoad Exp $
+ * $Id: Postgres73.php,v 1.134 2004/08/03 09:20:15 chriskl Exp $
*/
// @@@ THOUGHT: What about inherits? ie. use of ONLY???
return $this->selectSet($sql);
}
-
+
+ /**
+ * Creates a new composite type in the database
+ * @param $name The name of the type
+ * @param $fields The number of fields
+ * @param $field An array of field names
+ * @param $type An array of field types
+ * @param $array An array of '' or '[]' for each type if it's an array or not
+ * @param $length An array of field lengths
+ * @param $colcomment An array of comments
+ * @param $typcomment Type comment
+ * @return 0 success
+ * @return -1 no fields supplied
+ */
+ function createCompositeType($name, $fields, $field, $type, $array, $length, $colcomment, $typcomment) {
+ $this->fieldClean($name);
+ $this->clean($typcomment);
+
+ $status = $this->beginTransaction();
+ if ($status != 0) return -1;
+
+ $found = false;
+ $first = true;
+ $comment_sql = ''; // Accumulate comments for the columns
+ $sql = "CREATE TYPE \"{$name}\" AS (";
+ for ($i = 0; $i < $fields; $i++) {
+ $this->fieldClean($field[$i]);
+ $this->clean($type[$i]);
+ $this->clean($length[$i]);
+ $this->clean($colcomment[$i]);
+
+ // Skip blank columns - for user convenience
+ if ($field[$i] == '' || $type[$i] == '') continue;
+ // If not the first column, add a comma
+ if (!$first) $sql .= ", ";
+ else $first = false;
+
+ switch ($type[$i]) {
+ // Have to account for weird placing of length for with/without
+ // time zone types
+ case 'timestamp with time zone':
+ case 'timestamp without time zone':
+ $qual = substr($type[$i], 9);
+ $sql .= "\"{$field[$i]}\" timestamp";
+ if ($length[$i] != '') $sql .= "({$length[$i]})";
+ $sql .= $qual;
+ break;
+ case 'time with time zone':
+ case 'time without time zone':
+ $qual = substr($type[$i], 4);
+ $sql .= "\"{$field[$i]}\" time";
+ if ($length[$i] != '') $sql .= "({$length[$i]})";
+ $sql .= $qual;
+ break;
+ default:
+ $sql .= "\"{$field[$i]}\" {$type[$i]}";
+ if ($length[$i] != '') $sql .= "({$length[$i]})";
+ }
+ // Add array qualifier if necessary
+ if ($array[$i] == '[]') $sql .= '[]';
+
+ if ($colcomment[$i] != '') $comment_sql .= "COMMENT ON COLUMN \"{$name}\".\"{$field[$i]}\" IS '{$colcomment[$i]}';\n";
+
+ $found = true;
+ }
+
+ if (!$found) return -1;
+
+ $sql .= ")";
+
+ $status = $this->execute($sql);
+ if ($status) {
+ $this->rollbackTransaction();
+ return -1;
+ }
+
+ if ($typcomment != '') {
+ $status = $this->setComment('TYPE', $name, '', $typcomment, true);
+ if ($status) {
+ $this->rollbackTransaction();
+ return -1;
+ }
+ }
+
+ if ($comment_sql != '') {
+ $status = $this->execute($comment_sql);
+ if ($status) {
+ $this->rollbackTransaction();
+ return -1;
+ }
+ }
+ return $this->endTransaction();
+
+ }
+
// Rule functions
/**
function hasFullExplain() { return true; }
function hasForeignKeysInfo() { return true; }
function hasViewColumnRename() { return true; }
-
+ function hasUserAndDbVariables() { return true; }
+ function hasCompositeTypes() { return true; }
}
?>
* English language file for phpPgAdmin. Use this as a basis
* for new translations.
*
- * $Id: english.php,v 1.158 2004/07/23 07:28:24 chriskl Exp $
+ * $Id: english.php,v 1.159 2004/08/03 09:20:16 chriskl Exp $
*/
// Language and character set
$lang['strnotype'] = 'No type found.';
$lang['strnotypes'] = 'No types found.';
$lang['strcreatetype'] = 'Create type';
+ $lang['strcreatecomptype'] = 'Create composite type';
+ $lang['strtypeneedsfield'] = 'You must specify at least one field.';
+ $lang['strtypeneedscols'] = 'Composite types require a valid number of columns.';
$lang['strtypename'] = 'Type name';
$lang['strinputfn'] = 'Input function';
$lang['stroutputfn'] = 'Output function';
* English language file for phpPgAdmin. Use this as a basis
* for new translations.
*
- * $Id: english.php,v 1.110 2004/07/23 07:28:24 chriskl Exp $
+ * $Id: english.php,v 1.111 2004/08/03 09:20:16 chriskl Exp $
*/
// Language and character set
$lang['strnotype'] = 'No type found.';
$lang['strnotypes'] = 'No types found.';
$lang['strcreatetype'] = 'Create type';
+ $lang['strcreatecomptype'] = 'Create composite type';
+ $lang['strtypeneedsfield'] = 'You must specify at least one field.';
+ $lang['strtypeneedscols'] = 'Composite types require a valid number of columns.';
$lang['strtypename'] = 'Type name';
$lang['strinputfn'] = 'Input function';
$lang['stroutputfn'] = 'Output function';
/**
* Manage types in a database
*
- * $Id: types.php,v 1.21 2004/07/22 13:39:11 jollytoad Exp $
+ * $Id: types.php,v 1.22 2004/08/03 09:20:14 chriskl Exp $
*/
// Include application functions
'comment' => array(
'title' => $lang['strcomment'],
'field' => 'comment',
- ),
+ )
);
$actions = array();
}
}
+
+ /**
+ * Displays a screen where they can enter a new composite type
+ */
+ function doCreateComposite($msg = '') {
+ global $data, $misc;
+ global $PHP_SELF, $lang;
+
+ if (!isset($_REQUEST['stage'])) $_REQUEST['stage'] = 1;
+ if (!isset($_REQUEST['name'])) $_REQUEST['name'] = '';
+ if (!isset($_REQUEST['fields'])) $_REQUEST['fields'] = '';
+ if (!isset($_REQUEST['typcomment'])) $_REQUEST['typcomment'] = '';
+
+ switch ($_REQUEST['stage']) {
+ case 1:
+ $misc->printTitle(array($misc->printVal($_REQUEST['database']), $lang['strtypes'], $lang['strcreatecomptype']), 'create_type');
+ $misc->printMsg($msg);
+
+ echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+ echo "<table>\n";
+ echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n";
+ echo "\t\t<td class=\"data\"><input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"",
+ htmlspecialchars($_REQUEST['name']), "\" /></td>\n\t</tr>\n";
+ echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strnumfields']}</th>\n";
+ echo "\t\t<td class=\"data\"><input name=\"fields\" size=\"5\" maxlength=\"{$data->_maxNameLen}\" value=\"",
+ htmlspecialchars($_REQUEST['fields']), "\" /></td>\n\t</tr>\n";
+
+ echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n";
+ echo "\t\t<td><textarea name=\"typcomment\" rows=\"3\" cols=\"32\" wrap=\"virtual\">",
+ htmlspecialchars($_REQUEST['typcomment']), "</textarea></td>\n\t</tr>\n";
+
+ echo "</table>\n";
+ echo "<p><input type=\"hidden\" name=\"action\" value=\"create_comp\" />\n";
+ echo "<input type=\"hidden\" name=\"stage\" value=\"2\" />\n";
+ echo $misc->form;
+ echo "<input type=\"submit\" value=\"{$lang['strnext']}\" />\n";
+ echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n";
+ echo "</form>\n";
+ break;
+ case 2:
+ global $lang;
+
+ // Check inputs
+ $fields = trim($_REQUEST['fields']);
+ if (trim($_REQUEST['name']) == '') {
+ $_REQUEST['stage'] = 1;
+ doCreateComposite($lang['strtypeneedsname']);
+ return;
+ }
+ elseif ($fields == '' || !is_numeric($fields) || $fields != (int)$fields || $fields < 1) {
+ $_REQUEST['stage'] = 1;
+ doCreateComposite($lang['strtypeneedscols']);
+ return;
+ }
+
+ $types = &$data->getTypes(true, false, true);
+
+ $misc->printTitle(array($misc->printVal($_REQUEST['database']), $lang['strtypes'], $lang['strcreatecomptype']), 'create_type');
+ $misc->printMsg($msg);
+
+ echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+
+ // Output table header
+ echo "<table>\n";
+ echo "\t<tr><th colspan=\"2\" class=\"data required\">{$lang['strfield']}</th><th colspan=\"2\" class=\"data required\">{$lang['strtype']}</th>";
+ echo"<th class=\"data\">{$lang['strlength']}</th><th class=\"data\">{$lang['strcomment']}</th></tr>\n";
+
+ for ($i = 0; $i < $_REQUEST['fields']; $i++) {
+ if (!isset($_REQUEST['field'][$i])) $_REQUEST['field'][$i] = '';
+ if (!isset($_REQUEST['length'][$i])) $_REQUEST['length'][$i] = '';
+ if (!isset($_REQUEST['colcomment'][$i])) $_REQUEST['colcomment'][$i] = '';
+
+ echo "\t<tr>\n\t\t<td>", $i + 1, ". </td>\n";
+ echo "\t\t<td><input name=\"field[{$i}]\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"",
+ htmlspecialchars($_REQUEST['field'][$i]), "\" /></td>\n";
+ echo "\t\t<td>\n\t\t\t<select name=\"type[{$i}]\">\n";
+ $types->moveFirst();
+ while (!$types->EOF) {
+ $typname = $types->f['typname'];
+ echo "\t\t\t\t<option value=\"", htmlspecialchars($typname), "\"",
+ (isset($_REQUEST['type'][$i]) && $typname == $_REQUEST['type'][$i]) ? ' selected="selected"' : '', ">",
+ $misc->printVal($typname), "</option>\n";
+ $types->moveNext();
+ }
+ echo "\t\t\t</select>\n\t\t</td>\n";
+
+ // Output array type selector
+ echo "\t\t<td>\n\t\t\t<select name=\"array[{$i}]\">\n";
+ echo "\t\t\t\t<option value=\"\"", (isset($_REQUEST['array'][$i]) && $_REQUEST['array'][$i] == '') ? ' selected="selected"' : '', "></option>\n";
+ echo "\t\t\t\t<option value=\"[]\"", (isset($_REQUEST['array'][$i]) && $_REQUEST['array'][$i] == '[]') ? ' selected="selected"' : '', ">[ ]</option>\n";
+ echo "\t\t\t</select>\n\t\t</td>\n";
+
+ echo "\t\t<td><input name=\"length[{$i}]\" size=\"10\" value=\"",
+ htmlspecialchars($_REQUEST['length'][$i]), "\" /></td>\n";
+ echo "\t\t<td><input name=\"colcomment[{$i}]\" size=\"40\" value=\"",
+ htmlspecialchars($_REQUEST['colcomment'][$i]), "\" /></td>\n\t</tr>\n";
+ }
+ echo "</table>\n";
+ echo "<p><input type=\"hidden\" name=\"action\" value=\"create_comp\" />\n";
+ echo "<input type=\"hidden\" name=\"stage\" value=\"3\" />\n";
+ echo $misc->form;
+ echo "<input type=\"hidden\" name=\"name\" value=\"", htmlspecialchars($_REQUEST['name']), "\" />\n";
+ echo "<input type=\"hidden\" name=\"fields\" value=\"", htmlspecialchars($_REQUEST['fields']), "\" />\n";
+ echo "<input type=\"hidden\" name=\"typcomment\" value=\"", htmlspecialchars($_REQUEST['typcomment']), "\" />\n";
+ echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n";
+ echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n";
+ echo "</form>\n";
+
+ break;
+ case 3:
+ global $data, $lang;
+
+ // Check inputs
+ $fields = trim($_REQUEST['fields']);
+ if (trim($_REQUEST['name']) == '') {
+ $_REQUEST['stage'] = 1;
+ doCreateComposite($lang['strtypeneedsname']);
+ return;
+ }
+ elseif ($fields == '' || !is_numeric($fields) || $fields != (int)$fields || $fields <= 0) {
+ $_REQUEST['stage'] = 1;
+ doCreateComposite($lang['strtypeneedscols']);
+ return;
+ }
+
+ $status = $data->createCompositeType($_REQUEST['name'], $_REQUEST['fields'], $_REQUEST['field'],
+ $_REQUEST['type'], $_REQUEST['array'], $_REQUEST['length'], $_REQUEST['colcomment'],
+ $_REQUEST['typcomment']);
+
+ if ($status == 0)
+ doDefault($lang['strtypecreated']);
+ elseif ($status == -1) {
+ $_REQUEST['stage'] = 2;
+ doCreateComposite($lang['strtypeneedsfield']);
+ return;
+ }
+ else {
+ $_REQUEST['stage'] = 2;
+ doCreateComposite($lang['strtypecreatedbad']);
+ return;
+ }
+ break;
+ default:
+ global $lang;
+ echo "<p>{$lang['strinvalidparam']}</p>\n";
+ }
+ }
/**
* Displays a screen where they can enter a new type
$misc->printTable($types, $columns, $actions, $lang['strnotypes']);
- echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create&{$misc->href}\">{$lang['strcreatetype']}</a></p>\n";
+ echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create&{$misc->href}\">{$lang['strcreatetype']}</a>";
+ if ($data->hasCompositeTypes())
+ echo "\n| <a class=\"navlink\" href=\"$PHP_SELF?action=create_comp&{$misc->href}\">{$lang['strcreatecomptype']}</a>";
+ echo "</p>\n";
}
$misc->printNav('schema','types');
switch ($action) {
+ case 'create_comp':
+ if (isset($_POST['cancel'])) doDefault();
+ else doCreateComposite();
+ break;
case 'save_create':
if (isset($_POST['cancel'])) doDefault();
else doSaveCreate();