cms/drupal/includes/cache.inc
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * @file
       
     5  * Functions and interfaces for cache handling.
       
     6  */
       
     7 
       
     8 /**
       
     9  * Gets the cache object for a cache bin.
       
    10  *
       
    11  * By default, this returns an instance of the DrupalDatabaseCache class.
       
    12  * Classes implementing DrupalCacheInterface can register themselves both as a
       
    13  * default implementation and for specific bins.
       
    14  *
       
    15  * @param $bin
       
    16  *   The cache bin for which the cache object should be returned.
       
    17  *
       
    18  * @return DrupalCacheInterface
       
    19  *   The cache object associated with the specified bin.
       
    20  *
       
    21  * @see DrupalCacheInterface
       
    22  */
       
    23 function _cache_get_object($bin) {
       
    24   // We do not use drupal_static() here because we do not want to change the
       
    25   // storage of a cache bin mid-request.
       
    26   static $cache_objects;
       
    27   if (!isset($cache_objects[$bin])) {
       
    28     $class = variable_get('cache_class_' . $bin);
       
    29     if (!isset($class)) {
       
    30       $class = variable_get('cache_default_class', 'DrupalDatabaseCache');
       
    31     }
       
    32     $cache_objects[$bin] = new $class($bin);
       
    33   }
       
    34   return $cache_objects[$bin];
       
    35 }
       
    36 
       
    37 /**
       
    38  * Returns data from the persistent cache.
       
    39  *
       
    40  * Data may be stored as either plain text or as serialized data. cache_get
       
    41  * will automatically return unserialized objects and arrays.
       
    42  *
       
    43  * @param $cid
       
    44  *   The cache ID of the data to retrieve.
       
    45  * @param $bin
       
    46  *   The cache bin to store the data in. Valid core values are 'cache_block',
       
    47  *   'cache_bootstrap', 'cache_field', 'cache_filter', 'cache_form',
       
    48  *   'cache_menu', 'cache_page', 'cache_path', 'cache_update' or 'cache' for
       
    49  *   the default cache.
       
    50  *
       
    51  * @return
       
    52  *   The cache or FALSE on failure.
       
    53  *
       
    54  * @see cache_set()
       
    55  */
       
    56 function cache_get($cid, $bin = 'cache') {
       
    57   return _cache_get_object($bin)->get($cid);
       
    58 }
       
    59 
       
    60 /**
       
    61  * Returns data from the persistent cache when given an array of cache IDs.
       
    62  *
       
    63  * @param $cids
       
    64  *   An array of cache IDs for the data to retrieve. This is passed by
       
    65  *   reference, and will have the IDs successfully returned from cache removed.
       
    66  * @param $bin
       
    67  *   The cache bin where the data is stored.
       
    68  *
       
    69  * @return
       
    70  *   An array of the items successfully returned from cache indexed by cid.
       
    71  */
       
    72 function cache_get_multiple(array &$cids, $bin = 'cache') {
       
    73   return _cache_get_object($bin)->getMultiple($cids);
       
    74 }
       
    75 
       
    76 /**
       
    77  * Stores data in the persistent cache.
       
    78  *
       
    79  * The persistent cache is split up into several cache bins. In the default
       
    80  * cache implementation, each cache bin corresponds to a database table by the
       
    81  * same name. Other implementations might want to store several bins in data
       
    82  * structures that get flushed together. While it is not a problem for most
       
    83  * cache bins if the entries in them are flushed before their expire time, some
       
    84  * might break functionality or are extremely expensive to recalculate. The
       
    85  * other bins are expired automatically by core. Contributed modules can add
       
    86  * additional bins and get them expired automatically by implementing
       
    87  * hook_flush_caches().
       
    88  *
       
    89  * The reasons for having several bins are as follows:
       
    90  * - Smaller bins mean smaller database tables and allow for faster selects and
       
    91  *   inserts.
       
    92  * - We try to put fast changing cache items and rather static ones into
       
    93  *   different bins. The effect is that only the fast changing bins will need a
       
    94  *   lot of writes to disk. The more static bins will also be better cacheable
       
    95  *   with MySQL's query cache.
       
    96  *
       
    97  * @param $cid
       
    98  *   The cache ID of the data to store.
       
    99  * @param $data
       
   100  *   The data to store in the cache. Complex data types will be automatically
       
   101  *   serialized before insertion. Strings will be stored as plain text and are
       
   102  *   not serialized. Some storage engines only allow objects up to a maximum of
       
   103  *   1MB in size to be stored by default. When caching large arrays or similar,
       
   104  *   take care to ensure $data does not exceed this size.
       
   105  * @param $bin
       
   106  *   (optional) The cache bin to store the data in. Valid core values are:
       
   107  *   - cache: (default) Generic cache storage bin (used for theme registry,
       
   108  *     locale date, list of simpletest tests, etc.).
       
   109  *   - cache_block: Stores the content of various blocks.
       
   110  *   - cache_bootstrap: Stores the class registry, the system list of modules,
       
   111  *     the list of which modules implement which hooks, and the Drupal variable
       
   112  *     list.
       
   113  *   - cache_field: Stores the field data belonging to a given object.
       
   114  *   - cache_filter: Stores filtered pieces of content.
       
   115  *   - cache_form: Stores multistep forms. Flushing this bin means that some
       
   116  *     forms displayed to users lose their state and the data already submitted
       
   117  *     to them. This bin should not be flushed before its expired time.
       
   118  *   - cache_menu: Stores the structure of visible navigation menus per page.
       
   119  *   - cache_page: Stores generated pages for anonymous users. It is flushed
       
   120  *     very often, whenever a page changes, at least for every node and comment
       
   121  *     submission. This is the only bin affected by the page cache setting on
       
   122  *     the administrator panel.
       
   123  *   - cache_path: Stores the system paths that have an alias.
       
   124  * @param $expire
       
   125  *   (optional) Controls the maximum lifetime of this cache entry. Note that
       
   126  *   caches might be subject to clearing at any time, so this setting does not
       
   127  *   guarantee a minimum lifetime. With this in mind, the cache should not be
       
   128  *   used for data that must be kept during a cache clear, like sessions.
       
   129  *
       
   130  *   Use one of the following values:
       
   131  *   - CACHE_PERMANENT: Indicates that the item should never be removed unless
       
   132  *     explicitly told to using cache_clear_all() with a cache ID.
       
   133  *   - CACHE_TEMPORARY: Indicates that the item should be removed at the next
       
   134  *     general cache wipe.
       
   135  *   - A Unix timestamp: Indicates that the item should be kept at least until
       
   136  *     the given time, after which it behaves like CACHE_TEMPORARY.
       
   137  *
       
   138  * @see _update_cache_set()
       
   139  * @see cache_get()
       
   140  */
       
   141 function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) {
       
   142   return _cache_get_object($bin)->set($cid, $data, $expire);
       
   143 }
       
   144 
       
   145 /**
       
   146  * Expires data from the cache.
       
   147  *
       
   148  * If called with the arguments $cid and $bin set to NULL or omitted, then
       
   149  * expirable entries will be cleared from the cache_page and cache_block bins,
       
   150  * and the $wildcard argument is ignored.
       
   151  *
       
   152  * @param $cid
       
   153  *   If set, the cache ID or an array of cache IDs. Otherwise, all cache entries
       
   154  *   that can expire are deleted. The $wildcard argument will be ignored if set
       
   155  *   to NULL.
       
   156  * @param $bin
       
   157  *   If set, the cache bin to delete from. Mandatory argument if $cid is set.
       
   158  * @param $wildcard
       
   159  *   If TRUE, the $cid argument must contain a string value and cache IDs
       
   160  *   starting with $cid are deleted in addition to the exact cache ID specified
       
   161  *   by $cid. If $wildcard is TRUE and $cid is '*', the entire cache is emptied.
       
   162  */
       
   163 function cache_clear_all($cid = NULL, $bin = NULL, $wildcard = FALSE) {
       
   164   if (!isset($cid) && !isset($bin)) {
       
   165     // Clear the block cache first, so stale data will
       
   166     // not end up in the page cache.
       
   167     if (module_exists('block')) {
       
   168       cache_clear_all(NULL, 'cache_block');
       
   169     }
       
   170     cache_clear_all(NULL, 'cache_page');
       
   171     return;
       
   172   }
       
   173   return _cache_get_object($bin)->clear($cid, $wildcard);
       
   174 }
       
   175 
       
   176 /**
       
   177  * Checks if a cache bin is empty.
       
   178  *
       
   179  * A cache bin is considered empty if it does not contain any valid data for any
       
   180  * cache ID.
       
   181  *
       
   182  * @param $bin
       
   183  *   The cache bin to check.
       
   184  *
       
   185  * @return
       
   186  *   TRUE if the cache bin specified is empty.
       
   187  */
       
   188 function cache_is_empty($bin) {
       
   189   return _cache_get_object($bin)->isEmpty();
       
   190 }
       
   191 
       
   192 /**
       
   193  * Defines an interface for cache implementations.
       
   194  *
       
   195  * All cache implementations have to implement this interface.
       
   196  * DrupalDatabaseCache provides the default implementation, which can be
       
   197  * consulted as an example.
       
   198  *
       
   199  * To make Drupal use your implementation for a certain cache bin, you have to
       
   200  * set a variable with the name of the cache bin as its key and the name of
       
   201  * your class as its value. For example, if your implementation of
       
   202  * DrupalCacheInterface was called MyCustomCache, the following line would make
       
   203  * Drupal use it for the 'cache_page' bin:
       
   204  * @code
       
   205  *  variable_set('cache_class_cache_page', 'MyCustomCache');
       
   206  * @endcode
       
   207  *
       
   208  * Additionally, you can register your cache implementation to be used by
       
   209  * default for all cache bins by setting the variable 'cache_default_class' to
       
   210  * the name of your implementation of the DrupalCacheInterface, e.g.
       
   211  * @code
       
   212  *  variable_set('cache_default_class', 'MyCustomCache');
       
   213  * @endcode
       
   214  *
       
   215  * To implement a completely custom cache bin, use the same variable format:
       
   216  * @code
       
   217  *  variable_set('cache_class_custom_bin', 'MyCustomCache');
       
   218  * @endcode
       
   219  * To access your custom cache bin, specify the name of the bin when storing
       
   220  * or retrieving cached data:
       
   221  * @code
       
   222  *  cache_set($cid, $data, 'custom_bin', $expire);
       
   223  *  cache_get($cid, 'custom_bin');
       
   224  * @endcode
       
   225  *
       
   226  * @see _cache_get_object()
       
   227  * @see DrupalDatabaseCache
       
   228  */
       
   229 interface DrupalCacheInterface {
       
   230 
       
   231   /**
       
   232    * Returns data from the persistent cache.
       
   233    *
       
   234    * Data may be stored as either plain text or as serialized data. cache_get()
       
   235    * will automatically return unserialized objects and arrays.
       
   236    *
       
   237    * @param $cid
       
   238    *   The cache ID of the data to retrieve.
       
   239    *
       
   240    * @return
       
   241    *   The cache or FALSE on failure.
       
   242    */
       
   243   function get($cid);
       
   244 
       
   245   /**
       
   246    * Returns data from the persistent cache when given an array of cache IDs.
       
   247    *
       
   248    * @param $cids
       
   249    *   An array of cache IDs for the data to retrieve. This is passed by
       
   250    *   reference, and will have the IDs successfully returned from cache
       
   251    *   removed.
       
   252    *
       
   253    * @return
       
   254    *   An array of the items successfully returned from cache indexed by cid.
       
   255    */
       
   256    function getMultiple(&$cids);
       
   257 
       
   258   /**
       
   259    * Stores data in the persistent cache.
       
   260    *
       
   261    * @param $cid
       
   262    *   The cache ID of the data to store.
       
   263    * @param $data
       
   264    *   The data to store in the cache. Complex data types will be automatically
       
   265    *   serialized before insertion. Strings will be stored as plain text and not
       
   266    *   serialized. Some storage engines only allow objects up to a maximum of
       
   267    *   1MB in size to be stored by default. When caching large arrays or
       
   268    *   similar, take care to ensure $data does not exceed this size.
       
   269    * @param $expire
       
   270    *   (optional) Controls the maximum lifetime of this cache entry. Note that
       
   271    *   caches might be subject to clearing at any time, so this setting does not
       
   272    *   guarantee a minimum lifetime. With this in mind, the cache should not be
       
   273    *   used for data that must be kept during a cache clear, like sessions.
       
   274    *
       
   275    *   Use one of the following values:
       
   276    *   - CACHE_PERMANENT: Indicates that the item should never be removed unless
       
   277    *     explicitly told to using cache_clear_all() with a cache ID.
       
   278    *   - CACHE_TEMPORARY: Indicates that the item should be removed at the next
       
   279    *     general cache wipe.
       
   280    *   - A Unix timestamp: Indicates that the item should be kept at least until
       
   281    *     the given time, after which it behaves like CACHE_TEMPORARY.
       
   282    */
       
   283   function set($cid, $data, $expire = CACHE_PERMANENT);
       
   284 
       
   285 
       
   286   /**
       
   287    * Expires data from the cache.
       
   288    *
       
   289    * If called without arguments, expirable entries will be cleared from the
       
   290    * cache_page and cache_block bins.
       
   291    *
       
   292    * @param $cid
       
   293    *   If set, the cache ID or an array of cache IDs. Otherwise, all cache
       
   294    *   entries that can expire are deleted. The $wildcard argument will be
       
   295    *   ignored if set to NULL.
       
   296    * @param $wildcard
       
   297    *   If TRUE, the $cid argument must contain a string value and cache IDs
       
   298    *   starting with $cid are deleted in addition to the exact cache ID
       
   299    *   specified by $cid. If $wildcard is TRUE and $cid is '*', the entire
       
   300    *   cache is emptied.
       
   301    */
       
   302   function clear($cid = NULL, $wildcard = FALSE);
       
   303 
       
   304   /**
       
   305    * Checks if a cache bin is empty.
       
   306    *
       
   307    * A cache bin is considered empty if it does not contain any valid data for
       
   308    * any cache ID.
       
   309    *
       
   310    * @return
       
   311    *   TRUE if the cache bin specified is empty.
       
   312    */
       
   313   function isEmpty();
       
   314 }
       
   315 
       
   316 /**
       
   317  * Defines a default cache implementation.
       
   318  *
       
   319  * This is Drupal's default cache implementation. It uses the database to store
       
   320  * cached data. Each cache bin corresponds to a database table by the same name.
       
   321  */
       
   322 class DrupalDatabaseCache implements DrupalCacheInterface {
       
   323   protected $bin;
       
   324 
       
   325   /**
       
   326    * Constructs a DrupalDatabaseCache object.
       
   327    *
       
   328    * @param $bin
       
   329    *   The cache bin for which the object is created.
       
   330    */
       
   331   function __construct($bin) {
       
   332     $this->bin = $bin;
       
   333   }
       
   334 
       
   335   /**
       
   336    * Implements DrupalCacheInterface::get().
       
   337    */
       
   338   function get($cid) {
       
   339     $cids = array($cid);
       
   340     $cache = $this->getMultiple($cids);
       
   341     return reset($cache);
       
   342   }
       
   343 
       
   344   /**
       
   345    * Implements DrupalCacheInterface::getMultiple().
       
   346    */
       
   347   function getMultiple(&$cids) {
       
   348     try {
       
   349       // Garbage collection necessary when enforcing a minimum cache lifetime.
       
   350       $this->garbageCollection($this->bin);
       
   351 
       
   352       // When serving cached pages, the overhead of using db_select() was found
       
   353       // to add around 30% overhead to the request. Since $this->bin is a
       
   354       // variable, this means the call to db_query() here uses a concatenated
       
   355       // string. This is highly discouraged under any other circumstances, and
       
   356       // is used here only due to the performance overhead we would incur
       
   357       // otherwise. When serving an uncached page, the overhead of using
       
   358       // db_select() is a much smaller proportion of the request.
       
   359       $result = db_query('SELECT cid, data, created, expire, serialized FROM {' . db_escape_table($this->bin) . '} WHERE cid IN (:cids)', array(':cids' => $cids));
       
   360       $cache = array();
       
   361       foreach ($result as $item) {
       
   362         $item = $this->prepareItem($item);
       
   363         if ($item) {
       
   364           $cache[$item->cid] = $item;
       
   365         }
       
   366       }
       
   367       $cids = array_diff($cids, array_keys($cache));
       
   368       return $cache;
       
   369     }
       
   370     catch (Exception $e) {
       
   371       // If the database is never going to be available, cache requests should
       
   372       // return FALSE in order to allow exception handling to occur.
       
   373       return array();
       
   374     }
       
   375   }
       
   376 
       
   377   /**
       
   378    * Garbage collection for get() and getMultiple().
       
   379    *
       
   380    * @param $bin
       
   381    *   The bin being requested.
       
   382    */
       
   383   protected function garbageCollection() {
       
   384     $cache_lifetime = variable_get('cache_lifetime', 0);
       
   385 
       
   386     // Clean-up the per-user cache expiration session data, so that the session
       
   387     // handler can properly clean-up the session data for anonymous users.
       
   388     if (isset($_SESSION['cache_expiration'])) {
       
   389       $expire = REQUEST_TIME - $cache_lifetime;
       
   390       foreach ($_SESSION['cache_expiration'] as $bin => $timestamp) {
       
   391         if ($timestamp < $expire) {
       
   392           unset($_SESSION['cache_expiration'][$bin]);
       
   393         }
       
   394       }
       
   395       if (!$_SESSION['cache_expiration']) {
       
   396         unset($_SESSION['cache_expiration']);
       
   397       }
       
   398     }
       
   399 
       
   400     // Garbage collection of temporary items is only necessary when enforcing
       
   401     // a minimum cache lifetime.
       
   402     if (!$cache_lifetime) {
       
   403       return;
       
   404     }
       
   405     // When cache lifetime is in force, avoid running garbage collection too
       
   406     // often since this will remove temporary cache items indiscriminately.
       
   407     $cache_flush = variable_get('cache_flush_' . $this->bin, 0);
       
   408     if ($cache_flush && ($cache_flush + $cache_lifetime <= REQUEST_TIME)) {
       
   409       // Reset the variable immediately to prevent a meltdown in heavy load situations.
       
   410       variable_set('cache_flush_' . $this->bin, 0);
       
   411       // Time to flush old cache data
       
   412       db_delete($this->bin)
       
   413         ->condition('expire', CACHE_PERMANENT, '<>')
       
   414         ->condition('expire', $cache_flush, '<=')
       
   415         ->execute();
       
   416     }
       
   417   }
       
   418 
       
   419   /**
       
   420    * Prepares a cached item.
       
   421    *
       
   422    * Checks that items are either permanent or did not expire, and unserializes
       
   423    * data as appropriate.
       
   424    *
       
   425    * @param $cache
       
   426    *   An item loaded from cache_get() or cache_get_multiple().
       
   427    *
       
   428    * @return
       
   429    *   The item with data unserialized as appropriate or FALSE if there is no
       
   430    *   valid item to load.
       
   431    */
       
   432   protected function prepareItem($cache) {
       
   433     global $user;
       
   434 
       
   435     if (!isset($cache->data)) {
       
   436       return FALSE;
       
   437     }
       
   438     // If the cached data is temporary and subject to a per-user minimum
       
   439     // lifetime, compare the cache entry timestamp with the user session
       
   440     // cache_expiration timestamp. If the cache entry is too old, ignore it.
       
   441     if ($cache->expire != CACHE_PERMANENT && variable_get('cache_lifetime', 0) && isset($_SESSION['cache_expiration'][$this->bin]) && $_SESSION['cache_expiration'][$this->bin] > $cache->created) {
       
   442       // Ignore cache data that is too old and thus not valid for this user.
       
   443       return FALSE;
       
   444     }
       
   445 
       
   446     // If the data is permanent or not subject to a minimum cache lifetime,
       
   447     // unserialize and return the cached data.
       
   448     if ($cache->serialized) {
       
   449       $cache->data = unserialize($cache->data);
       
   450     }
       
   451 
       
   452     return $cache;
       
   453   }
       
   454 
       
   455   /**
       
   456    * Implements DrupalCacheInterface::set().
       
   457    */
       
   458   function set($cid, $data, $expire = CACHE_PERMANENT) {
       
   459     $fields = array(
       
   460       'serialized' => 0,
       
   461       'created' => REQUEST_TIME,
       
   462       'expire' => $expire,
       
   463     );
       
   464     if (!is_string($data)) {
       
   465       $fields['data'] = serialize($data);
       
   466       $fields['serialized'] = 1;
       
   467     }
       
   468     else {
       
   469       $fields['data'] = $data;
       
   470       $fields['serialized'] = 0;
       
   471     }
       
   472 
       
   473     try {
       
   474       db_merge($this->bin)
       
   475         ->key(array('cid' => $cid))
       
   476         ->fields($fields)
       
   477         ->execute();
       
   478     }
       
   479     catch (Exception $e) {
       
   480       // The database may not be available, so we'll ignore cache_set requests.
       
   481     }
       
   482   }
       
   483 
       
   484   /**
       
   485    * Implements DrupalCacheInterface::clear().
       
   486    */
       
   487   function clear($cid = NULL, $wildcard = FALSE) {
       
   488     global $user;
       
   489 
       
   490     if (empty($cid)) {
       
   491       if (variable_get('cache_lifetime', 0)) {
       
   492         // We store the time in the current user's session. We then simulate
       
   493         // that the cache was flushed for this user by not returning cached
       
   494         // data that was cached before the timestamp.
       
   495         $_SESSION['cache_expiration'][$this->bin] = REQUEST_TIME;
       
   496 
       
   497         $cache_flush = variable_get('cache_flush_' . $this->bin, 0);
       
   498         if ($cache_flush == 0) {
       
   499           // This is the first request to clear the cache, start a timer.
       
   500           variable_set('cache_flush_' . $this->bin, REQUEST_TIME);
       
   501         }
       
   502         elseif (REQUEST_TIME > ($cache_flush + variable_get('cache_lifetime', 0))) {
       
   503           // Clear the cache for everyone, cache_lifetime seconds have
       
   504           // passed since the first request to clear the cache.
       
   505           db_delete($this->bin)
       
   506             ->condition('expire', CACHE_PERMANENT, '<>')
       
   507             ->condition('expire', REQUEST_TIME, '<')
       
   508             ->execute();
       
   509           variable_set('cache_flush_' . $this->bin, 0);
       
   510         }
       
   511       }
       
   512       else {
       
   513         // No minimum cache lifetime, flush all temporary cache entries now.
       
   514         db_delete($this->bin)
       
   515           ->condition('expire', CACHE_PERMANENT, '<>')
       
   516           ->condition('expire', REQUEST_TIME, '<')
       
   517           ->execute();
       
   518       }
       
   519     }
       
   520     else {
       
   521       if ($wildcard) {
       
   522         if ($cid == '*') {
       
   523           // Check if $this->bin is a cache table before truncating. Other
       
   524           // cache_clear_all() operations throw a PDO error in this situation,
       
   525           // so we don't need to verify them first. This ensures that non-cache
       
   526           // tables cannot be truncated accidentally.
       
   527           if ($this->isValidBin()) {
       
   528             db_truncate($this->bin)->execute();
       
   529           }
       
   530           else {
       
   531             throw new Exception(t('Invalid or missing cache bin specified: %bin', array('%bin' => $this->bin)));
       
   532           }
       
   533         }
       
   534         else {
       
   535           db_delete($this->bin)
       
   536             ->condition('cid', db_like($cid) . '%', 'LIKE')
       
   537             ->execute();
       
   538         }
       
   539       }
       
   540       elseif (is_array($cid)) {
       
   541         // Delete in chunks when a large array is passed.
       
   542         do {
       
   543           db_delete($this->bin)
       
   544             ->condition('cid', array_splice($cid, 0, 1000), 'IN')
       
   545             ->execute();
       
   546         }
       
   547         while (count($cid));
       
   548       }
       
   549       else {
       
   550         db_delete($this->bin)
       
   551           ->condition('cid', $cid)
       
   552           ->execute();
       
   553       }
       
   554     }
       
   555   }
       
   556 
       
   557   /**
       
   558    * Implements DrupalCacheInterface::isEmpty().
       
   559    */
       
   560   function isEmpty() {
       
   561     $this->garbageCollection();
       
   562     $query = db_select($this->bin);
       
   563     $query->addExpression('1');
       
   564     $result = $query->range(0, 1)
       
   565       ->execute()
       
   566       ->fetchField();
       
   567     return empty($result);
       
   568   }
       
   569 
       
   570   /**
       
   571    * Checks if $this->bin represents a valid cache table.
       
   572    *
       
   573    * This check is required to ensure that non-cache tables are not truncated
       
   574    * accidentally when calling cache_clear_all().
       
   575    *
       
   576    * @return boolean
       
   577    */
       
   578   function isValidBin() {
       
   579     if ($this->bin == 'cache' || substr($this->bin, 0, 6) == 'cache_') {
       
   580       // Skip schema check for bins with standard table names.
       
   581       return TRUE;
       
   582     }
       
   583     // These fields are required for any cache table.
       
   584     $fields = array('cid', 'data', 'expire', 'created', 'serialized');
       
   585     // Load the table schema.
       
   586     $schema = drupal_get_schema($this->bin);
       
   587     // Confirm that all fields are present.
       
   588     return isset($schema['fields']) && !array_diff($fields, array_keys($schema['fields']));
       
   589   }
       
   590 }