diff options
author | chriskl | 2003-03-12 02:29:46 +0000 |
---|---|---|
committer | chriskl | 2003-03-12 02:29:46 +0000 |
commit | 6004f2c6c5baa4b7e076150f73a26e32b3ccca29 (patch) | |
tree | 96147912dac535c2104bf67e00932cbf65b9c114 | |
parent | 0c77cd05574e242e15a9643ba08cb4089aae839d (diff) |
Extensive trigger and index improvements from Felix Meinhold ([email protected])
-rw-r--r-- | classes/Misc.php | 8 | ||||
-rw-r--r-- | classes/class.select.php | 217 | ||||
-rwxr-xr-x | classes/database/Postgres.php | 39 | ||||
-rw-r--r-- | classes/database/Postgres73.php | 32 | ||||
-rw-r--r-- | indexes.js | 70 | ||||
-rw-r--r-- | indexes.php | 90 | ||||
-rwxr-xr-x | lang/english.php | 7 | ||||
-rw-r--r-- | lang/recoded/english.php | 7 | ||||
-rw-r--r-- | triggers.php | 154 |
9 files changed, 573 insertions, 51 deletions
diff --git a/classes/Misc.php b/classes/Misc.php index 5572076d..98319a64 100644 --- a/classes/Misc.php +++ b/classes/Misc.php @@ -2,7 +2,7 @@ /** * Class to hold various commonly used functions * - * $Id: Misc.php,v 1.14 2003/03/01 00:53:50 slubek Exp $ + * $Id: Misc.php,v 1.15 2003/03/12 02:29:47 chriskl Exp $ */ class Misc { @@ -82,8 +82,9 @@ * Prints the page header. If global variable $_no_output is * set then no header is drawn. * @param $title The title of the page + * @param $script script tag */ - function printHeader($title = '') { + function printHeader($title = '', $script = null) { global $appName, $appCharset, $_no_output, $guiTheme; if (!isset($_no_output)) { @@ -95,11 +96,12 @@ if ($title != '') echo " - ", htmlspecialchars($title); echo "</title>\n"; echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset={$appCharset}\" />\n"; - + // Theme echo "<style type=\"text/css\">\n<!--\n"; include("themes/{$guiTheme}/global.css"); echo "\n-->\n</style>\n"; + if ($script) echo "\n {$script} \n"; echo "</head>\n"; } } diff --git a/classes/class.select.php b/classes/class.select.php new file mode 100644 index 00000000..fe8244f1 --- /dev/null +++ b/classes/class.select.php @@ -0,0 +1,217 @@ +<?php
+
+/**
+* XHtmlSimpleElement
+*
+* Used to generate Xhtml-Code for simple xhtml elements
+* (i.e. elements, that can't contain child elements)
+*
+*
+* @author Felix Meinhold
+*
+*/
+class XHtmlSimpleElement {
+ var $_element;
+ var $_siblings = array();
+ var $_htmlcode;
+ var $_attributes = array();
+
+
+ /**
+ * Constructor
+ *
+ * @param string The element's name. Defaults to name of the
+ * derived class
+ *
+ */
+ function XHtmlSimpleElement($element = null) {
+
+ $this->_element = $this->is_element();
+
+ }
+
+ function set_style($style) {
+ $this->set_attribute("style", $style);
+ }
+
+ function set_class($class) {
+ $this->set_attribute("class", $class);
+ }
+
+
+ function is_element() {
+ return
+ str_replace("xhtml_", "", get_class($this));
+ }
+
+ /**
+ * Private function generates xhtml
+ * @access private
+ */
+ function _html() {
+ $this->_htmlcode = "<";
+ foreach ($this->_attributeCollection as $attribute => $value) {
+ if (!empty($value)) $this->_htmlcode .= " {$attribute}=\"{$value}\"";
+ }
+ $this->_htmlcode .= "/>";
+
+ return $this->_htmlcode;
+ }
+
+ /**
+ * Returns xhtml code
+ *
+ */
+ function fetch() {
+ return $this->_html();
+ }
+ /**
+ * Echoes xhtml
+ *
+ */
+ function show() {
+ echo $this->fetch();
+ }
+
+ function set_attribute($attr, $value) {
+ $this->_attributes[$attr] = $value;
+ }
+
+
+}
+
+/**
+* XHtmlElement
+*
+* Used to generate Xhtml-Code for xhtml elements
+* that can contain child elements
+*
+*
+*/
+class XHtmlElement extends XHtmlSimpleElement {
+ var $_text = null;
+ var $_htmlcode = "";
+ var $_siblings = array();
+
+ function XHtmlElement($text = null) {
+ XHtmlSimpleElement::XHtmlSimpleElement();
+
+ if ($text) $this->set_text($text);
+ }
+
+ /*
+ * Adds an xhtml child to element
+ *
+ * @param XHtmlElement The element to become a child of element
+ */
+ function add(&$object) {
+ array_push($this->_siblings,& $object);
+ }
+
+
+ /*
+ * The CDATA section of Element
+ *
+ * @param string Text
+ */
+ function set_text($text) {
+ if ($text) $this->_text = htmlspecialchars($text);
+ }
+
+ function fetch() {
+ return $this->_html();
+ }
+
+
+ function _html() {
+
+ $this->_htmlcode = "<{$this->_element}";
+ foreach ($this->_attributes as $attribute =>$value) {
+ if (!empty($value)) $this->_htmlcode .= " {$attribute} =\"{$value}\"";
+ }
+ $this->_htmlcode .= ">";
+
+
+ if ($this->_text) {
+ $this->_htmlcode .= $this->_text;
+ }
+
+ foreach ($this->_siblings as $obj) {
+ $this->_htmlcode .= $obj->fetch();
+ }
+
+ $this->_htmlcode .= "</{$this->_element}>";
+
+ return $this->_htmlcode;
+ }
+
+ /*
+ * Returns siblings of Element
+ *
+ */
+ function get_siblings() {
+ return $this->_siblings;
+ }
+
+ function has_siblings() {
+ return (count($this->_siblings) != 0);
+ }
+}
+
+class XHTML_Button extends XHtmlElement {
+ function XHTML_Button ($name, $text = null) {
+ parent::XHtmlElement();
+
+ $this->set_attribute("name", $name);
+
+ if ($text) $this->set_text($text);
+ }
+}
+
+
+class XHTML_Option extends XHtmlElement {
+ function XHTML_Option($text, $value = null) {
+ XHtmlElement::XHtmlElement(null);
+ $this->set_text($text);
+ }
+}
+
+
+class XHTML_Select extends XHTMLElement {
+ var $_data;
+
+ function XHTML_Select ($name, $multiple = false, $size = null) {
+ XHtmlElement::XHtmlElement();
+
+ $this->set_attribute("name", $name);
+ if ($multiple) $this->set_attribute("multiple","multiple");
+ if ($size) $this->set_attribute("size",$size);
+
+
+ }
+
+ function set_data(&$data, $delim = ",") {
+ switch (gettype($data)) {
+ case "string":
+ $this->_data = explode($delim, $data);
+ break;
+ case "array":
+ $this->_data = $data;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ function fetch() {
+ if ($this->_data) {
+ foreach ($this->_data as $value) { $this->add(new XHTML_Option($value)); }
+ }
+ return parent::fetch();
+ }
+
+}
+
+
+?>
\ No newline at end of file diff --git a/classes/database/Postgres.php b/classes/database/Postgres.php index f3c7632c..741d6616 100755 --- a/classes/database/Postgres.php +++ b/classes/database/Postgres.php @@ -4,7 +4,7 @@ * A class that implements the DB interface for Postgres * Note: This class uses ADODB and returns RecordSets. * - * $Id: Postgres.php,v 1.54 2003/03/10 02:15:15 chriskl Exp $ + * $Id: Postgres.php,v 1.55 2003/03/12 02:29:47 chriskl Exp $ */ // @@@ THOUGHT: What about inherits? ie. use of ONLY??? @@ -21,7 +21,7 @@ class Postgres extends BaseDB { var $sqFields = array('seqname' => 'relname', 'seqowner' => 'usename', 'lastvalue' => 'last_value', 'incrementby' => 'increment_by', 'maxvalue' => 'max_value', 'minvalue'=> 'min_value', 'cachevalue' => 'cache_value', 'logcount' => 'log_cnt', 'iscycled' => 'is_cycled', 'iscalled' => 'is_called' ); var $ixFields = array('idxname' => 'relname', 'idxdef' => 'pg_get_indexdef', 'uniquekey' => 'indisunique', 'primarykey' => 'indisprimary'); var $rlFields = array('rulename' => 'rulename', 'ruledef' => 'definition'); - var $tgFields = array('tgname' => 'tgname'); + var $tgFields = array('tgname' => 'tgname', 'tgtype' => 'tgtype', 'proname' => 'proname'); var $cnFields = array('conname' => 'conname', 'consrc' => 'consrc', 'contype' => 'contype'); var $typFields = array('typname' => 'typname', 'typowner' => 'typowner', 'typin' => 'typin', 'typout' => 'typout', 'typlen' => 'typlen', 'typdef' => 'typdef', 'typelem' => 'typelem', @@ -38,6 +38,14 @@ class Postgres extends BaseDB { var $typStorageDef = 'plain'; // Extra "magic" types var $extraTypes = array('SERIAL'); + // Array of allowed index types + var $typIndexes = array('BTREE', 'RTREE', 'GiST', 'HASH'); + // Default index type + var $typIndexDef = 'BTREE'; + // Array of allowed trigger events + var $triggerEvents= array('INSERT','UPDATE','DELETE','INSERT OR UPDATE'); + // When to execute the trigger + var $triggerExecTimes = array('BEFORE','AFTER'); // Last oid assigned to a system object var $_lastSystemOID = 18539; @@ -1552,15 +1560,36 @@ class Postgres extends BaseDB { function &getTriggers($table = '') { $this->clean($table); - $sql = "SELECT tgname - FROM pg_trigger + $sql = "SELECT tgname,tgtype,tgargs,proname + FROM pg_trigger, pg_proc WHERE tgrelid = (SELECT oid FROM pg_class WHERE relname='{$table}') - AND NOT tgisconstraint"; + AND pg_proc.oid = pg_trigger.tgfoid + AND NOT tgisconstraint"; return $this->selectSet($sql); } /** + * Create Trigger + * + * @param $tgname The name of the trigger to create + * @param $table The name of the table + * @param $trgpoc The function to execute + * @param $trgevent The action + * @param $trevent Event + */ + function createTrigger($trgName, $table, $trgFunction, $trgExecTime, $trgEvent) { + + /* No Statement Level Triggers in PostgreSQL (by now) */ + $sql = "CREATE TRIGGER {$trgName} {$trgExecTime} + {$trgEvent} ON {$table} + FOR EACH ROW EXECUTE PROCEDURE {$trgFunction} ();"; + + return $this->execute($sql); + + } + + /** * Drops a trigger * @param $tgname The name of the trigger to drop * @param $table The table from which to drop the trigger diff --git a/classes/database/Postgres73.php b/classes/database/Postgres73.php index 97391d51..ef2ba609 100644 --- a/classes/database/Postgres73.php +++ b/classes/database/Postgres73.php @@ -4,7 +4,7 @@ * A class that implements the DB interface for Postgres * Note: This class uses ADODB and returns RecordSets. * - * $Id: Postgres73.php,v 1.21 2003/03/10 02:15:16 chriskl Exp $ + * $Id: Postgres73.php,v 1.22 2003/03/12 02:29:47 chriskl Exp $ */ // @@@ THOUGHT: What about inherits? ie. use of ONLY??? @@ -451,14 +451,17 @@ class Postgres73 extends Postgres72 { function &getTriggers($table = '') { $this->clean($table); - $sql = "SELECT t.tgname - FROM pg_catalog.pg_trigger t - WHERE t.tgrelid = (SELECT oid FROM pg_catalog.pg_class WHERE relname='{$table}' - AND relnamespace=(SELECT oid FROM pg_catalog.pg_namespace WHERE nspname='{$this->_schema}')) - AND (NOT tgisconstraint OR NOT EXISTS - (SELECT 1 FROM pg_catalog.pg_depend d JOIN pg_catalog.pg_constraint c - ON (d.refclassid = c.tableoid AND d.refobjid = c.oid) - WHERE d.classid = t.tableoid AND d.objid = t.oid AND d.deptype = 'i' AND c.contype = 'f'))"; + $sql = "SELECT + t.tgname,t.tgargs,t.tgtype,p.proname + FROM pg_catalog.pg_trigger t,pg_catalog.pg_proc p + + WHERE t.tgrelid =(SELECT oid FROM pg_catalog.pg_class WHERE relname='{$table}' + AND (p.oid = t.tgfoid) + AND relnamespace=(SELECT oid FROM pg_catalog.pg_namespace WHERE nspname='{$this->_schema}')) + AND (NOT tgisconstraint OR NOT EXISTS (SELECT 1 FROM pg_catalog.pg_depend d JOIN pg_catalog.pg_constraint c + ON (d.refclassid = c.tableoid AND d.refobjid = c.oid) + + WHERE d.classid = t.tableoid AND d.objid = t.oid AND d.deptype = 'i' AND c.contype = 'f'))"; return $this->selectSet($sql); } @@ -468,15 +471,22 @@ class Postgres73 extends Postgres72 { /** * Returns a list of all functions in the database * @param $all If true, will find all available functions, if false just those in search path - * @return All functions + * @param $type If not null, will find all functions with return value = type + * + * @return All functions */ - function &getFunctions($all = false) { + function &getFunctions($all = false, $type = null) { if ($all) { $where = 'pg_catalog.pg_function_is_visible(p.oid)'; $distinct = 'DISTINCT ON (p.proname)'; } else { $where = "n.nspname = '{$this->_schema}'"; + + if ($type) { + $where .= " AND p.prorettype = (select oid from pg_catalog.pg_type p where p.typname = 'trigger') "; + } + $distinct = ''; } diff --git a/indexes.js b/indexes.js new file mode 100644 index 00000000..27160f2f --- /dev/null +++ b/indexes.js @@ -0,0 +1,70 @@ + // Globals
+ //
+
+
+ /*
+ * Multiple Selection lists in HTML Document
+ */
+ var tableColumnList;
+ var indexColumnList;
+
+ /*
+ * Two Array vars
+ */
+
+ var indexColumns, tableColumns;
+
+
+ function buttonPressed(object) {
+
+ if (object.name == "add") {
+ from = tableColumnList;
+ to = indexColumnList;
+ }
+ else {
+ to = tableColumnList;
+ from = indexColumnList;
+ }
+
+ var selectedOptions = getSelectedOptions(from);
+
+ for (i = 0; i < selectedOptions.length; i++) {
+ option = new Option(selectedOptions[i].text);
+ addToArray(to, option);
+ removeFromArray(from, selectedOptions[i].index);
+ }
+ }
+
+ function doSelectAll() {
+ for(var x = 0; x < indexColumnList.options.length; x++){
+ indexColumnList.options[x].selected = true;
+ }
+ }
+
+ function init() {
+ tableColumnList = document.formIndex.TableColumnList;
+ indexColumnList = document.getElementById("IndexColumnList");
+ indexColumns = indexColumnList.options;
+ tableColumns = tableColumnList.options;
+ }
+
+
+ function getSelectedOptions(obj) {
+ var selectedOptions = new Array();
+
+ for (i = 0; i < obj.options.length; i++) {
+ if (obj.options[i].selected) {
+ selectedOptions.push(obj.options[i]);
+ }
+ }
+
+ return selectedOptions;
+ }
+
+ function removeFromArray(obj, index) {
+ obj.remove(index);
+ }
+
+ function addToArray(obj, item) {
+ obj.options[obj.options.length] = item;
+ }
\ No newline at end of file diff --git a/indexes.php b/indexes.php index 9de9ee42..6fd5a23a 100644 --- a/indexes.php +++ b/indexes.php @@ -3,12 +3,13 @@ /** * List indexes on a table * - * $Id: indexes.php,v 1.4 2003/03/01 00:53:51 slubek Exp $ + * $Id: indexes.php,v 1.5 2003/03/12 02:29:47 chriskl Exp $ */ // Include application functions include_once('libraries/lib.inc.php'); - + include_once('classes/class.select.php'); + $action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; $PHP_SELF = $_SERVER['PHP_SELF']; @@ -17,23 +18,64 @@ */ function doCreateIndex($msg = '') { global $data, $localData, $misc; - global $PHP_SELF, $strName, $strDefinition, $strCreateIndex, $strIndexes, $strShowAllIndexes, $strColumns, $strSave, $strReset, $strExample; + global $PHP_SELF, $strName, $strDefinition, $strCreateIndex, $strShowAllIndexes, $strSave, $strReset, $strExample; + global $strTableColumnList, $strIndexColumnList, $strIndexes, $strIndexType, $strIndexName; - if (!isset($_POST['formIndex'])) $_POST['formIndex'] = ''; + if (!isset($_POST['formIndexName'])) $_POST['formIndexName'] = ''; if (!isset($_POST['formCols'])) $_POST['formCols'] = ''; echo "<h2>", htmlspecialchars($_REQUEST['database']), ": {$strIndexes} : {$strCreateIndex} </h2>\n"; $misc->printMsg($msg); - echo "<form action=\"$PHP_SELF\" method=post>\n"; - echo "<table width=100%>\n"; - echo "<tr><th class=data>{$strName}</th></tr>\n"; - echo "<tr><td class=data1><input name=formIndex size={$data->_maxNameLen} maxlength={$data->_maxNameLen} value=\"", - htmlspecialchars($_POST['formIndex']), "\"></td></tr>\n"; - echo "<tr><th class=data>{$strColumns}</th></tr>\n"; - echo "<tr><td class=data1><input name=formCols size={$data->_maxNameLen} value=\"", - htmlspecialchars($_POST['formCols']), "\"> ({$strExample} col1, col2)</td></tr>\n"; + $attrs = &$localData->getTableAttributes($_REQUEST['table']); + + $selColumns = new XHTML_select("TableColumnList",true,10); + $selColumns->set_style("width: 10em;"); + + if ($attrs->recordCount() > 0) { + while (!$attrs->EOF) { + $selColumns->add(new XHTML_Option($attrs->f['attname'])); + $attrs->moveNext(); + } + } + + $selIndex = new XHTML_select("IndexColumnList[]", true, 10); + $selIndex->set_style("width: 10em;"); + $selIndex->set_attribute("id", "IndexColumnList"); + $buttonAdd = new XHTML_Button("add", ">>"); + $buttonAdd->set_attribute("onclick", "buttonPressed(this);"); + $buttonAdd->set_attribute("type", "button"); + + $buttonRemove = new XHTML_Button("remove", "<<"); + $buttonRemove->set_attribute("onclick", "buttonPressed(this);"); + $buttonRemove->set_attribute("type", "button"); + + $selTypes = new XHTML_select("formIndexType"); + $selTypes->set_data($localData->typIndexes); + + echo "<form onsubmit=\"doSelectAll();\" name=\"formIndex\" action=\"$PHP_SELF\" method=\"post\">\n"; + + + echo "<table>\n"; + echo "<tr>"; + echo "<th class=\"data\" colspan=\"3\">{$strIndexName}</th>"; + echo "</tr>"; + echo "<tr>"; + echo "<td class=\"data1\" colspan=\"3\"><input type=\"text\" name=\"formIndexName\" size=\"80\" maxlength=\"300\"/></td></tr>"; + echo "<tr><th class=data>{$strTableColumnList}</th><th class=\"data\"> </th><th class=data>{$strIndexColumnList}</th></tr>\n"; + echo "<tr><td class=data1>" . $selColumns->fetch() . "</td>\n"; + echo "<td class=\"data1\">" . $buttonRemove->fetch() . $buttonAdd->fetch() . "</td>"; + echo "<td class=data1>" . $selIndex->fetch() . "</td></tr>\n"; echo "</table>\n"; + + echo "<table> \n"; + echo "<tr>"; + echo "<th class=\"data\">{$strIndexType}</th>"; + echo "<td>" . $selTypes->fetch() . "</td>"; + echo "</tr>"; + echo "</table>"; + + echo "<p><input type=hidden name=action value=save_create_index>\n"; echo $misc->form; echo "<input type=hidden name=table value=\"", htmlspecialchars($_REQUEST['table']), "\">\n"; @@ -51,12 +93,15 @@ function doSaveCreateIndex() { global $localData; global $strIndexNeedsName, $strIndexNeedsCols, $strIndexCreated, $strIndexCreatedBad; + + // Check that they've given a name and at least one column - if ($_POST['formIndex'] == '') doCreateIndex("{$strIndexNeedsName}"); - elseif ($_POST['formCols'] == '') doCreate("{$strIndexNeedsCols}"); + if ($_POST['formIndexName'] == '') doCreateIndex("{$strIndexNeedsName}"); + elseif ($_POST['IndexColumnList'] == '') doCreate("{$strIndexNeedsCols}"); else { - $status = $localData->createIndex($_POST['formIndex'], $_POST['table'], explode(',', $_POST['formCols'])); + + $status = $localData->createIndex($_POST['formIndexName'], $_POST['table'], $_POST['IndexColumnList'], $_POST['formIndexType']); if ($status == 0) doDefault($strIndexCreated); else @@ -98,7 +143,7 @@ function doDefault($msg = '') { global $data, $localData, $misc; global $PHP_SELF; - global $strNoIndexes, $strIndexes, $strActions, $strName, $strDefinition, $strCreateIndex, $strDrop; + global $strNoIndexes, $strIndexes, $strActions, $strName, $strDefinition, $strCreateIndex, $strDrop, $strPrivileges; $misc->printTableNav(); echo "<h2>", htmlspecialchars($_REQUEST['database']), ": ", htmlspecialchars($_REQUEST['table']), ": {$strIndexes}</h2>\n"; @@ -108,7 +153,7 @@ if ($indexes->recordCount() > 0) { echo "<table>\n"; - echo "<tr><th class=\"data\">{$strName}</th><th class=\"data\">{$strDefinition}</th><th class=\"data\">{$strActions}</th>\n"; + echo "<tr><th class=\"data\">{$strName}</th><th class=\"data\">{$strDefinition}</th><th colspan=\"2\" class=\"data\">{$strActions}</th>\n"; $i = 0; while (!$indexes->EOF) { @@ -117,7 +162,9 @@ echo "<td class=\"data{$id}\">", htmlspecialchars( $indexes->f[$data->ixFields['idxdef']]), "</td>"; echo "<td class=\"data{$id}\">"; echo "<a href=\"$PHP_SELF?action=confirm_drop_index&{$misc->href}&index=", htmlspecialchars( $indexes->f[$data->ixFields['idxname']]), - "&table=", htmlspecialchars($_REQUEST['table']), "\">{$strDrop}</td></tr>\n"; + "&table=", htmlspecialchars($_REQUEST['table']), "\">{$strDrop}</td>\n"; + echo "<td class=\"data{$id}\">"; + echo "<a href=\"$PHP_SELF?action=priviledges_index&{$misc->href}&index=", htmlspecialchars( $indexes->f[$data->ixFields['idxname']]), "\">{$strPrivileges}</td></tr>\n"; $indexes->movenext(); $i++; @@ -131,8 +178,9 @@ echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create_index&{$misc->href}&table=", htmlspecialchars($_REQUEST['table']), "\">{$strCreateIndex}</a></p>\n"; } - $misc->printHeader($strTables . ' - ' . $_REQUEST['table'] . ' - ' . $strIndexes); - $misc->printBody(); + $misc->printHeader($strIndexes, "<script src=\"indexes.js\" type=\"text/javascript\"></script>"); + + echo "<body onload=\"init();\">"; switch ($action) { case 'save_create_index': @@ -152,7 +200,7 @@ doDefault(); break; } - + $misc->printFooter(); ?> diff --git a/lang/english.php b/lang/english.php index e5a82c13..669b8146 100755 --- a/lang/english.php +++ b/lang/english.php @@ -4,7 +4,7 @@ * Language template file for WebDB. Use this to base language * files. * - * $Id: english.php,v 1.55 2003/03/10 02:15:17 chriskl Exp $ + * $Id: english.php,v 1.56 2003/03/12 02:29:47 chriskl Exp $ */ // Language and character set @@ -250,6 +250,10 @@ $strKeyName = 'Key Name'; $strUniqueKey = 'Unique Key'; $strPrimaryKey = 'Primary Key'; + $strIndexType = 'Type of index'; + $strIndexName = 'Name of index'; + $strTableColumnList = 'Columns in Table'; + $strIndexColumnList = 'Columns in Index'; // Rules $strRules = 'Rules'; @@ -312,6 +316,7 @@ $strConfDropTrigger = 'Are you sure you want to drop the trigger "%s" on "%s"?'; $strTriggerDropped = 'Trigger dropped.'; $strTriggerDroppedBad = 'Trigger drop failed.'; + // Types $strType = 'Type'; diff --git a/lang/recoded/english.php b/lang/recoded/english.php index 558dd480..9af4b600 100644 --- a/lang/recoded/english.php +++ b/lang/recoded/english.php @@ -4,7 +4,7 @@ * Language template file for WebDB. Use this to base language * files. * - * $Id: english.php,v 1.11 2003/03/10 02:15:18 chriskl Exp $ + * $Id: english.php,v 1.12 2003/03/12 02:29:47 chriskl Exp $ */ // Language and character set @@ -250,6 +250,10 @@ $strKeyName = 'Key Name'; $strUniqueKey = 'Unique Key'; $strPrimaryKey = 'Primary Key'; + $strIndexType = 'Type of index'; + $strIndexName = 'Name of index'; + $strTableColumnList = 'Columns in Table'; + $strIndexColumnList = 'Columns in Index'; // Rules $strRules = 'Rules'; @@ -312,6 +316,7 @@ $strConfDropTrigger = 'Are you sure you want to drop the trigger "%s" on "%s"?'; $strTriggerDropped = 'Trigger dropped.'; $strTriggerDroppedBad = 'Trigger drop failed.'; + // Types $strType = 'Type'; diff --git a/triggers.php b/triggers.php index 746e033a..a58d5a76 100644 --- a/triggers.php +++ b/triggers.php @@ -3,15 +3,43 @@ /** * List triggers on a table * - * $Id: triggers.php,v 1.3 2003/03/01 00:53:51 slubek Exp $ + * $Id: triggers.php,v 1.4 2003/03/12 02:29:47 chriskl Exp $ */ // Include application functions include_once('libraries/lib.inc.php'); - + include_once('classes/class.select.php'); + + // Constants to figure out tgtype + + define ('TRIGGER_TYPE_ROW', (1 << 0) ); + define ('TRIGGER_TYPE_BEFORE', (1 << 1) ); + define ('TRIGGER_TYPE_INSERT', (1 << 2) ); + define ('TRIGGER_TYPE_DELETE', (1 << 3) ); + define ('TRIGGER_TYPE_UPDATE', (1 << 4) ); + $action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; $PHP_SELF = $_SERVER['PHP_SELF']; + + + function getTriggerExecTime($type) { + $execTime = "AFTER"; + if ($type & TRIGGER_TYPE_BEFORE) $execTime = "BEFORE"; + + return $execTime; + } + + function getTriggerEvent($type) { + if ($type & TRIGGER_TYPE_INSERT) $event = "INSERT"; + elseif ($type & TRIGGER_TYPE_DELETE) $event = "DELETE"; + + if ($type & TRIGGER_TYPE_UPDATE) $event .= (empty($event)) ? "UPDATE" : " OR UPDATE"; + + return $event; + + } + /** * Show confirmation of drop and perform actual drop */ @@ -45,13 +73,82 @@ } /** + * Let them create s.th. + */ + function doCreate($msg = '') { + global $data, $localData, $misc; + global $PHP_SELF; + global $strTriggerEvents, $strTriggerWhen, $strCreateTrigger,$strTriggerNeedsFunction; + global $strTriggerFunction,$strTriggerEvent,$strTriggerExecTimes, $strSave, $strReset; + global $strFunction,$strTriggerName,$strTriggerArgs; + + + echo "<h2>",$strCreateTrigger,"</h2>"; + + $misc->printMsg($msg); + + // List only functions, that return "trigger" + $funcs = &$localData->getFunctions(false, 'trigger'); + + if ($funcs->recordCount() == 0) { + echo "<p class='message'>" . $strTriggerNeedsFunction . "</p>"; + return; + } + + + /* Populate functions */ + $sel0 = new XHTML_Select("formFunction"); + $sel0->set_style("width: 20em;"); + while (!$funcs->EOF) { + $sel0->add(new XHTML_Option($funcs->f[$data->fnFields['fnname']])); + $funcs->moveNext(); + } + + $sel1 = new XHTML_Select('formExecTime'); + $sel1->set_style("width: 7em;"); + $sel1->set_data($localData->triggerExecTimes); + + /* Populate events */ + $sel2 = new XHTML_Select('formEvent'); + $sel2->set_style("width: 7em;"); + $sel2->set_data($localData->triggerEvents); + + echo "<form action=\"$PHP_SELF\" method=\"POST\">\n"; + echo "<table>"; + echo "<tr><th colspan=\"4\" class=\"data\">{$strTriggerName}</th>"; + echo "</tr>"; + echo "<tr><td colspan=\"4\" class=\"data1\"><input type=\"text\" name=\"formTriggerName\" size=\"80\"/></th>"; + echo "</tr>"; + echo "<tr><th class=\"data\"> </th>"; + echo " <th class=\"data\">{$strFunction}</th>"; + echo " <th class=\"data\">{$strTriggerWhen}</th>"; + echo " <th class=\"data\">{$strTriggerEvent}</th>"; + echo "</tr>"; + echo " <tr><td class=\"data1\">{$strTriggerFunction}</td>\n"; + echo " <td class=\"data1\">" . $sel0->fetch() ."</td>"; + echo " <td class=\"data1\">" . $sel1->fetch() . "</td>"; + echo " <td class=\"data1\">" . $sel2->fetch() . "</td>"; + echo "</tr>"; + echo "<th colspan=\"4\" class=\"data\">{$strTriggerArgs}</th>"; + echo "<tr><td colspan=\"4\" class=\"data1\"><input type=\"text\" name=\"formTriggerArgs\" size=\"80\"/></th>"; + echo "</table>"; + echo "<p><input type=submit value=\"{$strSave}\"> <input type=reset value=\"{$strReset}\"></p>\n"; + echo "<input type=hidden value=save_create name=\"action\">"; + echo "<input type=hidden name=table value=\"", htmlspecialchars($_REQUEST['table']), "\">\n"; + echo $misc->form; + echo "</form>"; + } + + + /** * List all the triggers on the table */ function doDefault($msg = '') { - global $data, $localData, $misc; + global $data, $localData, $misc, $database; global $PHP_SELF; global $strTriggers, $strName, $strActions, $strNoTriggers, $strCreateTrigger, $strDrop; - + global $strTriggerWhen, $strTriggerEvent,$strFunction; + $misc->printTableNav(); echo "<h2>", htmlspecialchars($_REQUEST['database']), ": ", htmlspecialchars($_REQUEST['table']), ": {$strTriggers}</h2>\n"; $misc->printMsg($msg); @@ -60,12 +157,24 @@ if ($triggers->recordCount() > 0) { echo "<table>\n"; - echo "<tr><th class=\"data\">{$strName}</th><th class=\"data\">{$strActions}</th>\n"; + echo "<tr>"; + echo "<th class=\"data\">{$strName}</th>"; + echo "<th class=\"data\">{$strTriggerWhen}</th>"; + echo "<th class=\"data\">{$strTriggerEvent}</th>\n"; + echo "<th class=\"data\">{$strFunction}</th>\n"; + echo "</tr>"; $i = 0; - + while (!$triggers->EOF) { + $execTime = htmlspecialchars( getTriggerExecTime($triggers->f[$data->tgFields['tgtype']])); + $event = htmlspecialchars( getTriggerEvent($triggers->f[$data->tgFields['tgtype']])); $id = ( ($i % 2 ) == 0 ? '1' : '2' ); - echo "<tr><td class=\"data{$id}\">", htmlspecialchars( $triggers->f[$data->tgFields['tgname']]), "</td>"; + + echo "<tr>"; + echo "<td class=\"data{$id}\">", htmlspecialchars( $triggers->f[$data->tgFields['tgname']]), "</td>"; + echo "<td class=\"data{$id}\">{$execTime}</td>"; + echo "<td class=\"data{$id}\">{$event}</td>"; + echo "<td class=\"data{$id}\">",htmlspecialchars( $triggers->f[$data->tgFields['proname']]),"</td>"; echo "<td class=\"data{$id}\">"; echo "<a href=\"$PHP_SELF?action=confirm_drop&{$misc->href}&trigger=", htmlspecialchars( $triggers->f[$data->tgFields['tgname']]), "&table=", htmlspecialchars($_REQUEST['table']), "\">{$strDrop}</td></tr>\n"; @@ -79,11 +188,38 @@ else echo "<p>{$strNoTriggers}</p>\n"; - //echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create&{$misc->href}&table=", htmlspecialchars($_REQUEST['table']), "\">{$strCreateTrigger}</a></p>\n"; + echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create&{$misc->href}&table=", htmlspecialchars($_REQUEST['table']), "\">{$strCreateTrigger}</a></p>\n"; } + /** + * Actually creates the new trigger in the database + */ + function doSaveCreate() { + global $data, $localData, $misc, $database; + global $PHP_SELF; + global $strTriggerNeedsFunction, $strTriggerDone, $strTriggerNeedsName; + + + // Check that they've given a name and a definition + + if ($_POST['formFunction'] == '') + doCreate($strTriggerNeedsFunction); + elseif ($_POST['formExecTime'] == '') + doCreate(); + elseif ($_POST['formTriggerName'] == '') + doCreate($strTriggerNeedsName); + elseif ($_POST['formEvent'] == '') + doCreate(); + else { + $status = &$localData->createTrigger($_POST['formTriggerName'],$_POST['table'], $_POST['formFunction'], $_POST['formExecTime'] , $_POST['formEvent']); + if ($status == 0) + doDefault($strTriggerDone); + else + doCreate($strTriggerFailed); + } + } + $misc->printHeader($strTables . ' - ' . $_REQUEST['table'] . ' - ' . $strTriggers); - $misc->printBody(); switch ($action) { case 'save_create': |