TeraWurflDatabase
[ class tree: TeraWurflDatabase ] [ index: TeraWurflDatabase ] [ all elements ]

Source for file TeraWurflMySQLNestedSet.php

Documentation is available at TeraWurflMySQLNestedSet.php

  1. <?php
  2. /**
  3.  * Tera_WURFL - PHP MySQL driven WURFL
  4.  *
  5.  * Tera-WURFL was written by Steve Kamerman, and is based on the
  6.  * Java WURFL Evolution package by Luca Passani and WURFL PHP Tools by Andrea Trassati.
  7.  * This version uses a MySQL database to store the entire WURFL file, multiple patch
  8.  * files, and a persistent caching mechanism to provide extreme performance increases.
  9.  *
  10.  * @package TeraWurflDatabase
  11.  * @author Steve Kamerman <stevekamerman AT gmail.com>
  12.  * @version Stable 2.1.3 $Date: 2010/09/18 15:43:21
  13.  * @license http://www.mozilla.org/MPL/ MPL Vesion 1.1
  14.  */
  15. /**
  16.  * Takes an existing table with data in ancestor..descendent hierarchial format
  17.  * and ALTERs the table by adding a right and left (`rt` and `lt`) columns.  These
  18.  * columns contain the nested set relationships between the nodes.  This makes certain
  19.  * lookups (like fallback trees) extremely simple and very fast.
  20.  * 
  21.  * This class is used by Tera-WURFL's MySQL5 Nested Set Database Connector
  22.  * 
  23.  * @package TeraWurflDatabase
  24.  */
  25.     
  26.     /**
  27.      * How deeply the recursion can go into the tree
  28.      * @var int 
  29.      */
  30.     protected $max_level = 100;
  31.     protected $dbcon;
  32.     protected $left;
  33.     protected $source_table;
  34.     protected $index_table;
  35.     protected $column_node_id;
  36.     protected $column_parent_id;
  37.     protected $column_left;
  38.     protected $column_right;    
  39.     protected $child_query;
  40.     protected $update_query;
  41.     
  42.     public $numQueries = 0;
  43.     
  44.     public function __construct(MySQLi &$dbcon,$source_table,$index_table,$column_node_id,$column_parent_id,$column_left='lt',$column_right='rt'){
  45.         $this->dbcon =$dbcon;
  46.         $this->source_table = $source_table;
  47.         $this->index_table = $index_table;
  48.         $this->column_node_id = $column_node_id;
  49.         $this->column_parent_id = $column_parent_id;
  50.         $this->column_left = $column_left;
  51.         $this->column_right = $column_right;
  52.     }
  53.     public function generateNestedSet($root_node_id='generic'){
  54.         $this->left = 1;
  55.         $this->child_query = sprintf("SELECT `%s` FROM %s WHERE `%s` = '?' ORDER BY `%s`",
  56.             $this->column_node_id,
  57.             $this->source_table,
  58.             $this->column_parent_id,
  59.             $this->column_node_id
  60.         );
  61.         $this->child_query = str_replace('?','%s',$this->child_query);
  62.         $this->update_query = sprintf("UPDATE %s SET `?` = '?' WHERE `%s` = '?'",
  63.             $this->index_table,
  64.             $this->column_node_id
  65.         );
  66.         $this->update_query = str_replace('?','%s',$this->update_query);
  67.         $this->dropColumns();
  68.         $this->addColumns();
  69.         $this->processChildren($root_node_id,1);
  70.         $this->addIndices();
  71.     }
  72.     public function queryGetAncestors($id,$order="ASC"){
  73.         $query sprintf("SELECT parent.%s FROM %s AS node, %s AS parent
  74. WHERE node.%s BETWEEN parent.%s AND parent.%s
  75. AND node.%s = '%s'
  76. ORDER BY parent.%s %s",
  77.             $this->column_node_id,
  78.             $this->index_table,
  79.             $this->index_table,
  80.             $this->column_left,
  81.             $this->column_left,
  82.             $this->column_right,
  83.             $this->column_node_id,
  84.             $id,
  85.             $this->column_right,
  86.             $order
  87.         );
  88.         $this->numQueries++;
  89.         $res $this->dbcon->query($query);
  90.         $data array();
  91.         if($res->num_rows == 0return data;
  92.         while($row $res->fetch_assoc()){
  93.             $data[]=$row[$this->column_node_id];
  94.         }
  95.         return $data;
  96.     }
  97.     public function dropColumns(){
  98.         try{
  99.             $query "ALTER TABLE %s DROP COLUMN `%s`, DROP COLUMN `%s`";
  100.             $this->numQueries++;
  101.             $this->dbcon->query(sprintf($query,$this->index_table,$this->column_left,$this->column_right));
  102.         }catch(Exception $e){return false;}
  103.         return true;
  104.     }
  105.     public function addColumns(){
  106.         try{
  107.             $query "ALTER TABLE %s ADD COLUMN `%s` int(11) NULL";
  108.             $this->numQueries+=2;
  109.             $this->dbcon->query(sprintf($query,$this->index_table,$this->column_left));
  110.             $this->dbcon->query(sprintf($query,$this->index_table,$this->column_right));
  111.         }catch(Exception $e){return false;}
  112.         return true;
  113.     }
  114.     public function addIndices(){
  115.         try{
  116.             $query "ALTER TABLE %s ADD UNIQUE (`%s`), ADD UNIQUE (`%s`)";
  117.             $this->numQueries++;
  118.             $this->dbcon->query(sprintf($query,$this->index_table,$this->column_left,$this->column_right));
  119.         }catch(Exception $e){return false;}
  120.         return true;
  121.     }
  122.     protected function processChildren($node_id,$level){
  123.         if($level >= $this->max_levelreturn;
  124.         // Update LEFT
  125.         $this->numQueries++;
  126.         if(!$this->dbcon->query(sprintf($this->update_query,$this->column_left,$this->left++,$node_id))){throw new Exception($this->dbcon->error);}
  127.         // Find children of this device
  128.         $this->numQueries++;
  129.         if(!$res $this->dbcon->query(sprintf($this->child_query,$node_id))){throw new Exception($this->dbcon->error);}
  130.         if($res->num_rows == 0){
  131.             // Dead end.  Update RIGHT
  132.             $this->numQueries++;
  133.             if(!$this->dbcon->query(sprintf($this->update_query,$this->column_right,$this->left++,$node_id))){throw new Exception($this->dbcon->error);}
  134.             return;
  135.         }
  136.         while($row $res->fetch_assoc()){
  137.             $this->processChildren($row[$this->column_node_id],$level+1);
  138.         }
  139.         // No more children.  Update RIGHT
  140.         $this->numQueries++;
  141.         if(!$this->dbcon->query(sprintf($this->update_query,$this->column_right,$this->left++,$node_id))){throw new Exception($this->dbcon->error);}
  142.     }
  143. }

Documentation generated on Sun, 19 Sep 2010 00:16:03 +0000 by phpDocumentor 1.4.3