]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - classes/Memcached_DataObject.php
Make replies to @#
[quix0rs-gnu-social.git] / classes / Memcached_DataObject.php
1 <?php
2 /*
3  * Laconica - a distributed open-source microblogging tool
4  * Copyright (C) 2008, Controlez-Vous, Inc.
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 if (!defined('LACONICA')) { exit(1); }
21
22 require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
23
24 class Memcached_DataObject extends DB_DataObject 
25 {
26     function &staticGet($cls, $k, $v=NULL) {
27                 if (is_null($v)) {
28                         $v = $k;
29                         # XXX: HACK!
30                         $i = new $cls;
31                         $keys = $i->keys();
32                         $k = $keys[0];
33                         unset($i);
34                 }
35                 $i = Memcached_DataObject::getcached($cls, $k, $v);
36                 if ($i) {
37                         return $i;
38                 } else {
39                         $i = DB_DataObject::staticGet($cls, $k, $v);
40                         if ($i) {
41                                 $i->encache();
42                         }
43                         return $i;
44                 }
45         }
46
47         function &pkeyGet($cls, $kv) {
48                 $i = Memcached_DataObject::multicache($cls, $kv);
49                 if ($i) {
50                         return $i;
51                 } else {
52                         $i = new $cls();
53                         foreach ($kv as $k => $v) {
54                                 $i->$k = $v;
55                         }
56                         if ($i->find(true)) {
57                                 $i->encache();
58                                 return $i;
59                         } else {
60                                 return NULL;
61                         }
62                 }
63         }
64
65         function insert() {
66                 $result = parent::insert();
67                 return $result;
68         }
69         
70         function update($orig=NULL) {
71                 if (is_object($orig) && $orig instanceof Memcached_DataObject) {
72                         $orig->decache(); # might be different keys
73                 }
74                 $result = parent::update($orig);
75                 if ($result) {
76                         $this->encache();
77                 }
78                 return $result;
79         }
80         
81         function delete() {
82                 $this->decache(); # while we still have the values!
83                 return parent::delete();
84         }
85         
86         static function memcache() {
87                 return common_memcache();
88         }
89         
90         static function cacheKey($cls, $k, $v) {
91                 return common_cache_key(strtolower($cls).':'.$k.':'.$v);
92         }
93         
94         static function getcached($cls, $k, $v) {
95                 $c = Memcached_DataObject::memcache();
96                 if (!$c) {
97                         return false;
98                 } else {
99                         return $c->get(Memcached_DataObject::cacheKey($cls, $k, $v));
100                 }
101         }
102
103         function keyTypes() {
104                 global $_DB_DATAOBJECT;
105         if (!isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"])) {
106                         $this->databaseStructure();
107
108         }
109                 return $_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"];
110         }
111         
112         function encache() {
113                 $c = $this->memcache();
114                 if (!$c) {
115                         return false;
116                 } else {
117                         $pkey = array();
118                         $pval = array();                        
119                         $types = $this->keyTypes();
120                         ksort($types);
121                         foreach ($types as $key => $type) {
122                                 if ($type == 'K') {
123                                         $pkey[] = $key;
124                                         $pval[] = $this->$key;
125                                 } else {
126                                         $c->set($this->cacheKey($this->tableName(), $key, $this->$key), $this);
127                                 }
128                         }
129                         # XXX: should work for both compound and scalar pkeys
130                         $pvals = implode(',', $pval);
131                         $pkeys = implode(',', $pkey);
132                         $c->set($this->cacheKey($this->tableName(), $pkeys, $pvals), $this);
133                 }
134         }
135         
136         function decache() {
137                 $c = $this->memcache();
138                 if (!$c) {
139                         return false;
140                 } else {
141                         $pkey = array();
142                         $pval = array();                        
143                         $types = $this->keyTypes();
144                         ksort($types);
145                         foreach ($types as $key => $type) {
146                                 if ($type == 'K') {
147                                         $pkey[] = $key;
148                                         $pval[] = $this->$key;
149                                 } else {
150                                         $c->delete($this->cacheKey($this->tableName(), $key, $this->$key));
151                                 }
152                         }
153                         # should work for both compound and scalar pkeys
154                         # XXX: comma works for now but may not be safe separator for future keys
155                         $pvals = implode(',', $pval);
156                         $pkeys = implode(',', $pkey);
157                         $c->delete($this->cacheKey($this->tableName(), $pkeys, $pvals));
158                 }
159         }
160
161         function multicache($cls, $kv) {
162                 ksort($kv);
163                 $c = Memcached_DataObject::memcache();
164                 if (!$c) {
165                         return false;
166                 } else {
167                         $pkeys = implode(',', array_keys($kv));
168                         $pvals = implode(',', array_values($kv));
169                         return $c->get(Memcached_DataObject::cacheKey($cls, $pkeys, $pvals));
170                 }
171         }
172
173     function getSearchEngine($table) {
174         require_once INSTALLDIR.'/lib/search_engines.php';
175         static $search_engine;
176         if (!isset($search_engine)) {
177                 $connected = false;
178                 if (common_config('sphinx', 'enabled')) {
179                     $search_engine = new SphinxSearch($this, $table);
180                     $connected = $search_engine->is_connected();
181                 }
182
183                 // unable to connect to sphinx' search daemon
184                 if (!$connected) {
185                     if ('mysql' === common_config('db', 'type')) {
186                         $search_engine = new MySQLSearch($this, $table);
187                     } else {
188                         $search_engine = new PGSearch($this, $table);
189                     }
190                 }
191         }
192         return $search_engine;
193     }
194 }