PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/wind/cache/strategy/WindDbCache.php

http://github.com/phpwind/windframework
PHP | 259 lines | 85 code | 18 blank | 156 comment | 7 complexity | 1b1eec7eb099a026d882e7a6567c7fd7 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. Wind::import('WIND:cache.AbstractWindCache');
  3. /**
  4. * Db缓存策略实现
  5. *
  6. * Db缓存允许用户配置一个缓存数据表,将缓存数据保存到缓存表中.
  7. * 提供对方访问接口如下:
  8. * <ul>
  9. * <li>set($key, $value, $expire): 继承自{@link AbstractWindCache::set()}.</li>
  10. * <li>get($key): 继承自{@link AbstractWindCache::get()}.</li>
  11. * <li>delete($key): 继承自{@link AbstractWindCache::delete()}.</li>
  12. * <li>batchGet($keys): 继承自{@link AbstractWindCache::batchGet()}.</li>
  13. * <li>batchDelete($keys): 继承自{@link AbstractWindCache::batchDelete()}.</li>
  14. * <li>{@link setConfig($config)}: 重写了父类的{@link AbstractWindCache::setConfig()}.</li>
  15. * </ul>
  16. *
  17. * 它接收如下配置:
  18. * <code>
  19. * array(
  20. * 'table-name' => 'pw_cache', //缓存的表名
  21. * 'field-key' => 'key', //缓存key的字段名,唯一键值
  22. * 'field-value' => 'value', //缓存数据存储的字段名
  23. * 'field-expire' => 'expire', //缓存数据的过期时间字段名,为int类型,默认为0
  24. * 'security-code' => '', //继承自AbstractWindCache,安全码配置
  25. * 'key-prefix' => '', //继承自AbstractWindCache,缓存key前缀
  26. * 'expires' => '0', //继承自AbstractWindCache,缓存过期时间配置
  27. * )
  28. * </code>
  29. * <i>Db缓存的使用:</i><br/>
  30. * 1、像使用普通类库一样使用该组件:
  31. * <code>
  32. * Wind::import('WIND:cache.strategy.WindDbCache');
  33. * $cache = new WindDbCache($dbHandler, array('table-name' => 'pw_cache', 'field-key' => 'key', 'field-value' => 'value', 'field-expire' => '0'));
  34. * $cache->set('name', 'windDbTest');
  35. * </code>
  36. * <note><b>注意: </b>需要传入dbHandler(数据库链接对象)</note>
  37. * 2、采用组件配置的方式,通过组件机制调用
  38. * 在应用配置的components组件配置块中,配置dbCache(<i>该名字将决定调用的时候使用的组件名字</i>):
  39. * <pre>
  40. * 'dbCache' => array(
  41. * 'path' => 'WIND:cache.strategy.WindDbCache',
  42. * 'scope' => 'singleton',
  43. * 'properties' => array(
  44. * 'connection' => array('ref' => 'db');
  45. * ),
  46. * 'config' => array(
  47. * 'table-name' => 'pw_cache',
  48. * 'field-key' => 'key',
  49. * 'field-value' => 'value',
  50. * 'field-expire' => 'expire',
  51. * 'security-code' => '',
  52. * 'key-prefix' => '',
  53. * 'expires' => '0',
  54. * ),
  55. * ),
  56. * </pre>
  57. * 在应用中可以通过如下方式获得dbCache对象:
  58. * <code>
  59. * $cache = Wind::getApp()->getComponent('dbCache'); //dbCache的名字来自于组件配置中的名字
  60. * $cache->set('name', 'test');
  61. * </code>
  62. * <note><b>注意: </b>组件配置需要配置属性(preperties),connection其值为db组件的一个引用</note>
  63. *
  64. * the last known user to change this file in the repository <LastChangedBy: xiaoxiao >
  65. * @author xiaoxiao <xiaoxia.xuxx@aliyun-inc.com>
  66. * @copyright ©2003-2103 phpwind.com
  67. * @license http://www.windframework.com
  68. * @version $Id$
  69. * @package strategy
  70. */
  71. class WindDbCache extends AbstractWindCache {
  72. /**
  73. * 链接句柄
  74. *
  75. * @var WindConnection
  76. */
  77. protected $connection;
  78. /**
  79. * 缓存表名
  80. *
  81. * @var string
  82. */
  83. private $table = 'pw_cache';
  84. /**
  85. * 缓存表的键字段
  86. *
  87. * @var string
  88. */
  89. private $keyField = 'key';
  90. /**
  91. * 缓存表的值字段
  92. *
  93. * @var string
  94. */
  95. private $valueField = 'value';
  96. /**
  97. * 缓存表过期时间字段
  98. *
  99. * @var string
  100. */
  101. private $expireField = 'expire';
  102. /**
  103. * 构造函数
  104. *
  105. * 初始化数据
  106. *
  107. * @param WindConnection $connection 数据库链接对象,缺省值为null
  108. * @param array $config 缓存的配置文件,缺省值为array()
  109. */
  110. public function __construct(WindConnection $connection = null, $config = array()) {
  111. $connection && $this->setConnection($connection);
  112. $config && $this->setConfig($config);
  113. }
  114. /* (non-PHPdoc)
  115. * @see AbstractWindCache::setValue()
  116. */
  117. protected function setValue($key, $value, $expire = 0) {
  118. return $this->store($key, $value, $expire);
  119. }
  120. /* (non-PHPdoc)
  121. * @see AbstractWindCache::addValue()
  122. */
  123. protected function addValue($key, $value, $expire = 0) {
  124. return $this->store($key, $value, $expire, 'add');
  125. }
  126. /* (non-PHPdoc)
  127. * @see AbstractWindCache::getValue()
  128. */
  129. protected function getValue($key) {
  130. $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` =? AND (`' . $this->expireField . '`=0 OR `' . $this->expireField . '`>?)';
  131. $data = $this->getConnection()->createStatement($sql)->getOne(array($key, time()));
  132. return $data[$this->valueField];
  133. }
  134. /* (non-PHPdoc)
  135. * @see AbstractWindCache::batchGet()
  136. */
  137. public function batchGet(array $keys) {
  138. $_temp = array();
  139. foreach ($keys as $value) {
  140. $_temp[$value] = $this->buildSecurityKey($value);
  141. }
  142. list($sql, $result) = array('', array());
  143. $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` IN ' . $this->getConnection()->quoteArray(
  144. $_temp) . ' AND (`' . $this->expireField . '`=0 OR `' . $this->expireField . '`>?)';
  145. $data = $this->getConnection()->createStatement($sql)->queryAll(array(time()));
  146. $_keys = array_flip($_temp);
  147. foreach ($data as $tmp) {
  148. $result[$_keys[$tmp[$this->keyField]]] = $this->formatData($_keys[$tmp[$this->keyField]], $tmp[$this->valueField]);
  149. }
  150. return $result;
  151. }
  152. /* (non-PHPdoc)
  153. * @see AbstractWindCache::deleteValue()
  154. */
  155. protected function deleteValue($key) {
  156. $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` = ? ';
  157. return $this->getConnection()->createStatement($sql)->update(array($key));
  158. }
  159. /* (non-PHPdoc)
  160. * @see AbstractWindCache::batchDelete()
  161. */
  162. public function batchDelete(array $keys) {
  163. foreach ($keys as $key => $value) {
  164. $keys[$key] = $this->buildSecurityKey($value);
  165. }
  166. $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` IN ' . $this->getConnection()->quoteArray(
  167. $keys);
  168. return $this->getConnection()->execute($sql);
  169. }
  170. /**
  171. * 清除缓存数据
  172. * <ul>
  173. * <li>如果$expireOnly=true,则将只删除过期的数据。</li>
  174. * <li>如果$expireOnly=false,则将删除所有缓存数据。</li>
  175. * </ul>
  176. *
  177. * @param boolean $expireOnly 如果删除过期数据则设置为true,如果全部缓存都删除则为false,缺省值为true
  178. * @return int
  179. */
  180. public function clear($expireOnly = true) {
  181. $sql = sprintf('DELETE FROM `%s`', $this->getTableName());
  182. if ($expireOnly) {
  183. $sql = sprintf('DELETE FROM `%s` WHERE `%s` < ', $this->getTableName(), $this->expireField) . $this->getConnection()->quote(
  184. time());
  185. }
  186. return $this->getConnection()->execute($sql);
  187. }
  188. /* (non-PHPdoc)
  189. * @see AbstractWindCache::setConfig()
  190. */
  191. public function setConfig($config) {
  192. parent::setConfig($config);
  193. $this->table = $this->getConfig('table-name', '', 'pw_cache', $config);
  194. $this->keyField = $this->getConfig('field-key', '', 'key', $config);
  195. $this->valueField = $this->getConfig('field-value', '', 'value', $config);
  196. $this->expireField = $this->getConfig('field-expire', '', 'expire', $config);
  197. }
  198. /**
  199. * 设置链接对象
  200. *
  201. * @param WindConnection $connection
  202. */
  203. public function setConnection($connection) {
  204. if ($connection instanceof WindConnection) $this->connection = $connection;
  205. }
  206. /**
  207. * 返回缓存表名
  208. *
  209. * @return string
  210. */
  211. private function getTableName() {
  212. return $this->table;
  213. }
  214. /**
  215. * 存储数据
  216. *
  217. * @param string $key 保存的缓存key,
  218. * @param string $value 保存的缓存数据
  219. * @param int $expires 缓存保存的时间,如果为0则永不过期,默认为0
  220. * @param string $type 缓存的保存方式,默认为set将使用replace方式保存
  221. * @return int
  222. */
  223. private function store($key, $value, $expires = 0, $type="set") {
  224. ($expires > 0) ? $expires += time() : $expire = 0;
  225. $db = array($this->keyField => $key, $this->valueField => $value, $this->expireField => $expires);
  226. if ($type == 'add') {
  227. $sql = 'INSERT INTO ' . $this->getTableName() . ' SET ' . $this->getConnection()->sqlSingle($db);
  228. } else {
  229. $sql = 'REPLACE INTO ' . $this->getTableName() . ' SET ' . $this->getConnection()->sqlSingle($db);
  230. }
  231. return $this->getConnection()->createStatement($sql)->update();
  232. }
  233. /**
  234. * 获得链接对象
  235. *
  236. * @return WindConnection
  237. */
  238. private function getConnection() {
  239. return $this->_getConnection();
  240. }
  241. }