cache.inc

  1. 8.0.x includes/cache.inc
  2. 8.0.x commands/core/drupal/cache.inc
  3. 6.x includes/cache.inc
  4. 7.x includes/cache.inc
  5. 7.x commands/core/drupal/cache.inc
  6. 5.x includes/cache.inc
  7. master commands/core/drupal/cache.inc
  8. master includes/cache.inc

Drush cache API

Provides a cache API for drush core and commands, forked from Drupal 7.

The default storage backend uses the plain text files to store serialized php objects, which can be extended or replaced by setting the cache-default-class option in drushrc.php.

Functions

Namesort descending Description
drush_cache_clear_all Expire data from the cache.
drush_cache_get Return data from the persistent cache
drush_cache_get_bins Return drush cache bins and any bins added by implementing hook_drush_flush_caches().
drush_cache_get_multiple Return data from the persistent cache when given an array of cache IDs.
drush_cache_set Store data in the persistent cache.
drush_get_cid Create a cache id from a given prefix, contexts, and any additional parameters necessary.
_drush_cache_get_object Get the cache object for a cache bin.
_drush_cache_is_empty Check if a cache bin is empty.

Constants

Namesort descending Description
DRUSH_CACHE_PERMANENT Indicates that the item should never be removed unless explicitly selected.
DRUSH_CACHE_TEMPORARY Indicates that the item should be removed at the next general cache wipe.

Classes

Namesort descending Description
DrushFileCache Default cache implementation.
DrushJSONCache JSON cache storage backend.

Interfaces

Namesort descending Description
DrushCacheInterface Interface for cache implementations.

File

