From: ssilk
Date: Mon Jan 29 00:08:25 2001
Modified files:
php-lib/php/tree_sql.inc
Log message:
Bigfixes of the tree-classes.
Index: php-lib/php/tree_sql.inc
diff -u php-lib/php/tree_sql.inc:1.1 php-lib/php/tree_sql.inc:1.2
--- php-lib/php/tree_sql.inc:1.1 Wed Oct 4 03:39:01 2000
+++ php-lib/php/tree_sql.inc Mon Jan 29 00:07:53 2001
@@ -7,7 +7,7 @@
* a cookie-file to me - I'm collection cookies:
* [EMAIL PROTECTED] :-)
*
- * $Id: tree_sql.inc,v 1.1 2000/10/04 01:39:01 ssilk Exp $
+ * $Id: tree_sql.inc,v 1.2 2001/01/28 23:07:53 ssilk Exp $
*
*/
@@ -44,9 +44,9 @@
var $t_sort = ''; # Name of tree-sort-column
# never change this column value yourself: It will be overwritten!
- var $t_status= ''; # Name of type-of-knod-column
+ var $t_status= ''; # Name of type-of-node-column
# never change this column value yourself: It will be overwritten!
- # 'k' = knod; 'l' = leaf (a leaf has no descendants);
+ # 'n' = node; 'l' = leaf (a leaf has no descendants);
# root-elements can be detected by searching for elements with NULL-ancestors
# 'd' = deleted - cannot be selected, AND won't be DELETEd,
# can be set or unset with function tree_status();
@@ -73,7 +73,8 @@
function tree_root() {
$ret=Array();
$this->query("SELECT $this->t_pk from $this->treetab".
- " WHERE $this->t_ancestor IS NULL".
+ " WHERE ($this->t_ancestor IS NULL".
+ " OR $this->t_ancestor=0)". # is defined as root!
" AND $this->t_status<>'d'".
$this->tree_order());
while ($this->next_record()) {
@@ -96,14 +97,14 @@
$depth=0;
$this->t_sort_num=1; # begin sort (global)
while (list(,$pk)=each($root)) {
- $this->tree_revise_knod($pk,$depth,'');
+ $this->tree_revise_node($pk,$depth,'');
}
$this->tree_garbage_collection(); # deletes unlinked elements
}
# PRIVATE FUNCTION ($pk = "name"; -> won't work!)
- function tree_revise_knod ($pk,$depth,$path) {
+ function tree_revise_node ($pk,$depth,$path) {
$path.="$pk$this->delimit";
$this->query("SELECT $this->t_pk,$this->t_ancestor".
" FROM $this->treetab WHERE $this->t_ancestor=$pk".
@@ -119,12 +120,14 @@
$tree[$this->t_depth]= $depth;
$tree[$this->t_path] = $path;
$tree[$this->t_sort] = $this->t_sort_num++;
- # knod or leaf?
- $tree[$this->t_status]=((Count($ret))? 'k' : 'l');
+ # node or leaf?
+ $tree[$this->t_status]=((Count($ret))? 'n' : 'l');
$this->query($this->update_clause($this->treetab,$tree));
+ # go through all pks
+ reset($ret);
while (list(,$record)=each($ret)) {
- $this->tree_revise_knod(
+ $this->tree_revise_node(
$record[0],$depth+1,$path);
}
}
@@ -132,6 +135,13 @@
# this function will delete all unlinked elements
# (which don't have status deleted)
function tree_garbage_collection() {
+ # per definition ancestors of <= 0 are not allowed!
+ # phpmyadmin will not do this and prevents programming
+ # errors of other applications
+ # (make table acestors explicitly NULL)
+ $this->query("UPDATE $this->treetab SET".
+ " $this->t_ancestor = NULL".
+ " WHERE $this->t_ancestor<=0");
# This query will select all elements, which don't have
# a valid ancestor-link.
# Sorry, it will only work for more or less
@@ -142,11 +152,12 @@
# Sorry, this is not my fault, there is just no other way
# to do it efficiently, the alternative would
# be to select everything and check it for invalid ancestors
- $q="SELECT t2.$this->t_pk,t2.$this->t_ancestor FROM ".
+ $q="SELECT t1.$this->t_pk,t1.$this->t_ancestor FROM ".
$this->treetab . " AS t1".
" LEFT JOIN " . $this->treetab . " AS t2".
- " ON t2.$this->t_ancestor=t1.$this->t_ancestor ".
- " WHERE t1.$this->t_ancestor IS NULL";
+ " ON t1.$this->t_ancestor=t2.$this->t_pk ".
+ " WHERE t2.$this->t_pk IS NULL AND".
+ " t1.$this->t_ancestor IS NOT NULL";
# Hm, der Query stimmt wohl noch nicht!
$this->query($q);
$ret=Array();
@@ -155,9 +166,11 @@
$ret[]=$this->Record[0];
}
while (list(,$pk)=each($ret)) {
+# echo "DEBUG: Want to DELETE '$pk'";
$this->query($this->delete_Clause(
$this->treetab,Array($this->t_pk=>$pk)));
}
+ return($ret);
}
function tree_insert($fields,$special='',$params='') {
@@ -174,11 +187,15 @@
}
function tree_update ($fields,$special='',$params='') {
- if (empty($fields[$this->t_pk]) OR empty($fields[$this->t_name])) {
+ if (empty($fields[$this->t_pk]) AND
+ empty($fields[$this->t_name])) {
$this->halt("tree_update(): no primary key (t_pk) or name
(t_name) is given");
}
$this->query($this->update_Clause(
$this->treetab,$fields,$special,'',$params));
+ if ($this->affected_rows() != 1) {
+ $this->halt("tree_update(): more or less than one update");
+ }
if (empty($params['norevise']))
$this->tree_revise();
return(true);
@@ -232,21 +249,70 @@
}
+
+ # selects only those elements which are direct ancestors of
+ # the specified (fields must be one of "path", or "id")
+ function tree_branch ($fields,$special='',$params='') {
+ $where=Array();
+ $whereor=Array();
+ if (!empty($fields[$this->t_pk])) {
+ $this->query("SELECT $this->t_path".
+ " FROM $this->treetab".
+ $this->where_Clause($this->treetab,$fields,$special));
+ if ($this->next_record())
+ $fields[$this->t_path]=$this->Record[0];
+ unset($fields[$this->t_pk]);
+ }
+ if (!empty($fields[$this->t_path])) {
+ $p=split($this->delimit,
+
+ereg_Replace("$this->delimit\$","",$fields[$this->t_path]));
+ foreach ($p as $i => $v) {
+ if ($v)
+ # Knoten oder Blatt?
+ if ($i>=Count($p)-1)
+ $whereor[]="$this->t_pk = '$v'";
+ else
+ $whereor[]="$this->t_pk like '$v%'";
+ }
+ unset($fields[$this->t_path]);
+ }
+ ## ... many other possible actions
+
+ if (Count($whereor))
+ $where[]="(" . join(" OR ",$whereor) . ")";
+
+# $params['check']='weak';
+ $q="SELECT * FROM $this->treetab" .
+ $this->where_Clause($this->treetab,$fields,$special,
+ join(" AND ",$where),$params).
+ " ORDER BY $this->t_sort";
+ $this->query($q);
+
+ $this->tval=Array();
+ list($this->tree)=$this->tree_select_part();
+ }
+
+ ## create the tree from the selected set
function tree_select_part ($depth='') {
# the result is global in this class
$tree=Array();
- while ($this->next_record()) {
+ $nl=$this->next_record();
+ while ($nl) {
# remember only named values
$r=$this->capture_table_array($this->treetab,$this->Record);
$this->tval[$r[$this->t_pk]]=$r;
- if (empty($depth)) $depth=$r[$this->t_depth];
- # if it's a knod go deeper
- if ($r[$this->t_status] == 'k')
+ # take current depth as start-depth
+ if ($depth==='') $depth=$r[$this->t_depth];
+
+ # if it's a node go deeper
+ if ($r[$this->t_status] == 'n' and
+ $r[$this->t_depth] >= $depth)
{ # go deeper
list($tree[$r[$this->t_pk]],$r)=
$this->tree_select_part($depth+1);
+ continue;
}
- # if not in the same level
+ # if not in the same level go down
if ($r[$this->t_depth] < $depth)
{
return(Array($tree,$r));
@@ -257,6 +323,7 @@
# $tree[$r[$this->t_pk]]=$r[$this->t_name];
$tree[$r[$this->t_pk]]=true;
}
+ $nl=$this->next_record();
}
return(Array($tree,$r));
}
@@ -264,4 +331,4 @@
}
-?>
\ No newline at end of file
+?>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]