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]

Reply via email to