]> git.mxchange.org Git - friendica.git/blob - library/spam/b8/storage/storage_mysql.php
Merge remote branch 'upstream/master'
[friendica.git] / library / spam / b8 / storage / storage_mysql.php
1 <?php
2
3 #   Copyright (C) 2006-2011 Tobias Leupold <tobias.leupold@web.de>
4 #
5 #   This file is part of the b8 package
6 #
7 #   This program is free software; you can redistribute it and/or modify it
8 #   under the terms of the GNU Lesser General Public License as published by
9 #   the Free Software Foundation in version 2.1 of the License.
10 #
11 #   This program is distributed in the hope that it will be useful, but
12 #   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 #   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14 #   License for more details.
15 #
16 #   You should have received a copy of the GNU Lesser General Public License
17 #   along with this program; if not, write to the Free Software Foundation,
18 #   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
19
20 /**
21  * The MySQL abstraction layer for communicating with the database.
22  * Copyright (C) 2009 Oliver Lillie (aka buggedcom)
23  * Copyright (C) 2010-2011 Tobias Leupold <tobias.leupold@web.de>
24  *
25  * @license LGPL
26  * @access public
27  * @package b8
28  * @author Oliver Lillie (aka buggedcom) (original PHP 5 port and optimizations)
29  * @author Tobias Leupold
30  */
31
32 class b8_storage_mysql extends b8_storage_base
33 {
34
35         public $config = array(
36                 'database'        => 'b8_wordlist',
37                 'table_name'      => 'b8_wordlist',
38                 'host'            => 'localhost',
39                 'user'            => FALSE,
40                 'pass'            => FALSE,
41                 'connection'      => NULL
42         );
43
44         public $b8_config = array(
45                 'degenerator'     => NULL,
46                 'today'           => NULL
47         );
48
49         private $_connection                   = NULL;
50         private $_deletes                      = array();
51         private $_puts                         = array();
52         private $_updates                      = array();
53
54         const DATABASE_CONNECTION_FAIL         = 'DATABASE_CONNECTION_FAIL';
55         const DATABASE_CONNECTION_ERROR        = 'DATABASE_CONNECTION_ERROR';
56         const DATABASE_CONNECTION_BAD_RESOURCE = 'DATABASE_CONNECTION_BAD_RESOURCE';
57         const DATABASE_SELECT_ERROR            = 'DATABASE_SELECT_ERROR';
58         const DATABASE_TABLE_ACCESS_FAIL       = 'DATABASE_TABLE_ACCESS_FAIL';
59         const DATABASE_WRONG_VERSION           = 'DATABASE_WRONG_VERSION';
60
61         /**
62          * Constructs the database layer.
63          *
64          * @access public
65          * @param string $config
66          */
67
68         function __construct($config, $degenerator, $today)
69         {
70
71                 # Pass some variables of the main b8 config to this class
72                 $this->b8_config['degenerator'] = $degenerator;
73                 $this->b8_config['today']       = $today;
74
75                 # Validate the config items
76
77                 if(count($config) > 0) {
78
79                         foreach ($config as $name => $value) {
80
81                                 switch($name) {
82
83                                         case 'table_name':
84                                         case 'host':
85                                         case 'user':
86                                         case 'pass':
87                                         case 'database':
88                                                 $this->config[$name] = (string) $value;
89                                                 break;
90
91                                         case 'connection':
92
93                                                 if($value !== NULL) {
94
95                                                         if(is_resource($value) === TRUE) {
96                                                                 $resource_type = get_resource_type($value);
97                                                                 $this->config['connection'] = $resource_type !== 'mysql link' && $resource_type !== 'mysql link persistent' ? FALSE : $value;
98                                                         }
99
100                                                         else
101                                                                 $this->config['connection'] = FALSE;
102
103                                                 }
104
105                                                 break;
106
107                                 }
108
109                         }
110
111                 }
112
113         }
114
115         /**
116          * Closes the database connection.
117          *
118          * @access public
119          * @return void
120          */
121
122         function __destruct()
123         {
124
125                 if($this->_connection === NULL)
126                         return;
127
128                 # Commit any changes before closing
129                 $this->_commit();
130
131                 # Just close the connection if no link-resource was passed and b8 created it's own connection
132                 if($this->config['connection'] === NULL)
133                         mysql_close($this->_connection);
134
135                 $this->connected = FALSE;
136
137         }
138
139         /**
140          * Connect to the database and do some checks.
141          *
142          * @access public
143          * @return mixed Returns TRUE on a successful database connection, otherwise returns a constant from b8.
144          */
145
146         public function connect()
147         {
148
149                 # Are we already connected?
150                 if($this->connected === TRUE)
151                         return TRUE;
152
153                 # Are we using an existing passed resource?
154                 if($this->config['connection'] === FALSE) {
155                         # ... yes we are, but the connection is not a resource, so return an error
156                         $this->connected = FALSE;
157                         return self::DATABASE_CONNECTION_BAD_RESOURCE;
158                 }
159
160                 elseif($this->config['connection'] === NULL) {
161
162                         # ... no we aren't so we have to connect.
163
164                         if($this->_connection = mysql_connect($this->config['host'], $this->config['user'], $this->config['pass'])) {
165                                 if(mysql_select_db($this->config['database'], $this->_connection) === FALSE) {
166                                         $this->connected = FALSE;
167                                         return self::DATABASE_SELECT_ERROR . ": " . mysql_error();
168                                 }
169                         }
170                         else {
171                                 $this->connected = FALSE;
172                                 return self::DATABASE_CONNECTION_ERROR;
173                         }
174
175                 }
176
177                 else {
178                         # ... yes we are
179                         $this->_connection = $this->config['connection'];
180                 }
181
182                 # Just in case ...
183                 if($this->_connection === NULL) {
184                         $this->connected = FALSE;
185                         return self::DATABASE_CONNECTION_FAIL;
186                 }
187
188                 # Check to see if the wordlist table exists
189                 if(mysql_query('DESCRIBE ' . $this->config['table_name'], $this->_connection) === FALSE) {
190                         $this->connected = FALSE;
191                         return self::DATABASE_TABLE_ACCESS_FAIL . ": " . mysql_error();
192                 }
193
194                 # Everything is okay and connected
195                 $this->connected = TRUE;
196
197                 # Let's see if this is a b8 database and the version is okay
198                 return $this->check_database();
199
200         }
201
202         /**
203          * Does the actual interaction with the database when fetching data.
204          *
205          * @access protected
206          * @param array $tokens
207          * @return mixed Returns an array of the returned data in the format array(token => data) or an empty array if there was no data.
208          */
209
210         protected function _get_query($tokens)
211         {
212
213                 # Construct the query ...
214
215                 if(count($tokens) > 0) {
216
217                         $where = array();
218
219                         foreach ($tokens as $token) {
220                                 $token = mysql_real_escape_string($token, $this->_connection);
221                                 array_push($where, $token);
222                         }
223
224                         $where = 'token IN ("' . implode('", "', $where) . '")';
225                 }
226
227                 else {
228                         $token = mysql_real_escape_string($token, $this->_connection);
229                         $where = 'token = "' . $token . '"';
230                 }
231
232                 # ... and fetch the data
233
234                 $result = mysql_query('
235                         SELECT token, count
236                         FROM ' . $this->config['table_name'] . '
237                         WHERE ' . $where . ';
238                 ', $this->_connection);
239
240                 $data = array();
241
242                 while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
243                         $data[$row['token']] = $row['count'];
244
245                 mysql_free_result($result);
246
247                 return $data;
248
249         }
250
251         /**
252          * Store a token to the database.
253          *
254          * @access protected
255          * @param string $token
256          * @param string $count
257          * @return void
258          */
259
260         protected function _put($token, $count) {
261                 $token = mysql_real_escape_string($token, $this->_connection);
262                 $count = mysql_real_escape_string($count, $this->_connection);;
263                 array_push($this->_puts, '("' . $token . '", "' . $count . '")');
264         }
265
266         /**
267          * Update an existing token.
268          *
269          * @access protected
270          * @param string $token
271          * @param string $count
272          * @return void
273          */
274
275         protected function _update($token, $count)
276         {
277                 $token = mysql_real_escape_string($token, $this->_connection);
278                 $count = mysql_real_escape_string($count, $this->_connection);
279                 array_push($this->_updates, '("' . $token . '", "' . $count . '")');
280         }
281
282         /**
283          * Remove a token from the database.
284          *
285          * @access protected
286          * @param string $token
287          * @return void
288          */
289
290         protected function _del($token)
291         {
292                 $token = mysql_real_escape_string($token, $this->_connection);
293                 array_push($this->_deletes, $token);
294         }
295
296         /**
297          * Commits any modification queries.
298          *
299          * @access protected
300          * @return void
301          */
302
303         protected function _commit()
304         {
305
306                 if(count($this->_deletes) > 0) {
307
308                         $result = mysql_query('
309                                 DELETE FROM ' . $this->config['table_name'] . '
310                                 WHERE token IN ("' . implode('", "', $this->_deletes) . '");
311                         ', $this->_connection);
312
313                         if(is_resource($result) === TRUE)
314                                 mysql_free_result($result);
315
316                         $this->_deletes = array();
317
318                 }
319
320                 if(count($this->_puts) > 0) {
321
322                         $result = mysql_query('
323                                 INSERT INTO ' . $this->config['table_name'] . '(token, count)
324                                 VALUES ' . implode(', ', $this->_puts) . ';', $this->_connection);
325
326                         if(is_resource($result) === TRUE)
327                                 mysql_free_result($result);
328
329                         $this->_puts = array();
330
331                 }
332
333                 if(count($this->_updates) > 0) {
334
335                         $result = mysql_query('
336                                 INSERT INTO ' . $this->config['table_name'] . '(token, count)
337                                 VALUES ' . implode(', ', $this->_updates) . '
338                                 ON DUPLICATE KEY UPDATE ' . $this->config['table_name'] . '.count = VALUES(count);', $this->_connection);
339
340                         if(is_resource($result) === TRUE)
341                                 mysql_free_result($result);
342
343                         $this->_updates = array();
344
345                 }
346
347         }
348
349 }
350
351 ?>