summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchriskl2003-03-12 02:29:46 +0000
committerchriskl2003-03-12 02:29:46 +0000
commit6004f2c6c5baa4b7e076150f73a26e32b3ccca29 (patch)
tree96147912dac535c2104bf67e00932cbf65b9c114
parent0c77cd05574e242e15a9643ba08cb4089aae839d (diff)
Extensive trigger and index improvements from Felix Meinhold ([email protected])
-rw-r--r--classes/Misc.php8
-rw-r--r--classes/class.select.php217
-rwxr-xr-xclasses/database/Postgres.php39
-rw-r--r--classes/database/Postgres73.php32
-rw-r--r--indexes.js70
-rw-r--r--indexes.php90
-rwxr-xr-xlang/english.php7
-rw-r--r--lang/recoded/english.php7
-rw-r--r--triggers.php154
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\">&nbsp;</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 &quot;%s&quot; on &quot;%s&quot;?';
$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\">&nbsp;</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':