]> git.mxchange.org Git - friendica.git/blob - include/dba.php
Merge remote branch 'upstream/master'
[friendica.git] / include / dba.php
1 <?php
2
3 require_once('include/datetime.php');
4
5 /**
6  *
7  * MySQL database class
8  *
9  * For debugging, insert 'dbg(1);' anywhere in the program flow.
10  * dbg(0); will turn it off. Logging is performed at LOGGER_DATA level.
11  * When logging, all binary info is converted to text and html entities are escaped so that 
12  * the debugging stream is safe to view within both terminals and web pages.
13  *
14  */
15  
16 if(! class_exists('dba')) { 
17 class dba {
18
19         private $debug = 0;
20         private $db;
21         public  $mysqli = true;
22         public  $connected = false;
23         public  $error = false;
24
25         function __construct($server,$user,$pass,$db,$install = false) {
26
27                 $server = trim($server);
28                 $user = trim($user);
29                 $pass = trim($pass);
30                 $db = trim($db);
31
32                 if (!(strlen($server) && strlen($user))){
33                         $this->connected = false;
34                         $this->db = null;
35                         return;
36                 }
37
38                 if($install) {
39                         if(strlen($server) && ($server !== 'localhost') && ($server !== '127.0.0.1')) {
40                                 if(! dns_get_record($server, DNS_A + DNS_CNAME + DNS_PTR)) {
41                                         $this->error = sprintf( t('Cannot locate DNS info for database server \'%s\''), $server);
42                                         $this->connected = false;
43                                         $this->db = null;
44                                         return;
45                                 }
46                         }
47                 }
48
49                 if(class_exists('mysqli')) {
50                         $this->db = @new mysqli($server,$user,$pass,$db);
51                         if(! mysqli_connect_errno()) {
52                                 $this->connected = true;
53                         }
54                 }
55                 else {
56                         $this->mysqli = false;
57                         $this->db = mysql_connect($server,$user,$pass);
58                         if($this->db && mysql_select_db($db,$this->db)) {
59                                 $this->connected = true;
60                         }
61                 }
62                 if(! $this->connected) {
63                         $this->db = null;
64                         if(! $install)
65                                 system_unavailable();
66                 }
67         }
68
69         public function getdb() {
70                 return $this->db;
71         }
72
73         public function q($sql) {
74
75                 if((! $this->db) || (! $this->connected))
76                         return false;
77
78                 $this->error = '';
79
80                 //@file_put_contents("/tmp/friendica-db.log", datetime_convert().':'.session_id(). ' Start '.$sql."\n", FILE_APPEND);
81
82                 if($this->mysqli)
83                         $result = @$this->db->query($sql);
84                 else
85                         $result = @mysql_query($sql,$this->db);
86
87                 //@file_put_contents("/tmp/friendica-db.log", datetime_convert().':'.session_id(). ' Stop '."\n", FILE_APPEND);
88
89                 if($this->mysqli) {
90                         if($this->db->errno)
91                                 $this->error = $this->db->error;
92                 }
93                 elseif(mysql_errno($this->db))
94                                 $this->error = mysql_error($this->db);
95
96                 if(strlen($this->error)) {
97                         logger('dba: ' . $this->error);
98                 }
99
100                 if($this->debug) {
101
102                         $mesg = '';
103
104                         if($result === false)
105                                 $mesg = 'false';
106                         elseif($result === true)
107                                 $mesg = 'true';
108                         else {
109                                 if($this->mysqli)
110                                         $mesg = $result->num_rows . ' results' . EOL;
111                         else
112                                         $mesg = mysql_num_rows($result) . ' results' . EOL;
113                         }
114
115                         $str =  'SQL = ' . printable($sql) . EOL . 'SQL returned ' . $mesg
116                                 . (($this->error) ? ' error: ' . $this->error : '')
117                                 . EOL;
118
119                         logger('dba: ' . $str );
120                 }
121
122                 /**
123                  * If dbfail.out exists, we will write any failed calls directly to it,
124                  * regardless of any logging that may or may nor be in effect.
125                  * These usually indicate SQL syntax errors that need to be resolved.
126                  */
127
128                 if($result === false) {
129                         logger('dba: ' . printable($sql) . ' returned false.' . "\n" . $this->error);
130                         if(file_exists('dbfail.out'))
131                                 file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . ' returned false' . "\n" . $this->error . "\n", FILE_APPEND);
132                 }
133
134                 if(($result === true) || ($result === false))
135                         return $result;
136
137                 $r = array();
138                 if($this->mysqli) {
139                         if($result->num_rows) {
140                                 while($x = $result->fetch_array(MYSQLI_ASSOC))
141                                         $r[] = $x;
142                                 $result->free_result();
143                         }
144                 }
145                 else {
146                         if(mysql_num_rows($result)) {
147                                 while($x = mysql_fetch_array($result, MYSQL_ASSOC))
148                                         $r[] = $x;
149                                 mysql_free_result($result);
150                         }
151                 }
152
153
154                 if($this->debug)
155                         logger('dba: ' . printable(print_r($r, true)));
156                 return($r);
157         }
158
159         public function dbg($dbg) {
160                 $this->debug = $dbg;
161         }
162
163         public function escape($str) {
164                 if($this->db && $this->connected) {
165                         if($this->mysqli)
166                                 return @$this->db->real_escape_string($str);
167                         else
168                                 return @mysql_real_escape_string($str,$this->db);
169                 }
170         }
171
172         function __destruct() {
173                 if ($this->db) 
174                         if($this->mysqli)
175                                 $this->db->close();
176                         else
177                                 mysql_close($this->db);
178         }
179 }}
180
181 if(! function_exists('printable')) {
182 function printable($s) {
183         $s = preg_replace("~([\x01-\x08\x0E-\x0F\x10-\x1F\x7F-\xFF])~",".", $s);
184         $s = str_replace("\x00",'.',$s);
185         if(x($_SERVER,'SERVER_NAME'))
186                 $s = escape_tags($s);
187         return $s;
188 }}
189
190 // Procedural functions
191 if(! function_exists('dbg')) { 
192 function dbg($state) {
193         global $db;
194         if($db)
195         $db->dbg($state);
196 }}
197
198 if(! function_exists('dbesc')) { 
199 function dbesc($str) {
200         global $db;
201         if($db && $db->connected)
202                 return($db->escape($str));
203         else
204                 return(str_replace("'","\\'",$str));
205 }}
206
207
208
209 // Function: q($sql,$args);
210 // Description: execute SQL query with printf style args.
211 // Example: $r = q("SELECT * FROM `%s` WHERE `uid` = %d",
212 //                   'user', 1);
213
214 if(! function_exists('q')) { 
215 function q($sql) {
216
217         global $db;
218         $args = func_get_args();
219         unset($args[0]);
220
221         if($db && $db->connected) {
222                 $stmt = vsprintf($sql,$args);
223                 if($stmt === false)
224                         logger('dba: vsprintf error: ' . print_r(debug_backtrace(),true));
225                 return $db->q($stmt);
226         }
227
228         /**
229          *
230          * This will happen occasionally trying to store the 
231          * session data after abnormal program termination 
232          *
233          */
234         logger('dba: no database: ' . print_r($args,true));
235         return false; 
236
237 }}
238
239 /**
240  *
241  * Raw db query, no arguments
242  *
243  */
244
245 if(! function_exists('dbq')) { 
246 function dbq($sql) {
247
248         global $db;
249         if($db && $db->connected)
250                 $ret = $db->q($sql);
251         else
252                 $ret = false;
253         return $ret;
254 }}
255
256
257 // Caller is responsible for ensuring that any integer arguments to 
258 // dbesc_array are actually integers and not malformed strings containing
259 // SQL injection vectors. All integer array elements should be specifically 
260 // cast to int to avoid trouble. 
261
262
263 if(! function_exists('dbesc_array_cb')) {
264 function dbesc_array_cb(&$item, $key) {
265         if(is_string($item))
266                 $item = dbesc($item);
267 }}
268
269
270 if(! function_exists('dbesc_array')) {
271 function dbesc_array(&$arr) {
272         if(is_array($arr) && count($arr)) {
273                 array_walk($arr,'dbesc_array_cb');
274         }
275 }}