Вход Регистрация
Файл: boot/db_cache.class.php
Строк: 151
<?php

/**
* @name        JMY CMS
* @link        http://jmy.su/
* @copyright   Copyright (C) 2012-2014 JMY LTD
* @license     LICENSE.txt (see attached file)
* @version     VERSION.txt (see attached file)
* @author      Komarov Ivan
* @outside     Youshi
*/
 
if (!defined('ACCESS')) {
    
header('Location: /');
    exit;
}
define('NOW_TIME'time());
 
class 
dateBase extends controlDB 
{
    var 
$prefix '';    
    private 
$dir 'tmp/mysql';
    private 
$index_file 'index';
    private 
$index = array('drop' => array());
    private 
$cached = array();
    private 
$pointer = array();
    private 
$hashDrop = array();
    private 
$flush_by = array('INSERT''UPDATE''DELETE''REPLACE''ALTER');
    private 
$real_time_tables = array('online''comments''plugins''logs''reffers');
    private 
$real_time_func = array('NOW''UNIX_TIMESTAMP');
    private 
$no_cache_timeout 300;

    function 
__construct() 
    {
        require_once 
ROOT 'etc/db.config.php';
        
parent::connect($dbhost$dbuser$dbpass$dbname);        
        
define("DB_PREFIX"$prefix); 
        
define("USER_PREFIX"$user_prefix);
        
define("USER_DB"$user_db);        
        if (!
is_dir(ROOT.'tmp/mysql/')) {mkdir(ROOT.'tmp/mysql/'0777); @chmod_R(ROOT.'tmp/mysql/'0777);}        
        
$this->dir ROOT.'tmp/mysql/';        
        if (
file_exists($this->dir.$this->index_file)) include_once($this->dir.$this->index_file);
        unset(
$dbhost$dbuser$dbpass$prefix$user_prefix$user_db);
    }
    
    function 
__destruct()
    {
        if (
sizeof($this->index['drop']) > 0)
        {
            
$this->index['drop'] = array_unique($this->index['drop']);
            foreach (
$this->index['drop'] AS $hash)
            {
                unset(
$this->index['lifetime'][$hash]);
                @
unlink($this->dir.$hash);
            }
            
$this->index['drop'] = array();
        }
        
        
$index '<?php $this->index='.$this->arr2str($this->index).'; ?>';
        
$this->write_file($this->index_file$index);
    }
    

    function 
query($query
    {
        
$hash md5 (preg_replace('~([0-9]{10})~'''$query));
        
$is_realtime preg_match('~([0-9]{10})~'$query);
        
$is_cached false;
        
$do trim(strtoupper(mb_substr($query0strpos($query' '))));
        if (!isset(
$this->cached[$hash]))
        {
            if (
$do == 'SELECT' or $do == 'DO')
            {
                
preg_match_all('~' $this->prefix '_([^s`]+)~i'$query$match);
                
$tables =& $match[1]; unset ($match);
                
                if (
sizeof($tables) > && sizeof(array_intersect($tables$this->real_time_tables)) == 0)
                {
                    if (
in_array($hash$this->index['drop']) or !file_exists($this->dir.$hash))
                    {
                        foreach (
$tables AS $table)
                        {
                            
$this->index['links'][$table][$hash] = array_diff($tables, array($table));
                        }
                        
$this->index['times'][$hash] = NOW_TIME;
                    }
                    else
                    {
                        
$modified =& $this->index['times'][$hash];
                        if (
$is_realtime or preg_match('~('.implode('|'$this->real_time_func).')~i'$query))
                        {        
                            if (
$this->no_cache_timeout && (NOW_TIME $modified) < $this->no_cache_timeout$is_cached true;
                            else
                            {
                                
$this->index['times'][$hash] = NOW_TIME;
                            }
                        }
                        else 
$is_cached true;
                    }
                    if (
$is_cached$this->readcache($hash);
                    else
                    {
                        
$mysql parent::doQuery($queryfalse$this->prefix);                        
                        if (
$mysql)
                        {
                            while (
$row parent::getRow($mysql)) $this->cached[$hash]['data'][] = $row;
                            
$this->cached[$hash]['sizeof'] = parent::numRows($mysql);
                            if (!
$this->cached[$hash]['sizeof']) $this->cached[$hash]['sizeof'] = 0;
                            
$this->pointer[$hash] = 0;
                            
$this->iQuery_id $hash;
                            
$this->write_cache($hash);
                        }
                    }
                    return 
$hash;
                }
            }
            
        
            if (
in_array($do$this->flush_by))
            {                    
                if (
preg_match('~' $this->prefix '_([^s`]+)~i'$query$match))
                {        
                    
$table =& $match[1]; unset ($match);                
                    if (isset(
$this->index['links'][$table]))
                    {
                        foreach (
$this->index['links'][$table] AS $h => $link)
                        {
                            if(!isset(
$this->hashDrop[$h]))
                            {
                                foreach (
$link AS $tbl)
                                {
                                    unset(
$this->index['links'][$tbl][$h]);
                                }
                                
$this->index['drop'][] = $h;
                                
$this->hashDrop[$h] = true;
                            }
                        }
                    }
                }
            }
            return 
parent::doQuery($queryfalse$this->prefix);
        }
        return 
$hash;

    }

    function 
arr2str (&$arr$depth 0)
    {
            
$ret = array();
            if (
is_array($arr) && sizeof($arr) > 0)
            {
                    foreach (
$arr AS $key => $value)
                    {
                            
$key str_replace("'""'"$key);
                            if (
is_array($value)) $ret[] = "'{$key}'=>".$this->arr2str($value$depth+1);
                            elseif (
is_int($value)) $ret[] = "'{$key}'=>$value";
                            else
                            {
                                    if (
is_string($value)) $value str_replace("'"'"'$value);
                                    
$ret[] = "'{$key}'=>'".strval($value)."'";
                            }
                    }
            }
            return 
'array('.implode(','$ret).')';
    }

    function 
freeResult($resource
    {
        return 
parent::freeResult($resource);
    }
    
    function &
getRow($query_id)
    {
        
$ret false;
        if (isset(
$this->cached[$query_id]))
        {
            if (
$this->pointer[$query_id] < $this->cached[$query_id]['sizeof'])
            {
                
$ret $this->cached[$query_id]['data'][$this->pointer[$query_id]];
                
$this->pointer[$query_id]++;
            }
        }
        else 
$ret parent::getRow($query_id);
        
        return 
$ret;
    }
    
    function 
fetchRow($query_id
    {
        
$ret =& $this->fetch_assoc($query_id);
        return 
$ret array_values($ret) : $ret;
    }
    
    function &
fetch_assoc ($query_id = -1)
    {
        
$ret false;
        if (isset(
$this->cached[$query_id]))
        {
            if (
$this->pointer[$query_id] < $this->cached[$query_id]['sizeof'])
            {
                
$ret $this->cached[$query_id]['data'][$this->pointer[$query_id]];
                
$this->pointer[$query_id]++;
            }
        }
        elseif (
$query_id != -1$ret parent::getRow($query_id);
        return 
$ret;
    }
    
    function 
numRows($query_id)
    {
        if (isset(
$this->cached[$query_id])) return $this->cached[$query_id]['sizeof'];
        else return 
parent::numRows($query_id);
    }
    

    private function 
readcache ($hash)
    {
        include_once(
$this->dir.$hash);
        
$this->pointer[$hash] = 0;
        
$this->iQuery_id $hash;
    }
    
    private function 
write_cache ($hash)
    {
        
$data "<?php $this->cached['$hash']=".$this->arr2str($this->cached[$hash]).'; ?>';
        
$this->write_file($hash$data);
    }
    
    private function 
write_file($filename, &$content)
    {
        
ignore_user_abort(1);
        
$lockfile $this->dir.$filename '.lock';
        if (
file_exists($lockfile) && (time() - filemtime($lockfile)) > 5) @unlink($lockfile);
        
$lock_ex = @fopen($lockfile'x');
        for (
$i=0; ($lock_ex === false) && ($i 20); $i++)
        {
            
clearstatcache();
            
usleep(rand(515));
            
$lock_ex = @fopen($lockfile'x');
        }
        
        
$success false;
        if (
$lock_ex !== false)
        {
            
$fp = @fopen($this->dir.$filename'wb');
            if (@
fwrite($fp$content)) $success true;
            @
fclose($fp);
            
fclose($lock_ex);
            @
unlink($lockfile);
        }
        
ignore_user_abort(0);
        return 
$success;
    }
}
$db = new dateBase();
Онлайн: 0
Реклама