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 315100 2011-08-17 19:32:23Z cweiske $
  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 315100 2011-08-17 19:32:23Z cweiske $
  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->setAllowedOptions(array('dsn''cache_table'));
  91.         $this->setOptions($options);
  92.         $this->db = &MDB::Connect($options);
  93.         if (MDB::isError($this->db)) {
  94.             return new Cache_Error(
  95.                 'MDB::connect failed: '
  96.                 . $this->db->getMessage()__FILE____LINE__
  97.             );
  98.         else {
  99.             $this->db->setFetchMode(MDB_FETCHMODE_ASSOC);
  100.         }
  101.     }
  102.  
  103.     /**
  104.      * Fetch in the db the data that matches input parameters
  105.      *
  106.      * @param    string  dataset ID
  107.      * @param    string  cache group
  108.      * @return   mixed   dataset value or null/Cache_Error on failure
  109.      * @access   public
  110.      */
  111.     function fetch($id$group)
  112.     {
  113.         $query 'SELECT cachedata FROM ' $this->cache_table
  114.                 .' WHERE id='       $this->db->getTextValue($id)
  115.                 .' AND cachegroup=' $this->db->getTextValue($group);
  116.         if ($res $this->db->query($query)) {
  117.             if ($this->db->endOfResult($res)) {
  118.                 //no rows returned
  119.                 $data = array(nullnullnull);
  120.             else {
  121.                 $clob $this->db->fetchClob($res,0,'cachedata');
  122.                 if (!MDB::isError($clob)) {
  123.                     $cached_data '';
  124.                     while(!$this->db->endOfLOB($clob)) {
  125.                         if (MDB::isError($error =
  126.                                     $this->db->readLob($clob,$data,8000)<0)) {
  127.                             return new Cache_Error('MDB::query failed: '
  128.                                     . $error->getMessage()__FILE____LINE__);
  129.                         }
  130.                         $cached_data .= $data;
  131.                     }
  132.                     unset($data);
  133.                     $this->db->destroyLob($clob);
  134.                     $this->db->freeResult($res);
  135.  
  136.                     //finished fetching LOB, now fetch other fields...
  137.                     $query 'SELECT userdata, expires FROM ' $this->cache_table
  138.                             .' WHERE id='       $this->db->getTextValue($id)
  139.                             .' AND cachegroup=' $this->db->getTextValue($group);
  140.                     if ($res $this->db->query($query)) {
  141.                         $row $this->db->fetchInto($res);
  142.                         if (is_array($row)) {
  143.                             $data = array(
  144.                                         $row['expires'],
  145.                                         $this->decode($cached_data),
  146.                                         $row['userdata']
  147.                                     );
  148.                         else {
  149.                             $data = array(nullnullnull);
  150.                         }
  151.                     else {
  152.                         $data = array(nullnullnull);
  153.                     }
  154.                 else {
  155.                     return new Cache_Error('MDB::query failed: '
  156.                              . $clob->getMessage()__FILE____LINE__);
  157.                 }
  158.             }
  159.             $this->db->freeResult($res);
  160.         else {
  161.             //return new Cache_Error('MDB::query failed: '
  162.             //          . $result->getMessage(), __FILE__, __LINE__);
  163.             $data = array(nullnullnull);
  164.         }
  165.  
  166.         // last used required by the garbage collection
  167.         $query 'UPDATE '          $this->cache_table
  168.                 .' SET changed='    time()
  169.                 .' WHERE id='       $this->db->getTextValue($id)
  170.                 .' AND cachegroup=' $this->db->getTextValue($group);
  171.  
  172.         $res $this->db->query($query);
  173.         if (MDB::isError($res)) {
  174.             return new Cache_Error('MDB::query failed: '
  175.                 . $this->db->errorMessage($res)__FILE____LINE__);
  176.         }
  177.         return $data;
  178.     }
  179.  
  180.    /**
  181.      * Stores a dataset in the database
  182.      *
  183.      * If dataset_ID already exists, overwrite it with new data,
  184.      * else insert data in a new record.
  185.      *
  186.      * @param    string  dataset ID
  187.      * @param    mixed   data to be cached
  188.      * @param    integer expiration time
  189.      * @param    string  cache group
  190.      * @param    string  userdata
  191.      * @access   public
  192.      */
  193.     function save($id$data$expires$group$userdata)
  194.     {
  195.         global $db;
  196.         $this->flushPreload($id$group);
  197.  
  198.         $fields = array(
  199.             'id'        => array(
  200.                             'Type'   => 'text',
  201.                             'Value'  => $id,
  202.                             'Key'    => true
  203.                         ),
  204.             'userdata'  => array(
  205.                             'Type'   => 'integer',
  206.                             'Value'  => $userdata,
  207.                             'null'   => ($userdata ? false : true)
  208.                         ),
  209.             'expires'   => array(
  210.                             'Type'   => 'integer',
  211.                             'Value'  => $this->getExpiresAbsolute($expires)
  212.                         ),
  213.             'cachegroup' => array(
  214.                             'Type'   => 'text',
  215.                             'Value'  => $group
  216.                         )
  217.             );
  218.  
  219.         $result $this->db->replace($this->cache_table$fields);
  220.  
  221.         if (MDB::isError($result)) {
  222.             //Var_Dump::display($result);
  223.             return new Cache_Error('MDB::query failed: '
  224.                     . $this->db->errorMessage($result)__FILE____LINE__);
  225.         }
  226.         unset($fields)//end first part of query
  227.         $query2 'UPDATE '   $this->cache_table
  228.                  .' SET cachedata=?'
  229.                  .' WHERE id='$this->db->getTextValue($id);
  230.  
  231.         if (($prepared_query $this->db->prepareQuery($query2))) {
  232.             $char_lob = array(
  233.                             'Error' => '',
  234.                             'Type' => 'data',
  235.                             'Data' => $this->encode($data)
  236.                         );
  237.             if (!MDB::isError($clob $this->db->createLob($char_lob))) {
  238.                 $this->db->setParamClob($prepared_query,1,$clob,'cachedata');
  239.                 if(MDB::isError($error=$this->db->executeQuery($prepared_query))) {
  240.                     return new Cache_Error('MDB::query failed: '
  241.                             . $error->getMessage(__FILE____LINE__);
  242.                 }
  243.                 $this->db->destroyLob($clob);
  244.             else {
  245.                 // creation of the handler object failed
  246.                 return new Cache_Error('MDB::query failed: '
  247.                         . $clob->getMessage(__FILE____LINE__);
  248.             }
  249.             $this->db->freePreparedQuery($prepared_query);
  250.         else {
  251.             //prepared query failed
  252.             return new Cache_Error('MDB::query failed: '
  253.                     . $prepared_query->getMessage(__FILE____LINE__);
  254.         }
  255.     }
  256.  
  257.     /**
  258.      * Removes a dataset from the database
  259.      *
  260.      * @param    string  dataset ID
  261.      * @param    string  cache group
  262.      */
  263.     function remove($id$group)
  264.     {
  265.         $this->flushPreload($id$group);
  266.  
  267.         $query 'DELETE FROM '     $this->cache_table
  268.                 .' WHERE id='       $this->db->getTextValue($id)
  269.                 .' AND cachegroup=' $this->db->getTextValue($group);
  270.  
  271.         $res $this->db->query($query);
  272.         if (MDB::isError($res)) {
  273.             return new Cache_Error('MDB::query failed: '
  274.                     . $this->db->errorMessage($res)__FILE____LINE__);
  275.         }
  276.     }
  277.  
  278.     /**
  279.      * Remove all cached data for a certain group, or empty
  280.      * the cache table if no group is specified.
  281.      *
  282.      * @param    string  cache group
  283.      */
  284.     function flush($group '')
  285.     {
  286.         $this->flushPreload();
  287.  
  288.         if ($group{
  289.             $query 'DELETE FROM '       $this->cache_table
  290.                     .' WHERE cachegroup=' $this->db->getTextValue($group);
  291.         else {
  292.             $query 'DELETE FROM ' $this->cache_table;
  293.         }
  294.  
  295.         $res $this->db->query($query);
  296.         if (MDB::isError($res)) {
  297.             return new Cache_Error('MDB::query failed: '
  298.                 . $this->db->errorMessage($res)__FILE____LINE__);
  299.         }
  300.     }
  301.  
  302.     /**
  303.      * Check if a dataset ID/group exists.
  304.      *
  305.      * @param    string  dataset ID
  306.      * @param    string  cache group
  307.      * @return   boolean 
  308.      */
  309.     function idExists($id$group)
  310.     {
  311.         $query 'SELECT id FROM '  $this->cache_table
  312.                 .' WHERE id='       $this->db->getTextValue($id)
  313.                 .' AND cachegroup=' $this->db->getTextValue($group);
  314.         echo $query;
  315.         $res $this->db->query($query);
  316.         if (MDB::isError($res)) {
  317.             return new Cache_Error('MDB::query failed: '
  318.                     . $this->db->errorMessage($res)__FILE____LINE__);
  319.         }
  320.         $row $this->db->fetchInto($res);
  321.  
  322.         if (is_array($row)) {
  323.             return true;
  324.         }
  325.         return false;
  326.     }
  327.  
  328.     /**
  329.      * Garbage collector.
  330.      *
  331.      * @param    int maxlifetime
  332.      */
  333.     function garbageCollection($maxlifetime)
  334.     {
  335.         $this->flushPreload();
  336.         $query 'DELETE FROM '        $this->cache_table
  337.                 .' WHERE (expires <= ' time()
  338.                 .' AND expires > 0) OR changed <= 'time($maxlifetime;
  339.  
  340.         $res $this->db->query($query);
  341.  
  342.         $query 'SELECT sum(length(cachedata)) as CacheSize FROM '
  343.                 . $this->cache_table;
  344.  
  345.         $cachesize $this->db->getOne($query);
  346.         if (MDB::isError($cachesize)) {
  347.             return new Cache_Error('MDB::query failed: '
  348.                    . $this->db->errorMessage($cachesize)__FILE____LINE__);
  349.         }
  350.         //if cache is to big.
  351.         if ($cachesize $this->highwater{
  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. ?>

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