Changeset 184

Show
Ignore:
Timestamp:
02/01/07 18:07:42 (13 years ago)
Author:
exi
Message:

Fix for ticket:39 in class.db_cache.php.
Several additions to the parser and cache loader to support more sql statements.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • dev/common/class.db_cache.php

    r183 r184  
    3333        // eligible for caching in seconds 
    3434        $this->_minruntime = 0.1; 
     35 
     36        // maximum size of a cached result set (512kB) 
     37        $this->_maxcachesize = 524288; 
    3538    } 
    3639 
     
    6265        // gets all involved tables for a select statement 
    6366        $text = strtolower($this->_sql).' '; 
     67 
     68        // we try to get the text from 'from' to 'where' because all involved 
     69        // tables are declared in that part 
    6470        $from = strpos($text, 'from')+5; 
    6571        if (!$to = strpos($text, 'where')) 
     
    7076 
    7177        $tables = array(); 
     78        if (strpos($parse, ',') !== false) 
     79        { 
     80            // , is a synonym for join so we'll replace them 
     81            $parse = str_replace(',', ' join ', $parse); 
     82        } 
    7283        if (strpos($parse, 'join')) 
    7384        { 
     85            // if this query is a join we parse it with regexp to get all tables 
    7486            preg_match_all('/join (.*?) /', $parse, $match); 
    7587            $tables = $match[1]; 
     
    7789        else 
    7890        { 
     91            // no join so it is hopefully a simple table select 
    7992            $tables[] = $parse; 
    8093        } 
     
    8598    function isCacheValid() 
    8699    { 
    87         // check if one of the tables needs to be updated 
     100        // check if cachefiles are stil valid 
    88101 
    89102        // first, we need to get all involved tables 
     
    109122        // this function invalidates cache files for touched tables 
    110123        $text = trim(strtolower($this->_sql)); 
    111         $ta = explode(' ', $text); 
    112  
     124        $text = str_replace(array('ignore','`'), '', $text); 
     125        $ta = preg_split('/ /', $text, 0, PREG_SPLIT_NO_EMPTY); 
     126 
     127        // check for sql keywords and get the table from the appropriate position 
    113128        $tables = array(); 
    114129        if ($ta[0] == 'update') 
     
    140155            touch($file); 
    141156        } 
     157        // refresh php's filestatcache so we dont get wrong timestamps on changed files 
     158        clearstatcache(); 
    142159    } 
    143160 
     
    146163        // this function fetches all rows and writes the data into a textfile 
    147164 
     165        // don't attemp to cache updates! 
     166        if (strtolower(substr($this->_sql, 0, 6)) != 'select' && strtolower(substr($this->_sql, 0, 4)) != 'show') 
     167        { 
     168            return false; 
     169        } 
     170 
     171        $bsize = 0; 
    148172        while ($row = $this->getRow()) 
    149173        { 
    150174            $this->_cache[] = $row; 
     175 
     176            // if the bytesize of the table exceeds the limit we'll abort 
     177            // the cache generation and leave this query unbuffered 
     178            $bsize += join('', $row); 
     179            if ($bsize > $this->_maxcachesize) 
     180            { 
     181                $this->_cache[] = array(); 
     182                $this->_cached = false; 
     183                $this->rewind(); 
     184                return false; 
     185            } 
    151186        } 
    152187 
    153188        // write data into textfile 
    154189        file_put_contents(KB_CACHEDIR.'/qcache_qry_'.$this->_hash, serialize($this->_cache)); 
    155  
    156         $this->_cached = true; 
    157         $this->_currrow = 0; 
    158     } 
    159  
    160     function loadCache() 
    161     { 
    162         // loads the cachefile into the memory 
    163         $this->_cache = unserialize(file_get_contents(KB_CACHEDIR.'/qcache_qry_'.$this->_hash)); 
    164190 
    165191        $this->_cached = true; 
     
    168194    } 
    169195 
     196    function loadCache() 
     197    { 
     198        // loads the cachefile into the memory 
     199        $this->_cache = unserialize(file_get_contents(KB_CACHEDIR.'/qcache_qry_'.$this->_hash)); 
     200 
     201        $this->_cached = true; 
     202        $this->_currrow = 0; 
     203        $this->executed_ = true; 
     204    } 
     205 
    170206    function execute($sql) 
    171207    { 
    172         $this->_sql = $sql; 
    173         $this->_hash = md5($sql); 
     208        $this->_sql = trim($sql); 
     209        $this->_hash = md5($this->_sql); 
    174210 
    175211        if ($this->checkCache()) 
     
    178214            return true; 
    179215        } 
     216 
     217        // we got no or no valid cache so open the connection and run the query 
    180218        $this->dbconn_ = new DBConnection; 
    181219 
     
    186224        if ($this->resid_ == false) 
    187225        { 
    188             if (defined('DB_HALTONERROR') && DB_HALTONERROR) 
    189             { 
    190                 echo "Database error: " . mysql_error($this->dbconn_->id()) . "<br>"; 
    191                 echo "SQL: " . $sql . "<br>"; 
     226            if (DB_HALTONERROR === true) 
     227            { 
     228                echo "Database error: ".mysql_error($this->dbconn_->id())."<br/>"; 
     229                echo "SQL: ".$this->_sql."<br/>"; 
    192230                exit; 
    193231            } 
     
    203241        if (KB_PROFILE == 2) 
    204242        { 
    205             file_put_contents('/tmp/profile.lst', $sql . "\nExecution time: " . $this->exectime_ . "\n", FILE_APPEND); 
    206         } 
    207  
     243            file_put_contents('/tmp/profile.lst', $sql."\nExecution time: ".$this->exectime_."\n", FILE_APPEND); 
     244        } 
     245 
     246        // if the query was too slow we'll fetch all rows and run it cached 
    208247        if ($this->exectime_ > $this->_minruntime) 
    209248        { 
     
    227266        if ($this->_cached) 
    228267        { 
     268            if (!isset($this->_cache[$this->_currrow])) 
     269            { 
     270                return false; 
     271            } 
    229272            // return the current row and increase the pointer by one 
    230273            return $this->_cache[$this->_currrow++]; 
    231274        } 
    232         if ($this->resid_) 
     275        if (is_resource($this->resid_)) 
    233276        { 
    234277            return mysql_fetch_assoc($this->resid_); 
     
    263306    function getErrorMsg() 
    264307    { 
    265         $msg = $this->sql_ . "<br>"; 
    266         $msg .= "Query failed. " . mysql_error($this->dbconn_->id()); 
     308        $msg = $this->sql_."<br>"; 
     309        $msg .= "Query failed. ".mysql_error($this->dbconn_->id()); 
    267310 
    268311        return $msg;