includes/cache.inc
View source
  1. <?php
  2. /**
  3. * @file
  4. * Drush cache API
  5. *
  6. * Provides a cache API for drush core and commands, forked from Drupal 7.
  7. *
  8. * The default storage backend uses the plain text files to store serialized php
  9. * objects, which can be extended or replaced by setting the cache-default-class
  10. * option in drushrc.php.
  11. */
  12. /**
  13. * Indicates that the item should never be removed unless explicitly selected.
  14. *
  15. * The item may be removed using cache_clear_all() with a cache ID.
  16. */
  17. define('DRUSH_CACHE_PERMANENT', 0);
  18. /**
  19. * Indicates that the item should be removed at the next general cache wipe.
  20. */
  21. define('DRUSH_CACHE_TEMPORARY', -1);
  22. /**
  23. * Get the cache object for a cache bin.
  24. *
  25. * By default, this returns an instance of the DrushFileCache class.
  26. * Classes implementing DrushCacheInterface can register themselves both as a
  27. * default implementation and for specific bins.
  28. *
  29. * @see DrushCacheInterface
  30. *
  31. * @param $bin
  32. * The cache bin for which the cache object should be returned.
  33. * @return DrushCacheInterface
  34. * The cache object associated with the specified bin.
  35. */
  36. function _drush_cache_get_object($bin) {
  37. static $cache_objects;
  38. if (!isset($cache_objects[$bin])) {
  39. $class = drush_get_option('cache-class-' . $bin, NULL);
  40. if (!isset($class)) {
  41. $class = drush_get_option('cache-default-class', 'DrushJSONCache');
  42. }
  43. $cache_objects[$bin] = new $class($bin);
  44. }
  45. return $cache_objects[$bin];
  46. }
  47. /**
  48. * Return data from the persistent cache
  49. *
  50. * Data may be stored as either plain text or as serialized data. _drush_cache_get
  51. * will automatically return unserialized objects and arrays.
  52. *
  53. * @param $cid
  54. * The cache ID of the data to retrieve.
  55. * @param $bin
  56. * The cache bin to store the data in.
  57. *
  58. * @return
  59. * The cache or FALSE on failure.
  60. */
  61. function drush_cache_get($cid, $bin = 'default') {
  62. $ret = _drush_cache_get_object($bin)->get($cid);
  63. $mess = $ret ? "HIT" : "MISS";
  64. drush_log(dt("Cache !mess cid: !cid", array('!mess' => $mess, '!cid' => $cid)), 'debug');
  65. return $ret;
  66. }
  67. /**
  68. * Return data from the persistent cache when given an array of cache IDs.
  69. *
  70. * @param $cids
  71. * An array of cache IDs for the data to retrieve. This is passed by
  72. * reference, and will have the IDs successfully returned from cache removed.
  73. * @param $bin
  74. * The cache bin where the data is stored.
  75. * @return
  76. * An array of the items successfully returned from cache indexed by cid.
  77. */
  78. function drush_cache_get_multiple(array &$cids, $bin = 'default') {
  79. return _drush_cache_get_object($bin)->getMultiple($cids);
  80. }
  81. /**
  82. * Store data in the persistent cache.
  83. *
  84. * @param $cid
  85. * The cache ID of the data to store.
  86. * @param $data
  87. * The data to store in the cache.
  88. * @param $bin
  89. * The cache bin to store the data in.
  90. * @param $expire
  91. * One of the following values:
  92. * - DRUSH_CACHE_PERMANENT: Indicates that the item should never be removed unless
  93. * explicitly told to using cache_clear_all() with a cache ID.
  94. * - DRUSH_CACHE_TEMPORARY: Indicates that the item should be removed at the next
  95. * general cache wipe.
  96. * - A Unix timestamp: Indicates that the item should be kept at least until
  97. * the given time, after which it behaves like DRUSH_CACHE_TEMPORARY.
  98. */
  99. function drush_cache_set($cid, $data, $bin = 'default', $expire = DRUSH_CACHE_PERMANENT) {
  100. $ret = _drush_cache_get_object($bin)->set($cid, $data, $expire);
  101. if ($ret) drush_log(dt("Cache SET cid: !cid", array('!cid' => $cid)), 'debug');
  102. return $ret;
  103. }
  104. /**
  105. * Expire data from the cache.
  106. *
  107. * If called without arguments, expirable entries will be cleared from all known
  108. * cache bins.
  109. *
  110. * @param $cid
  111. * If set, the cache ID to delete. Otherwise, all cache entries that can
  112. * expire are deleted.
  113. *
  114. * @param $bin
  115. * If set, the bin $bin to delete from. Mandatory
  116. * argument if $cid is set.
  117. *
  118. * @param $wildcard
  119. * If $wildcard is TRUE, cache IDs starting with $cid are deleted in
  120. * addition to the exact cache ID specified by $cid. If $wildcard is
  121. * TRUE and $cid is '*' then the entire bin $bin is emptied.
  122. */
  123. function drush_cache_clear_all($cid = NULL, $bin = 'default', $wildcard = FALSE) {
  124. if (!isset($cid) && !isset($bin)) {
  125. foreach (drush_cache_get_bins() as $bin) {
  126. _drush_cache_get_object($bin)->clear();
  127. }
  128. return;
  129. }
  130. return _drush_cache_get_object($bin)->clear($cid, $wildcard);
  131. }
  132. /**
  133. * Check if a cache bin is empty.
  134. *
  135. * A cache bin is considered empty if it does not contain any valid data for any
  136. * cache ID.
  137. *
  138. * @param $bin
  139. * The cache bin to check.
  140. * @return
  141. * TRUE if the cache bin specified is empty.
  142. */
  143. function _drush_cache_is_empty($bin) {
  144. return _drush_cache_get_object($bin)->isEmpty();
  145. }
  146. /**
  147. * Return drush cache bins and any bins added by
  148. * implementing hook_drush_flush_caches().
  149. */
  150. function drush_cache_get_bins() {
  151. $drush = array('default');
  152. return array_merge(drush_command_invoke_all('drush_flush_caches'), $drush);
  153. }
  154. /**
  155. * Create a cache id from a given prefix, contexts, and any additional
  156. * parameters necessary.
  157. *
  158. * @param prefix
  159. * A human readable cid prefix that will not be hashed.
  160. * @param contexts
  161. * Optional. An array of drush contexts that will be used to build a unique hash.
  162. * @param params
  163. * Optional. An array of any addition parameters to be hashed.
  164. *
  165. * @return
  166. * A cache id string.
  167. */
  168. function drush_get_cid($prefix, $contexts = array(), $params = array()) {
  169. $cid = array();
  170. foreach ($contexts as $context) {
  171. $c = drush_get_context($context);
  172. if (!empty($c)) {
  173. $cid[] = is_scalar($c) ? $c : serialize($c);
  174. }
  175. }
  176. foreach ($params as $param) {
  177. $cid[] = $param;
  178. }
  179. return DRUSH_VERSION . '-' . $prefix . '-' . md5(implode("", $cid));
  180. }
  181. /**
  182. * Interface for cache implementations.
  183. *
  184. * All cache implementations have to implement this interface.
  185. * DrushDatabaseCache provides the default implementation, which can be
  186. * consulted as an example.
  187. *
  188. * To make Drush use your implementation for a certain cache bin, you have to
  189. * set a variable with the name of the cache bin as its key and the name of
  190. * your class as its value. For example, if your implementation of
  191. * DrushCacheInterface was called MyCustomCache, the following line in
  192. * drushrc.php would make Drush use it for the 'example' bin:
  193. * @code
  194. * $options['cache-class-example'] = 'MyCustomCache;
  195. * @endcode
  196. *
  197. * Additionally, you can register your cache implementation to be used by
  198. * default for all cache bins by setting the option 'cache-default-class' to
  199. * the name of your implementation of the DrushCacheInterface, e.g.
  200. * @code
  201. * $options['cache-default-class'] = 'MyCustomCache;
  202. * @endcode
  203. *
  204. * @see _drush_cache_get_object()
  205. * @see DrupalCacheInterface
  206. */
  207. interface DrushCacheInterface {
  208. /**
  209. * Constructor.
  210. *
  211. * @param $bin
  212. * The cache bin for which the object is created.
  213. */
  214. function __construct($bin);
  215. /**
  216. * Return data from the persistent cache.
  217. *
  218. * @param $cid
  219. * The cache ID of the data to retrieve.
  220. * @return
  221. * The cache or FALSE on failure.
  222. */
  223. function get($cid);
  224. /**
  225. * Return data from the persistent cache when given an array of cache IDs.
  226. *
  227. * @param $cids
  228. * An array of cache IDs for the data to retrieve. This is passed by
  229. * reference, and will have the IDs successfully returned from cache
  230. * removed.
  231. * @return
  232. * An array of the items successfully returned from cache indexed by cid.
  233. */
  234. function getMultiple(&$cids);
  235. /**
  236. * Store data in the persistent cache.
  237. *
  238. * @param $cid
  239. * The cache ID of the data to store.
  240. * @param $data
  241. * The data to store in the cache.
  242. * @param $expire
  243. * One of the following values:
  244. * - DRUSH_CACHE_PERMANENT: Indicates that the item should never be removed unless
  245. * explicitly told to using _drush_cache_clear_all() with a cache ID.
  246. * - DRUSH_CACHE_TEMPORARY: Indicates that the item should be removed at the next
  247. * general cache wipe.
  248. * - A Unix timestamp: Indicates that the item should be kept at least until
  249. * the given time, after which it behaves like CACHE_TEMPORARY.
  250. */
  251. function set($cid, $data, $expire = DRUSH_CACHE_PERMANENT);
  252. /**
  253. * Expire data from the cache. If called without arguments, expirable
  254. * entries will be cleared from all known cache bins.
  255. *
  256. * @param $cid
  257. * If set, the cache ID to delete. Otherwise, all cache entries that can
  258. * expire are deleted.
  259. * @param $wildcard
  260. * If set to TRUE, the $cid is treated as a substring
  261. * to match rather than a complete ID. The match is a right hand
  262. * match. If '*' is given as $cid, the bin $bin will be emptied.
  263. */
  264. function clear($cid = NULL, $wildcard = FALSE);
  265. /**
  266. * Check if a cache bin is empty.
  267. *
  268. * A cache bin is considered empty if it does not contain any valid data for
  269. * any cache ID.
  270. *
  271. * @return
  272. * TRUE if the cache bin specified is empty.
  273. */
  274. function isEmpty();
  275. }
  276. /**
  277. * Default cache implementation.
  278. *
  279. * This is Drush's default cache implementation. It uses plain text files
  280. * containing serialized php to store cached data. Each cache bin corresponds
  281. * to a directory by the same name.
  282. */
  283. class DrushFileCache implements DrushCacheInterface {
  284. const EXTENSION = '.cache';
  285. protected $bin;
  286. function __construct($bin) {
  287. $this->bin = $bin;
  288. $this->directory = $this->cacheDirectory();
  289. }
  290. function cacheDirectory($bin = NULL) {
  291. $bin = $bin ? $bin : $this->bin;
  292. return drush_directory_cache($bin);
  293. }
  294. function get($cid) {
  295. $cids = array($cid);
  296. $cache = $this->getMultiple($cids);
  297. return reset($cache);
  298. }
  299. function getMultiple(&$cids) {
  300. try {
  301. $cache = array();
  302. foreach ($cids as $cid) {
  303. $filename = $this->getFilePath($cid);
  304. if (!file_exists($filename)) throw new Exception;
  305. $item = $this->readFile($filename);
  306. if ($item) {
  307. $cache[$cid] = $item;
  308. }
  309. }
  310. $cids = array_diff($cids, array_keys($cache));
  311. return $cache;
  312. }
  313. catch (Exception $e) {
  314. return array();
  315. }
  316. }
  317. function readFile($filename) {
  318. $item = file_get_contents($filename);
  319. return $item ? unserialize($item) : FALSE;
  320. }
  321. function set($cid, $data, $expire = DRUSH_CACHE_PERMANENT, array $headers = NULL) {
  322. $created = time();
  323. $cache = new stdClass;
  324. $cache->cid = $cid;
  325. $cache->data = is_object($data) ? clone $data : $data;
  326. $cache->created = $created;
  327. $cache->headers = $headers;
  328. if ($expire == DRUSH_CACHE_TEMPORARY) {
  329. $cache->expire = $created + 2591999;
  330. }
  331. // Expire time is in seconds if less than 30 days, otherwise is a timestamp.
  332. elseif ($expire != DRUSH_CACHE_PERMANENT && $expire < 2592000) {
  333. $cache->expire = $created + $expire;
  334. }
  335. else {
  336. $cache->expire = $expire;
  337. }
  338. // Ensure the cache directory still exists, in case a backend process
  339. // cleared the cache after the cache was initialized.
  340. drush_mkdir($this->directory);
  341. $filename = $this->getFilePath($cid);
  342. return $this->writeFile($filename, $cache);
  343. }
  344. function writeFile($filename, $cache) {
  345. return file_put_contents($filename, serialize($cache));
  346. }
  347. function clear($cid = NULL, $wildcard = FALSE) {
  348. $bin_dir = $this->cacheDirectory();
  349. $files = array();
  350. if (empty($cid)) {
  351. drush_delete_dir($bin_dir, TRUE);
  352. }
  353. else {
  354. if ($wildcard) {
  355. if ($cid == '*') {
  356. drush_delete_dir($bin_dir, TRUE);
  357. }
  358. else {
  359. $matches = drush_scan_directory($bin_dir, "/^$cid/", array('.', '..'));
  360. $files = $files + array_keys($matches);
  361. }
  362. }
  363. else {
  364. $files[] = $this->getFilePath($cid);
  365. }
  366. foreach ($files as $f) {
  367. // Delete immediately instead of drush_register_file_for_deletion().
  368. unlink($f);
  369. }
  370. }
  371. }
  372. function isEmpty() {
  373. $files = drush_scan_directory($dir, "//", array('.', '..'));
  374. return empty($files);
  375. }
  376. /**
  377. * Converts a cache id to a full path.
  378. *
  379. * @param $cid
  380. * The cache ID of the data to retrieve.
  381. * @return
  382. * The full path to the cache file.
  383. */
  384. protected function getFilePath($cid) {
  385. return $this->directory . '/' . str_replace(array(':'), '.', $cid) . self::EXTENSION;
  386. }
  387. }
  388. /**
  389. * JSON cache storage backend.
  390. */
  391. class DrushJSONCache extends DrushFileCache {
  392. const EXTENSION = '.json';
  393. function readFile($filename) {
  394. $item = file_get_contents($filename);
  395. return $item ? (object)drush_json_decode($item) : FALSE;
  396. }
  397. function writeFile($filename, $cache) {
  398. return file_put_contents($filename, drush_json_encode($cache));
  399. }
  400. }