root/dev/common/includes/class.db_memcache.php @ 343

Revision 343, 5.9 KB (checked in by beans, 14 years ago)

A lot of updates done by Karbowiak (LaMaH).
See them here:  http://eve-id.net/forum/viewtopic.php?f=503&t=13204&p=15284#p15284

Highlights:
* Integrated feed fetcher & API Mod into the core
* memcached support in core

Line 
1<?php
2
3class DBMemcachedQuery
4{
5    function DBMemcachedQuery()
6    {
7        $this->executed_ = false;
8        $this->_cache = array();
9        $this->_cached = false;
10
11        // this is the minimum runtime a query has to run to be
12        // eligible for caching in seconds
13        $this->_minruntime = 0.1;
14
15        // maximum size of a cached result set (1MB)
16        $this->_maxcachesize = 1048576;
17        $this->d = true;
18    }
19
20    function checkCache()
21    {
22        global $mc;
23
24        // only cache selects
25        // we don't use select ... into so there is no problem
26        $this->_sql = str_replace(array("\r\n", "\n"), ' ', $this->_sql);
27        if (strtolower(substr($this->_sql, 0, 6)) != 'select' && strtolower(substr($this->_sql, 0, 4)) != 'show')
28            return false;
29
30        $cached = $mc->get(KB_SITE . '_sql_' . $this->_hash);
31        if($cached) {
32            return true;
33        }
34
35        return false;
36    }
37
38    function parseSQL()
39    {
40        // gets all involved tables for a select statement
41        $text = strtolower($this->_sql).' ';
42
43        // we try to get the text from 'from' to 'where' because all involved
44        // tables are declared in that part
45        $from = strpos($text, 'from')+5;
46        if (!$to = strpos($text, 'where'))
47        {
48            $to = strlen($text);
49        }
50        $parse = trim(substr($text, $from, $to-$from));
51
52        $tables = array();
53        if (strpos($parse, ',') !== false)
54        {
55            // , is a synonym for join so we'll replace them
56            $parse = str_replace(',', ' join ', $parse);
57        }
58
59        $parse = 'join '.$parse;
60        if (strpos($parse, 'join'))
61        {
62            // if this query is a join we parse it with regexp to get all tables
63            preg_match_all('/join (.*?) /', $parse, $match);
64            $tables = $match[1];
65        }
66        else
67        {
68            // no join so it is hopefully a simple table select
69            $tables[] = $parse;
70        }
71
72        $this->_usedtables = $tables;
73    }
74
75    function genCache()
76    {
77        global $mc;
78
79        // this function fetches all rows and writes the data into a textfile
80
81        // don't attemp to cache updates!
82        if (strtolower(substr($this->_sql, 0, 6)) != 'select' && strtolower(substr($this->_sql, 0, 4)) != 'show')
83        {
84            return false;
85        }
86
87        $bsize = 0;
88        while ($row = $this->getRow())
89        {
90            $this->_cache[] = $row;
91
92            $bsize += strlen(join('', $row));
93            if ($bsize > $this->_maxcachesize)
94            {
95                $this->_cache[] = array();
96                $this->_cached = false;
97                $this->rewind();
98                return false;
99            }
100
101        }
102
103        // write data into textfile
104        $mc->set(KB_SITE . '_sql_' . $this->_hash, $this->_cache, 0, 600);
105
106        $this->_cached = true;
107        $this->_currrow = 0;
108        $this->executed_ = true;
109    }
110
111    function execute($sql)
112    {
113        global $mc; 
114
115        $this->_sql = trim($sql);
116        $this->_hash = md5($this->_sql);
117        $this->_cache = array();
118        $this->_cached = false;
119
120        $cached = $mc->get(KB_SITE . '_sql_' . $this->_hash);
121        if($cached) {
122            $this->_cache = $cached;
123            $this->_cached = true;
124            $this->_currrow = 0;
125            $this->executed_ = true;
126            $this->queryCachedCount(true);
127            return true;
128        }
129
130        // we got no or no valid cache so open the connection and run the query
131        $this->dbconn_ = new DBConnection;
132
133        $t1 = strtok(microtime(), ' ') + strtok('');
134
135        $this->resid_ = mysql_query($sql, $this->dbconn_->id());
136
137        if ($this->resid_ == false)
138        {
139            if (DB_HALTONERROR === true)
140            {
141                echo "Database error: ".mysql_error($this->dbconn_->id())."<br/>";
142                echo "SQL: ".$this->_sql."<br/>";
143                exit;
144            }
145            else
146            {
147                return false;
148            }
149        }
150
151        $this->exectime_ = strtok(microtime(), ' ') + strtok('') - $t1;
152        $this->executed_ = true;
153
154        if (KB_PROFILE == 2)
155        {
156            file_put_contents('/tmp/profile.lst', $sql."\nExecution time: ".$this->exectime_."\n", FILE_APPEND);
157        }
158
159        // if the query was too slow we'll fetch all rows and run it cached
160        $this->genCache();
161
162        $this->queryCount(true);
163        return true;
164    }
165
166    function queryCount($increase = false)
167    {
168        static $count;
169
170        if ($increase)
171        {
172            $count++;
173        }
174
175        return $count;
176    }
177
178    function queryCachedCount($increase = false)
179    {
180        static $count;
181
182        if ($increase)
183        {
184            $count++;
185        }
186
187        return $count;
188    }
189
190    function recordCount()
191    {
192        if ($this->_cached)
193        {
194            return count($this->_cache);
195        }
196        return mysql_num_rows($this->resid_);
197    }
198
199    function getRow()
200    {
201        if ($this->_cached)
202        {
203            if (!isset($this->_cache[$this->_currrow]))
204            {
205                return false;
206            }
207            // return the current row and increase the pointer by one
208            return $this->_cache[$this->_currrow++];
209        }
210        if (is_resource($this->resid_))
211        {
212            return mysql_fetch_assoc($this->resid_);
213        }
214        return false;
215    }
216
217    function rewind()
218    {
219        if ($this->_cached)
220        {
221            $this->_currrow = 0;
222        }
223        @mysql_data_seek($this->resid_, 0);
224    }
225
226    function getInsertID()
227    {
228        return mysql_insert_id();
229    }
230
231    function execTime()
232    {
233        return $this->exectime_;
234    }
235
236    function executed()
237    {
238        return $this->executed_;
239    }
240
241    function getErrorMsg()
242    {
243        $msg = $this->sql_."<br>";
244        $msg .= "Query failed. ".mysql_error($this->dbconn_->id());
245
246        return $msg;
247    }
248}
249?>
Note: See TracBrowser for help on using the browser.