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

Source for file mdb.php

Documentation is available at mdb.php

  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.5 2004/12/15 09:09:30 dufuz 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.5 2004/12/15 09:09:30 dufuz Exp $
  65. @package  Cache
  66. */
  67. {
  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($optionsarray_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(nullnullnull);
  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(nullnullnull);
  148.                         }
  149.                     else {
  150.                         $data = array(nullnullnull);
  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(nullnullnull);
  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.         }
  323.         return false;
  324.     }
  325.  
  326.     /**
  327.      * Garbage collector.
  328.      *
  329.      * @param    int maxlifetime
  330.      */
  331.     function garbageCollection($maxlifetime)
  332.     {
  333.         $this->flushPreload();
  334.         $query 'DELETE FROM '        $this->cache_table
  335.                 .' WHERE (expires <= ' time()
  336.                 .' AND expires > 0) OR changed <= 'time($maxlifetime;
  337.  
  338.         $res $this->db->query($query);
  339.  
  340.         $query 'SELECT sum(length(cachedata)) as CacheSize FROM '
  341.                 . $this->cache_table;
  342.  
  343.         $cachesize $this->db->getOne($query);
  344.         if (MDB::isError($cachesize)) {
  345.             return new Cache_Error('MDB::query failed: '
  346.                    . $this->db->errorMessage($cachesize)__FILE____LINE__);
  347.         }
  348.         //if cache is to big.
  349.         if ($cachesize $this->highwater{
  350.             //find the lowwater mark.
  351.             $query 'SELECT length(cachedata) as size, changed FROM '
  352.                     . $this->cache_table .' ORDER BY changed DESC';
  353.  
  354.             $res $this->db->query($query);
  355.             if (MDB::isError($res)) {
  356.                return new Cache_Error('MDB::query failed: '
  357.                     . $this->db->errorMessage($res)__FILE____LINE__);
  358.             }
  359.             $numrows $this->db->numRows($res);
  360.             $keep_size = 0;
  361.             while ($keep_size $this->lowwater && $numrows--{
  362.                 $entry $this->db->fetchInto($res,MDB_FETCHMODE_ASSOC);
  363.                 $keep_size += $entry['size'];
  364.             }
  365.  
  366.             //delete all entries, which were changed before the "lowwater mark"
  367.             $query 'DELETE FROM ' $this->cache_table
  368.                     .' WHERE changed<='.($entry['changed'$entry['changed': 0);
  369.  
  370.             $res $this->db->query($query);
  371.             if (MDB::isError($res)) {
  372.                return new Cache_Error('MDB::query failed: '
  373.                     . $this->db->errorMessage($res)__FILE____LINE__);
  374.             }
  375.         }
  376.     }
  377.  
  378. }
  379. ?>

Documentation generated on Mon, 11 Mar 2019 15:25:50 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.