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