| [ Index ] |
|
Code source de PHP PEAR 1.4.5 |
1 <?php 2 // +----------------------------------------------------------------------+ 3 // | PEAR :: Cache :: MDB Container | 4 // +----------------------------------------------------------------------+ 5 // | Copyright (c) 1997-2003 The PHP Group | 6 // +----------------------------------------------------------------------+ 7 // | This source file is subject to version 2.0 of the PHP license, | 8 // | that is bundled with this package in the file LICENSE, and is | 9 // | available at through the world-wide-web at | 10 // | http://www.php.net/license/2_02.txt. | 11 // | If you did not receive a copy of the PHP license and are unable to | 12 // | obtain it through the world-wide-web, please send a note to | 13 // | license@php.net so we can mail you a copy immediately. | 14 // +----------------------------------------------------------------------+ 15 // | Note: This is a MDB-oriented rewrite of Cache/Container/db.php. | 16 // | Thanks to Lukas Smith for his patience in answering my questions | 17 // +----------------------------------------------------------------------+ 18 // | Author: Lorenzo Alberton <l.alberton at quipo.it> | 19 // +----------------------------------------------------------------------+ 20 // 21 // $Id: mdb.php,v 1.3 2003/01/04 11:54:46 mj Exp $ 22 23 require_once 'MDB.php'; 24 require_once 'Cache/Container.php'; 25 26 /** 27 * PEAR/MDB Cache Container. 28 * 29 * NB: The field 'changed' has no meaning for the Cache itself. It's just there 30 * because it's a good idea to have an automatically updated timestamp 31 * field for debugging in all of your tables. 32 * 33 * A XML MDB-compliant schema example for the table needed is provided. 34 * Look at the file "mdb_cache_schema.xml" for that. 35 * 36 * ------------------------------------------ 37 * A basic usage example: 38 * ------------------------------------------ 39 * 40 * $dbinfo = array( 41 * 'database' => 'dbname', 42 * 'phptype' => 'mysql', 43 * 'username' => 'root', 44 * 'password' => '', 45 * 'cache_table' => 'cache' 46 * ); 47 * 48 * 49 * $cache = new Cache('mdb', $dbinfo); 50 * $id = $cache->generateID('testentry'); 51 * 52 * if ($data = $cache->get($id)) { 53 * echo 'Cache hit.<br />Data: '.$data; 54 * 55 * } else { 56 * $data = 'data of any kind'; 57 * $cache->save($id, $data); 58 * echo 'Cache miss.<br />'; 59 * } 60 * 61 * ------------------------------------------ 62 * 63 * @author Lorenzo Alberton <l.alberton at quipo.it> 64 * @version $Id: mdb.php,v 1.3 2003/01/04 11:54:46 mj Exp $ 65 * @package Cache 66 */ 67 class Cache_Container_mdb extends Cache_Container { 68 69 /** 70 * Name of the MDB table to store caching data 71 * 72 * @see Cache_Container_file::$filename_prefix 73 */ 74 var $cache_table = ''; 75 76 /** 77 * PEAR MDB object 78 * 79 * @var object PEAR_MDB 80 */ 81 var $db; 82 83 /** 84 * Constructor 85 * 86 * @param mixed Array with connection info or dsn string 87 */ 88 function Cache_Container_mdb($options) 89 { 90 $this->db = &MDB::Connect($options); 91 if(MDB::isError($this->db)) { 92 return new Cache_Error('MDB::connect failed: ' 93 . $this->db->getMessage(), __FILE__, __LINE__); 94 } else { 95 $this->db->setFetchMode(MDB_FETCHMODE_ASSOC); 96 } 97 $this->setOptions($options, array_merge($this->allowed_options, 98 array('dsn', 'cache_table'))); 99 } 100 101 /** 102 * Fetch in the db the data that matches input parameters 103 * 104 * @param string dataset ID 105 * @param string cache group 106 * @return mixed dataset value or NULL/Cache_Error on failure 107 * @access public 108 */ 109 function fetch($id, $group) 110 { 111 $query = 'SELECT cachedata FROM ' . $this->cache_table 112 .' WHERE id=' . $this->db->getTextValue($id) 113 .' AND cachegroup=' . $this->db->getTextValue($group); 114 if($res = $this->db->query($query)) { 115 if($this->db->endOfResult($res)) { 116 //no rows returned 117 $data = array(NULL, NULL, NULL); 118 } else { 119 $clob = $this->db->fetchClob($res,0,'cachedata'); 120 if(!MDB::isError($clob)) { 121 $cached_data = ''; 122 while(!$this->db->endOfLOB($clob)) { 123 if(MDB::isError($error = 124 $this->db->readLob($clob,$data,8000)<0)) { 125 return new Cache_Error('MDB::query failed: ' 126 . $error->getMessage(), __FILE__, __LINE__); 127 } 128 $cached_data .= $data; 129 } 130 unset($data); 131 $this->db->destroyLob($clob); 132 $this->db->freeResult($res); 133 134 //finished fetching LOB, now fetch other fields... 135 $query = 'SELECT userdata, expires FROM ' . $this->cache_table 136 .' WHERE id=' . $this->db->getTextValue($id) 137 .' AND cachegroup=' . $this->db->getTextValue($group); 138 if($res = $this->db->query($query)) { 139 $row = $this->db->fetchInto($res); 140 if (is_array($row)) { 141 $data = array( 142 $row['expires'], 143 $this->decode($cached_data), 144 $row['userdata'] 145 ); 146 } else { 147 $data = array(NULL, NULL, NULL); 148 } 149 } else { 150 $data = array(NULL, NULL, NULL); 151 } 152 } else { 153 return new Cache_Error('MDB::query failed: ' 154 . $clob->getMessage(), __FILE__, __LINE__); 155 } 156 } 157 $this->db->freeResult($res); 158 } else { 159 //return new Cache_Error('MDB::query failed: ' 160 // . $result->getMessage(), __FILE__, __LINE__); 161 $data = array(NULL, NULL, NULL); 162 } 163 164 // last used required by the garbage collection 165 $query = 'UPDATE ' . $this->cache_table 166 .' SET changed=' . time() 167 .' WHERE id=' . $this->db->getTextValue($id) 168 .' AND cachegroup=' . $this->db->getTextValue($group); 169 170 $res = $this->db->query($query); 171 if (MDB::isError($res)) { 172 return new Cache_Error('MDB::query failed: ' 173 . $this->db->errorMessage($res), __FILE__, __LINE__); 174 } 175 return $data; 176 } 177 178 /** 179 * Stores a dataset in the database 180 * 181 * If dataset_ID already exists, overwrite it with new data, 182 * else insert data in a new record. 183 * 184 * @param string dataset ID 185 * @param mixed data to be cached 186 * @param integer expiration time 187 * @param string cache group 188 * @param string userdata 189 * @access public 190 */ 191 function save($id, $data, $expires, $group, $userdata) 192 { 193 global $db; 194 $this->flushPreload($id, $group); 195 196 $fields = array( 197 'id' => array( 198 'Type' => 'text', 199 'Value' => $id, 200 'Key' => true 201 ), 202 'userdata' => array( 203 'Type' => 'integer', 204 'Value' => $userdata, 205 'Null' => ($userdata ? false : true) 206 ), 207 'expires' => array( 208 'Type' => 'integer', 209 'Value' => $this->getExpiresAbsolute($expires) 210 ), 211 'cachegroup' => array( 212 'Type' => 'text', 213 'Value' => $group 214 ) 215 ); 216 217 $result = $this->db->replace($this->cache_table, $fields); 218 219 if(MDB::isError($result)) { 220 //Var_Dump::display($result); 221 return new Cache_Error('MDB::query failed: ' 222 . $this->db->errorMessage($result), __FILE__, __LINE__); 223 } 224 unset($fields); //end first part of query 225 $query2 = 'UPDATE ' . $this->cache_table 226 .' SET cachedata=?' 227 .' WHERE id='. $this->db->getTextValue($id); 228 229 if(($prepared_query = $this->db->prepareQuery($query2))) { 230 $char_lob = array( 231 'Error' => '', 232 'Type' => 'data', 233 'Data' => $this->encode($data) 234 ); 235 if(!MDB::isError($clob = $this->db->createLob($char_lob))) { 236 $this->db->setParamClob($prepared_query,1,$clob,'cachedata'); 237 if(MDB::isError($error=$this->db->executeQuery($prepared_query))) { 238 return new Cache_Error('MDB::query failed: ' 239 . $error->getMessage() , __FILE__, __LINE__); 240 } 241 $this->db->destroyLob($clob); 242 } else { 243 // creation of the handler object failed 244 return new Cache_Error('MDB::query failed: ' 245 . $clob->getMessage() , __FILE__, __LINE__); 246 } 247 $this->db->freePreparedQuery($prepared_query); 248 } else { 249 //prepared query failed 250 return new Cache_Error('MDB::query failed: ' 251 . $prepared_query->getMessage() , __FILE__, __LINE__); 252 } 253 } 254 255 /** 256 * Removes a dataset from the database 257 * 258 * @param string dataset ID 259 * @param string cache group 260 */ 261 function remove($id, $group) 262 { 263 $this->flushPreload($id, $group); 264 265 $query = 'DELETE FROM ' . $this->cache_table 266 .' WHERE id=' . $this->db->getTextValue($id) 267 .' AND cachegroup=' . $this->db->getTextValue($group); 268 269 $res = $this->db->query($query); 270 if (MDB::isError($res)) { 271 return new Cache_Error('MDB::query failed: ' 272 . $this->db->errorMessage($res), __FILE__, __LINE__); 273 } 274 } 275 276 /** 277 * Remove all cached data for a certain group, or empty 278 * the cache table if no group is specified. 279 * 280 * @param string cache group 281 */ 282 function flush($group = '') 283 { 284 $this->flushPreload(); 285 286 if ($group) { 287 $query = 'DELETE FROM ' . $this->cache_table 288 .' WHERE cachegroup=' . $this->db->getTextValue($group); 289 } else { 290 $query = 'DELETE FROM ' . $this->cache_table; 291 } 292 293 $res = $this->db->query($query); 294 if (MDB::isError($res)) { 295 return new Cache_Error('MDB::query failed: ' 296 . $this->db->errorMessage($res), __FILE__, __LINE__); 297 } 298 } 299 300 /** 301 * Check if a dataset ID/group exists. 302 * 303 * @param string dataset ID 304 * @param string cache group 305 * @return boolean 306 */ 307 function idExists($id, $group) 308 { 309 $query = 'SELECT id FROM ' . $this->cache_table 310 .' WHERE id=' . $this->db->getTextValue($id) 311 .' AND cachegroup=' . $this->db->getTextValue($group); 312 echo $query; 313 $res = $this->db->query($query); 314 if (MDB::isError($res)) { 315 return new Cache_Error('MDB::query failed: ' 316 . $this->db->errorMessage($res), __FILE__, __LINE__); 317 } 318 $row = $this->db->fetchInto($res); 319 320 if (is_array($row)) { 321 return true; 322 } else { 323 return false; 324 } 325 } 326 327 /** 328 * Garbage collector. 329 * 330 * @param int maxlifetime 331 */ 332 function garbageCollection($maxlifetime) 333 { 334 $this->flushPreload(); 335 $query = 'DELETE FROM ' . $this->cache_table 336 .' WHERE (expires <= ' . time() 337 .' AND expires > 0) OR changed <= '. time() - $maxlifetime; 338 339 $res = $this->db->query($query); 340 341 $query = 'SELECT sum(length(cachedata)) as CacheSize FROM ' 342 . $this->cache_table; 343 344 $cachesize = $this->db->getOne($query); 345 if (MDB::isError($cachesize)) { 346 return new Cache_Error('MDB::query failed: ' 347 . $this->db->errorMessage($cachesize), __FILE__, __LINE__); 348 } 349 //if cache is to big. 350 if ($cachesize > $this->highwater) 351 { 352 //find the lowwater mark. 353 $query = 'SELECT length(cachedata) as size, changed FROM ' 354 . $this->cache_table .' ORDER BY changed DESC'; 355 356 $res = $this->db->query($query); 357 if (MDB::isError($res)) { 358 return new Cache_Error('MDB::query failed: ' 359 . $this->db->errorMessage($res), __FILE__, __LINE__); 360 } 361 $numrows = $this->db->numRows($res); 362 $keep_size = 0; 363 while ($keep_size < $this->lowwater && $numrows--) { 364 $entry = $this->db->fetchInto($res,MDB_FETCHMODE_ASSOC); 365 $keep_size += $entry['size']; 366 } 367 368 //delete all entries, which were changed before the "lowwater mark" 369 $query = 'DELETE FROM ' . $this->cache_table 370 .' WHERE changed<='.($entry['changed'] ? $entry['changed'] : 0); 371 372 $res = $this->db->query($query); 373 if (MDB::isError($res)) { 374 return new Cache_Error('MDB::query failed: ' 375 . $this->db->errorMessage($res), __FILE__, __LINE__); 376 } 377 } 378 } 379 380 } 381 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 14:08:00 2007 | par Balluche grâce à PHPXref 0.7 |