1 | <?php |
||
2 | /** |
||
3 | * @link https://www.yiiframework.com/ |
||
4 | * @copyright Copyright (c) 2008 Yii Software LLC |
||
5 | * @license https://www.yiiframework.com/license/ |
||
6 | */ |
||
7 | |||
8 | namespace yii\caching; |
||
9 | |||
10 | use yii\base\InvalidConfigException; |
||
11 | use yii\db\QueryInterface; |
||
12 | use yii\di\Instance; |
||
13 | |||
14 | /** |
||
15 | * DbQueryDependency represents a dependency based on the query result of an [[QueryInterface]] instance. |
||
16 | * |
||
17 | * If the query result changes, the dependency is considered as changed. |
||
18 | * The query is specified via the [[query]] property. |
||
19 | * |
||
20 | * Object of any class which matches [[QueryInterface]] can be used, so this dependency can be used not only |
||
21 | * with regular relational databases but with MongoDB, Redis and so on as well. |
||
22 | * |
||
23 | * For more details and usage information on Cache, see the [guide article on caching](guide:caching-overview). |
||
24 | * |
||
25 | * @see QueryInterface |
||
26 | * |
||
27 | * @author Paul Klimov <[email protected]> |
||
28 | * @since 2.0.12 |
||
29 | */ |
||
30 | class DbQueryDependency extends Dependency |
||
31 | { |
||
32 | /** |
||
33 | * @var string|array|object the application component ID of the database connection, connection object or |
||
34 | * its array configuration. |
||
35 | * This field can be left blank, allowing query to determine connection automatically. |
||
36 | */ |
||
37 | public $db; |
||
38 | /** |
||
39 | * @var QueryInterface the query which result is used to determine if the dependency has been changed. |
||
40 | * Actual query method to be invoked is determined by [[method]]. |
||
41 | */ |
||
42 | public $query; |
||
43 | /** |
||
44 | * @var string|callable|null method which should be invoked in over the [[query]] object. |
||
45 | * |
||
46 | * If specified as a string an own query method with such name will be invoked, passing [[db]] value as its |
||
47 | * first argument. For example: `exists`, `all`. |
||
48 | * |
||
49 | * This field can be specified as a PHP callback of following signature: |
||
50 | * |
||
51 | * ```php |
||
52 | * function (QueryInterface $query, mixed $db) { |
||
53 | * //return mixed; |
||
54 | * } |
||
55 | * ``` |
||
56 | * |
||
57 | * If not set - [[QueryInterface::one()]] will be used. |
||
58 | */ |
||
59 | public $method; |
||
60 | |||
61 | |||
62 | /** |
||
63 | * Generates the data needed to determine if dependency is changed. |
||
64 | * |
||
65 | * This method returns the query result. |
||
66 | * @param CacheInterface $cache the cache component that is currently evaluating this dependency |
||
67 | * @return mixed the data needed to determine if dependency has been changed. |
||
68 | * @throws InvalidConfigException on invalid configuration. |
||
69 | */ |
||
70 | 4 | protected function generateDependencyData($cache) |
|
71 | { |
||
72 | 4 | $db = $this->db; |
|
73 | 4 | if ($db !== null) { |
|
74 | 4 | $db = Instance::ensure($db); |
|
75 | } |
||
76 | |||
77 | 4 | if (!$this->query instanceof QueryInterface) { |
|
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
78 | throw new InvalidConfigException('"' . get_class($this) . '::$query" should be an instance of "yii\db\QueryInterface".'); |
||
79 | } |
||
80 | |||
81 | 4 | if (!empty($db->enableQueryCache)) { |
|
82 | // temporarily disable and re-enable query caching |
||
83 | 4 | $originEnableQueryCache = $db->enableQueryCache; |
|
84 | 4 | $db->enableQueryCache = false; |
|
85 | 4 | $result = $this->executeQuery($this->query, $db); |
|
86 | 4 | $db->enableQueryCache = $originEnableQueryCache; |
|
87 | } else { |
||
88 | $result = $this->executeQuery($this->query, $db); |
||
89 | } |
||
90 | |||
91 | 4 | return $result; |
|
92 | } |
||
93 | |||
94 | /** |
||
95 | * Executes the query according to [[method]] specification. |
||
96 | * @param QueryInterface $query query to be executed. |
||
97 | * @param mixed $db connection. |
||
98 | * @return mixed query result. |
||
99 | */ |
||
100 | 4 | private function executeQuery($query, $db) |
|
101 | { |
||
102 | 4 | if ($this->method === null) { |
|
103 | 1 | return $query->one($db); |
|
104 | } |
||
105 | 3 | if (is_string($this->method)) { |
|
106 | 1 | return call_user_func([$query, $this->method], $db); |
|
107 | } |
||
108 | |||
109 | 2 | return call_user_func($this->method, $query, $db); |
|
110 | } |
||
111 | } |
||
112 |