/ lib / db.php
db.php
  1  <?php
  2  // generic db functions
  3  require_once 'config/config_db.php';
  4  require_once 'lib/util.php';
  5  
  6  // define the error message strings in case this wasn't used in a file that
  7  // uses the full yotsuba_config system...
  8  if(!defined('S_SQLCONF')) {
  9  	define('S_SQLCONF', 'MySQL connection error');
 10  	define('S_SQLDBSF', 'MySQL database error');
 11  }
 12  
 13  //paranoid since i don't know when it fails, when it does fail
 14  function mysql_try_connect($host,$usr,$pass,$db,$pconnect=true) {
 15  	global $mysql_connect_opts;
 16  	$tries = 1;
 17  
 18  	do {
 19  		$con = $pconnect ? @mysql_pconnect($host,$usr,$pass,$mysql_connect_opts) : @mysql_connect($host,$usr,$pass,1,$mysql_connect_opts);
 20  		$failed = 1; $pconnect = false;
 21  
 22  		if ($con) {
 23  			if (mysql_select_db($db, $con)) {
 24  				$failed = 0;
 25  			}
 26  		}
 27  	} while ($failed && $tries--);
 28  
 29  	if ($failed)
 30  		mysql_internal_err(NULL, "while connecting to $host", "", true);
 31  
 32  	return $con;
 33  }
 34  
 35  function mysql_internal_close($con) {
 36  	mysql_query("UNLOCK TABLES", $con);
 37  	mysql_close($con);
 38  }
 39  
 40  function mysql_board_lock($local=false) {
 41  	global $board_lock_level, $con;
 42  
 43  	if ($board_lock_level > 0) {
 44  		mysql_internal_err($con, "recursively locked table", "lock tables ".BOARD_DIR);
 45  		return;
 46  	}
 47  
 48  	$board_lock_level++;
 49  
 50  	mysql_query("lock tables ".BOARD_DIR." read".($local ? " local" : ""), $con);
 51  }
 52  
 53  function mysql_board_unlock($ignore_error=false) {
 54  	global $board_lock_level, $con;
 55  
 56  	if ($board_lock_level == 0) {
 57  		if (!$ignore_error)
 58  			mysql_internal_err($con, "not already locked", "unlock tables");
 59  		return;
 60  	}
 61  
 62  	$board_lock_level--;
 63  	mysql_query("unlock tables", $con);
 64  }
 65  
 66  function mysql_clear_locks() {
 67  	mysql_board_unlock(true);
 68  }
 69  
 70  function mysql_global_connect($pconnect=true) {
 71  	global $gcon;
 72  	$gcon = mysql_try_connect(SQLHOST_GLOBAL, SQLUSER_GLOBAL, SQLPASS_GLOBAL, SQLDB_GLOBAL, $pconnect);
 73  	return $gcon;
 74  }
 75  
 76  // assumes BOARD_DIR is set
 77  function mysql_check_connections() {
 78  	global $gcon, $con;
 79  
 80  	$gcon_res = mysql_ping($gcon);
 81  	$con_res = mysql_ping($con);
 82  
 83  	if ($gcon_res == false || $con_res == false) {
 84  		mysql_internal_close($con);
 85  		mysql_internal_close($gcon);
 86  		$con = null;
 87  		$gcon = null;
 88  		mysql_board_connect(BOARD_DIR, false);
 89  		mysql_global_connect(false);
 90  	}
 91  }
 92  
 93  //really bad error system...
 94  function mysql_internal_err($conn, $priverr, $query="", $die=false) {
 95  	global $mysql_never_die;
 96  	global $mysql_suppress_err;
 97  		
 98  	$err = sprintf("%s error: %s - %d - %s%s", $query ? "query" : "connection",
 99  					$priverr, mysql_errno($conn), mysql_error($conn), $query ? " query: $query" : "");
100  
101      if (SQL_DEBUG && ini_get('display_errors')) echo $err."\n";
102  
103  	internal_error_log("SQL", $err);
104  
105  	if ($die && !$mysql_never_die) die($query ? S_SQLDBSF : S_SQLCONF);
106  }
107  
108  //pconnect - call _pconnect, not safe if tables are locked
109  function mysql_board_connect($board="", $pconnect=true) {
110  	global $con;
111  	global $did_add_lockfunc;
112  
113  	if (!defined('SQLHOST')) {
114  		$db = 1; // db is always 1 now
115  		$host = "db-ena.int"; // and always "db-ena" (this should never happen because we define SQLHOST)
116  		$db = "img$db";
117  
118  		define('SQLHOST', $host);
119  		define('SQLDB', $db);
120  		if ($board) define('BOARD_DIR', $board);
121  	} else {
122  		$host = SQLHOST;
123  		$db = SQLDB;
124  	}
125  
126  	$con = mysql_try_connect($host, SQLUSER, SQLPASS, $db, $pconnect);
127      //if (SQL_DEBUG && ini_get('display_errors')) echo "connected to ".$host." SQLHOST is ".SQLHOST."\n";
128  	
129  	if (!$did_add_lockfunc) {
130  		$did_add_lockfunc = 1;
131  		register_shutdown_function("mysql_clear_locks");
132  	}
133  	return $con;
134  }
135  
136  function mysql_do_query($query, $con) {
137  	global $mysql_unbuffered_reads;
138  	global $mysql_suppress_err;
139  	global $mysql_query_log;
140  	global $mysql_debug_buf;
141  	static $querylog_fd;
142  	
143  	$querylog = (defined('QUERY_LOG') && constant('QUERY_LOG')) || $mysql_query_log == true;
144  	$is_select = stripos($query, "SELECT")===0;
145  
146  	$time = 0;
147  	if ($querylog) {
148  		$time = microtime(true);
149  		
150  		if (!$querylog_fd) {
151  			$querylog_fd = fopen("/www/perhost/querylog.log", "a");
152  			flock($querylog_fd, LOCK_EX);
153  		}
154  	
155  		fprintf($querylog_fd, "%d query: %s\n", getmypid(), $query);
156  	}
157  
158  	if ($mysql_unbuffered_reads)
159  		$ret = @mysql_unbuffered_query($query, $con);
160  	else
161  		$ret = @mysql_query($query, $con);
162  
163  	if ($ret && $querylog) {
164  		$elapsed = microtime(true) - $time;
165  
166  		if (!$mysql_unbuffered_reads) {
167  			$nr = @mysql_num_rows($ret);
168  			if (!$nr) $nr = @mysql_affected_rows($ret);
169  		} else
170  			$nr = "?";
171  
172  		fprintf($querylog_fd, "%d rows, %f sec\n", $nr, $elapsed);
173  	}
174  	
175  	if (isset($mysql_debug_buf)) {
176  		if (!$mysql_unbuffered_reads) {
177  			$nr = @mysql_num_rows($ret);
178  			if (!$nr) $nr = @mysql_affected_rows($ret);
179  			if (!$nr) $nr = 0;
180  		} else
181  			$nr = "?";
182  			
183  		$mysql_debug_buf .= "Query: $query\nRows: $nr\n";
184  	}
185  
186  	if ($ret === FALSE) {
187  		mysql_internal_err($con, "in do_query", $query);
188  	}
189  
190  	return $ret;
191  }
192  
193  function try_escape_string($string, $con, $recon_func, $tries=0)
194  {
195  	$res = mysql_real_escape_string($string, $con);
196  
197  	if ($res === FALSE) {
198  		mysql_internal_err($con, "in escape_string", $string, $tries == 0);
199  	}
200  
201  	return $res;
202  }
203  
204  //note for use of db query functions
205  //old-style calls (escaping done manually beforehand)
206  //must connect manually too
207  
208  //for read queries
209  function mysql_global_call() {
210  	global $gcon;
211  	if(!$gcon) mysql_global_connect();
212  	$args = func_get_args();
213  	$format = array_shift($args);
214  
215  	if (count($args)) {
216  		foreach($args as &$arg)
217  			$arg = try_escape_string($arg, $gcon, "mysql_global_connect" );
218  		$query = vsprintf($format, $args);
219  	} else $query = $format;
220  
221  	return mysql_do_query( $query, $gcon );
222  }
223  
224  function mysql_global_error() {
225  	global $gcon;
226  	if(!$gcon) mysql_global_connect();
227  	
228  	return mysql_error($gcon);
229  }
230  
231  //for r/w queries (historical, doesn't actually matter)
232  //TODO: remove
233  function mysql_global_do() {
234  	global $gcon;
235  	if(!$gcon) mysql_global_connect();
236  	$args = func_get_args();
237  	$format = array_shift($args);
238  
239  	if (count($args)) {
240  		foreach($args as &$arg)
241  			$arg = try_escape_string($arg, $gcon, "mysql_global_connect" );
242  		$query = vsprintf($format, $args);
243  	} else $query = $format;
244  
245  	return mysql_do_query( $query, $gcon );
246  }
247  
248  function mysql_global_insert_id() {
249  	global $gcon;
250  	return mysql_insert_id($gcon);
251  }
252  
253  function mysql_board_call() {
254  	global $con;
255  	if (!$con) mysql_board_connect();
256  	$args = func_get_args();
257  	$format = array_shift($args);
258  
259  	if (count($args)) {
260  		foreach($args as &$arg)
261  			$arg = mysql_real_escape_string($arg, $con);
262  		$query = vsprintf($format, $args);
263  	} else $query = $format;
264  
265  	return mysql_do_query( $query, $con );
266  }
267  
268  function mysql_global_escape($string) {
269  	global $gcon;
270  	if(!$gcon) mysql_global_connect();
271  
272  	return mysql_real_escape_string($string, $gcon);
273  }
274  
275  function mysql_board_error() {
276  	global $con;
277  	if(!$con) mysql_board_connect();
278  	
279  	return mysql_error($con);
280  }
281  
282  function mysql_board_escape($string) {
283  	global $con;
284  	if (!$con) mysql_board_connect();
285  
286  	return mysql_real_escape_string($string, $con);
287  }
288  
289  function mysql_board_get_post($board,$no) {
290  	global $con;
291  	mysql_board_connect($board);
292  	$query = mysql_board_call("SELECT HIGH_PRIORITY * from `%s` WHERE no=%d",$board,$no);
293  	$array = mysql_fetch_assoc($query);
294  	mysql_close($con);
295  	$con = NULL;
296  	return $array;
297  }
298  
299  function mysql_board_get_post_lazy( $board, $no )
300  {
301  	global $con;
302  	mysql_board_connect($board);
303  	$query = mysql_board_call("SELECT * from `%s` WHERE no=%d",$board,$no);
304  	$array = mysql_fetch_assoc($query);
305  	mysql_close($con);
306  	$con = NULL;
307  	return $array;
308  }
309  
310  function mysql_board_insert_id() {
311  	global $con;
312  	return mysql_insert_id($con);
313  }
314  
315  function mysql_global_row($table, $col, $val)
316  {
317  	$q = mysql_global_call("select * from `%s` where $col='%s'", $table, $val);
318  	$r = mysql_fetch_assoc($q);
319  	mysql_free_result($q);
320  	return $r;
321  }
322  
323  function mysql_board_row($table, $col, $val)
324  {
325  	$q = mysql_board_call("select * from `%s` where $col='%s'", $table, $val);
326  	$r = mysql_fetch_assoc($q);
327  	mysql_free_result($q);
328  	return $r;
329  }
330  
331  // answer must be one column
332  function mysql_column_array($q) {
333  	$ret = array();
334  	while ($row = mysql_fetch_row($q))
335  		$ret[] = $row[0];
336  	return $ret;
337  }
338  
339  // turn "" into NULL
340  // incompatible with escaping :(
341  function mysql_nullify($s) {
342  	return ($s || $s === '0') ? "'$s'" : "''"; //"NULL";
343  }
344  
345  ?>