QueryCacher.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  11. * @link https://cakephp.org CakePHP(tm) Project
  12. * @since 3.0.0
  13. * @license https://opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Datasource;
  16. use Cake\Cache\Cache;
  17. use Cake\Cache\CacheEngine;
  18. use RuntimeException;
  19. use Traversable;
  20. /**
  21. * Handles caching queries and loading results from the cache.
  22. *
  23. * Used by Cake\Datasource\QueryTrait internally.
  24. *
  25. * @see \Cake\Datasource\QueryTrait::cache() for the public interface.
  26. */
  27. class QueryCacher
  28. {
  29. /**
  30. * The key or function to generate a key.
  31. *
  32. * @var string|callable
  33. */
  34. protected $_key;
  35. /**
  36. * Config for cache engine.
  37. *
  38. * @var string|\Cake\Cache\CacheEngine
  39. */
  40. protected $_config;
  41. /**
  42. * Constructor.
  43. *
  44. * @param string|\Closure $key The key or function to generate a key.
  45. * @param string|\Cake\Cache\CacheEngine $config The cache config name or cache engine instance.
  46. * @throws \RuntimeException
  47. */
  48. public function __construct($key, $config)
  49. {
  50. if (!is_string($key) && !is_callable($key)) {
  51. throw new RuntimeException('Cache keys must be strings or callables.');
  52. }
  53. $this->_key = $key;
  54. if (!is_string($config) && !($config instanceof CacheEngine)) {
  55. throw new RuntimeException('Cache configs must be strings or CacheEngine instances.');
  56. }
  57. $this->_config = $config;
  58. }
  59. /**
  60. * Load the cached results from the cache or run the query.
  61. *
  62. * @param object $query The query the cache read is for.
  63. * @return \Cake\Datasource\ResultSetInterface|null Either the cached results or null.
  64. */
  65. public function fetch($query)
  66. {
  67. $key = $this->_resolveKey($query);
  68. $storage = $this->_resolveCacher();
  69. $result = $storage->read($key);
  70. if (empty($result)) {
  71. return null;
  72. }
  73. return $result;
  74. }
  75. /**
  76. * Store the result set into the cache.
  77. *
  78. * @param object $query The query the cache read is for.
  79. * @param \Traversable $results The result set to store.
  80. * @return bool True if the data was successfully cached, false on failure
  81. */
  82. public function store($query, Traversable $results)
  83. {
  84. $key = $this->_resolveKey($query);
  85. $storage = $this->_resolveCacher();
  86. return $storage->write($key, $results);
  87. }
  88. /**
  89. * Get/generate the cache key.
  90. *
  91. * @param object $query The query to generate a key for.
  92. * @return string
  93. * @throws \RuntimeException
  94. */
  95. protected function _resolveKey($query)
  96. {
  97. if (is_string($this->_key)) {
  98. return $this->_key;
  99. }
  100. $func = $this->_key;
  101. $key = $func($query);
  102. if (!is_string($key)) {
  103. $msg = sprintf('Cache key functions must return a string. Got %s.', var_export($key, true));
  104. throw new RuntimeException($msg);
  105. }
  106. return $key;
  107. }
  108. /**
  109. * Get the cache engine.
  110. *
  111. * @return \Cake\Cache\CacheEngine
  112. */
  113. protected function _resolveCacher()
  114. {
  115. if (is_string($this->_config)) {
  116. return Cache::engine($this->_config);
  117. }
  118. return $this->_config;
  119. }
  120. }