1: <?php
  2:   3:   4:   5:   6:   7: 
  8: 
  9: namespace Wei;
 10: 
 11:  12:  13:  14:  15:  16: 
 17: class DbCache extends BaseCache
 18: {
 19:      20:  21:  22:  23: 
 24:     protected $table = 'cache';
 25: 
 26:      27:  28:  29:  30: 
 31:     protected $checkTable = true;
 32: 
 33:      34:  35:  36:  37: 
 38:     protected $checkTableSqls = array(
 39:         'mysql'     => "SHOW TABLES LIKE '%s'",
 40:         'sqlite'    => "SELECT name FROM sqlite_master WHERE type='table' AND name='%s'",
 41:         'pgsql'     => "SELECT true FROM pg_tables WHERE tablename = '%s'"
 42:     );
 43: 
 44:      45:  46:  47:  48: 
 49:     protected $createTableSqls = array(
 50:         'mysql'  => "CREATE TABLE %s (id VARCHAR(255) NOT NULL, value LONGTEXT NOT NULL, expire DATETIME NOT NULL, lastModified DATETIME NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB",
 51:         'sqlite' => "CREATE TABLE %s (id VARCHAR(255) NOT NULL, value CLOB NOT NULL, expire DATETIME NOT NULL, lastModified DATETIME NOT NULL, PRIMARY KEY(id))",
 52:         'pgsql'  => "CREATE TABLE %s (id VARCHAR(255) NOT NULL, value TEXT NOT NULL, expire TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, lastModified TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))",
 53:     );
 54: 
 55:      56:  57:  58:  59: 
 60:     public function __construct(array $options = array())
 61:     {
 62:         parent::__construct($options);
 63:         $this->prepareTable();
 64:     }
 65: 
 66:      67:  68: 
 69:     public function prepareTable()
 70:     {
 71:         $driver = $this->db->getDriver();
 72:         $tableExistsSql = sprintf($this->checkTableSqls[$driver], $this->table);
 73:         if ($this->checkTable && !$this->db->fetchColumn($tableExistsSql)) {
 74:             $createTableSql = sprintf($this->createTableSqls[$driver], $this->table);
 75:             $this->db->executeUpdate($createTableSql);
 76:         }
 77:     }
 78: 
 79:      80:  81: 
 82:     public function get($key, $expire = null, $fn = null)
 83:     {
 84:         if ($this->exists($key)) {
 85:             $result = $this->db->select($this->table, $this->namespace . $key);
 86:             $result = unserialize($result['value']);
 87:         } else {
 88:             $result = false;
 89:         }
 90:         return $this->processGetResult($key, $result, $expire, $fn);
 91:     }
 92: 
 93:      94:  95: 
 96:     public function set($key, $value, $expire = 0)
 97:     {
 98:         $data = array(
 99:             'value' => serialize($value),
100:             'lastModified' => date('Y-m-d H:i:s'),
101:             'expire' => date('Y-m-d H:i:s', $expire ? time() + $expire : 2147483647)
102:         );
103:         $identifier = array(
104:             'id' => $this->namespace . $key
105:         );
106: 
107:         if ($this->exists($key)) {
108:             
109:             
110:             $result = $this->db->update($this->table, $data, $identifier) || '0000' == $this->db->errorCode();
111:         } else {
112:             $result = $this->db->insert($this->table, $data + $identifier);
113:         }
114:         return (bool)$result;
115:     }
116: 
117:     118: 119: 
120:     public function remove($key)
121:     {
122:         return (bool)$this->db->delete($this->table, array('id' => $this->namespace . $key));
123:     }
124: 
125:     126: 127: 
128:     public function exists($key)
129:     {
130:         $result = $this->db->select($this->table, $this->namespace . $key);
131: 
132:         if (!$result) {
133:             return false;
134:         }
135:         if ($result['expire'] < date('Y-m-d H:i:s')) {
136:             $this->remove($key);
137:             return false;
138:         }
139: 
140:         return true;
141:     }
142: 
143:     144: 145: 
146:     public function add($key, $value, $expire = 0)
147:     {
148:         if ($this->exists($key)) {
149:             return false;
150:         } else {
151:             return $this->set($key, $value, $expire);
152:         }
153:     }
154: 
155:     156: 157: 
158:     public function replace($key, $value, $expire = 0)
159:     {
160:         if (!$this->exists($key)) {
161:             return false;
162:         } else {
163:             return $this->set($key, $value, $expire);
164:         }
165:     }
166: 
167:     168: 169: 170: 171: 
172:     public function incr($key, $offset = 1)
173:     {
174:         $value = $this->get($key) + $offset;
175:         return $this->set($key, $value) ? $value : false;
176:     }
177: 
178:     179: 180: 
181:     public function clear()
182:     {
183:         return (bool)$this->db->executeUpdate("DELETE FROM {$this->table}");
184:     }
185: }
186: