PageRenderTime 48ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/core/utils/MySql.php

https://github.com/amanai/next24
PHP | 374 lines | 288 code | 59 blank | 27 comment | 73 complexity | df5d605e84784ce49dd2509850e4bef7 MD5 | raw file
  1. <?php
  2. class MySql
  3. {
  4. static public $logFile = null;
  5. static public $defaultLink = null;
  6. static public function initDb(){
  7. self::$defaultLink = self::connect(DB_SERVERNAME, DB_USERNAME, DB_PASS);
  8. self::select_db(DB_NAME);
  9. $sql = 'SET NAMES "utf8"';
  10. self::query($sql);
  11. }
  12. static public function logError($code, $error)
  13. {
  14. if (self::$logFile === null)
  15. return;
  16. $f = @fopen(self::$logFile, "a");
  17. if (!$f)
  18. return;
  19. $d = date("Y-m-d H:i:s");
  20. $b = array_slice(debug_backtrace(), 1);
  21. $trace = "";
  22. foreach ($b as $k=>$place)
  23. $trace .= " {$place["file"]}, line {$place["line"]}: {$place["function"]}\n";
  24. $url = "";
  25. if (isset($_SERVER['REQUEST_URI']))
  26. $url = $_SERVER['REQUEST_URI']."\n";
  27. $st = "";
  28. if (isset($_SERVER['REQUEST_TIME']))
  29. $st = "\nrequest time: ".date("Y-m-d H:i:s", $_SERVER['REQUEST_TIME'])."\n";
  30. fwrite($f, "{$d}{$st} {$error}\n{$trace}{$url}{$code}\n\n");
  31. fclose($f);
  32. }
  33. /**
  34. * Wrapper for mysql_query, to extend it with logging abilities
  35. *
  36. * @param string $sql
  37. * @param resource $link
  38. * @param array $handledCodes 2DO! which mysql error codes are handled by caller, and
  39. * therefore shouldnt be written to log
  40. * @param int $timeThreshold 2DO! all queries taking longer than this value (sec) are written
  41. * to error log. 0 for no limit.
  42. * @return resource
  43. */
  44. static public function query($sql, $link = null, $handledCodes = array(), &$retCode = null, $timeThreshold = 10)
  45. {
  46. if ($link === null)
  47. $link = self::$defaultLink;
  48. $res = Mysql::_query($sql, $link);
  49. $n = Mysql::errno($link);
  50. if ($n)
  51. $e = Mysql::error($link);
  52. // if not handled by application, try handling (just exception, to prevent further processing):
  53. // 2002 Can't connect to local MySQL server through socket '%s' (%d)
  54. // 2003 Can't connect to MySQL server on '%s' (%d)
  55. if (($n == 2002 || $n == 2003) && !in_array($n, $handledCodes))
  56. {
  57. Mysql::logError($n, $e);
  58. throw new Exception("Mysql: unable to connect");
  59. }
  60. // if not handled by application, try handling (autoreconnect):
  61. // 2006 Mysql server has gone away
  62. // 2013 Lost connection during query
  63. if (($n == 2006 || $n == 2013) && !in_array($n, $handledCodes))
  64. {
  65. if (!Mysql::ping($link))
  66. {
  67. $e = Mysql::error($link);
  68. Mysql::logError($sql, "{$n}: {$e} // ping reconnect failed");
  69. throw new Exception("Mysql: connection lost, ping reconnect failed");
  70. }
  71. $res = Mysql::_query($sql, $link);
  72. $n = Mysql::errno($link);
  73. if ($n)
  74. $e = Mysql::error($link)." // after ping reconnect";
  75. }
  76. // if not handled by application, try handling (just retry query):
  77. // 1205 Lock wait timeout
  78. if ($n == 1205 && !in_array($n, $handledCodes))
  79. if (isset($_SERVER['REQUEST_TIME']) && $_SERVER['REQUEST_TIME'] > time() - 1)
  80. {
  81. $res = Mysql::_query($sql, $link);
  82. $n = Mysql::errno($link);
  83. if ($n)
  84. $e = Mysql::error($link)." // after retry";
  85. }
  86. if ($n && !in_array($n, $handledCodes))
  87. {
  88. //$e = Mysql::error($link);
  89. Mysql::logError($sql, "{$n}: {$e}");
  90. }
  91. else if (func_num_args() >= 4)
  92. $retCode = $n;
  93. return $res;
  94. }
  95. static function query_row($sql, $link = null)
  96. {
  97. if ($link === null)
  98. $link = self::$defaultLink;
  99. $ret = array();
  100. $res = Mysql::query($sql, $link);
  101. if (!empty($res)){
  102. if ($r = mysql_fetch_assoc($res)){
  103. $ret = $r;
  104. }
  105. mysql_free_result($res);
  106. }
  107. return $ret;
  108. }
  109. static function query_array($sql, $index_by = '', $link = null)
  110. {
  111. if ($link === null)
  112. $link = self::$defaultLink;
  113. $ret = array();
  114. $res = Mysql::query($sql, $link);
  115. if (!empty($res)){
  116. while($r = mysql_fetch_assoc($res)){
  117. if ($index_by == ''){
  118. $ret[] = $r;
  119. }else{
  120. $ret[$r[$index_by]] = $r;
  121. }
  122. }
  123. mysql_free_result($res);
  124. }
  125. return $ret;
  126. }
  127. static function insert_array($table_name, $arr, $link = null)
  128. {
  129. if ($link === null)
  130. $link = self::$defaultLink;
  131. $names = implode(', ', array_keys($arr));
  132. $values = implode(', ', array_values($arr));
  133. Mysql::query(
  134. "insert into $table_name($names) values($values)", $link
  135. );
  136. if ($link === null)
  137. return mysql_insert_id();
  138. else
  139. return mysql_insert_id($nk);
  140. }
  141. static function query_grouped_array($sql, $keys, $link = null)
  142. {
  143. if ($link === null)
  144. $link = self::$defaultLink;
  145. $ret = array();
  146. $kn = count($keys);
  147. $res = Mysql::query($sql, $link);
  148. while($r = mysql_fetch_assoc($res)){
  149. $cn = & $ret;
  150. for ($i = 0; $i < $kn; $i++){
  151. if ($i < $kn - 1){
  152. if (!isset($cn[$r[$keys[$i]]])){
  153. $cn[$r[$keys[$i]]] = array();
  154. }
  155. $cn = & $cn[$r[$keys[$i]]];
  156. }else{
  157. $cn[$r[$keys[$i]]] = $r;
  158. }
  159. }
  160. }
  161. mysql_free_result($res);
  162. return $ret;
  163. }
  164. static function query_iterator($sql, $link=null)
  165. {
  166. if ($link === null)
  167. $link = self::$defaultLink;
  168. // returns object implementing Iterator for $sql /// use in foreach only ... NOT seekable
  169. // or throws Exceptions
  170. // first column will be extracted also as key
  171. // foreach ( $qi as $k => $v) // will make, for instance
  172. // $k = 12343
  173. // $v = array('id'=> '12343', 'data' => 'some data')
  174. return new QueryIterator($sql, $link);
  175. }
  176. static function real_escape_string($s, $link=null)
  177. {
  178. if ($link === null)
  179. $link = self::$defaultLink;
  180. if ($link !== null)
  181. return mysql_real_escape_string($s, $link);
  182. else
  183. return mysql_real_escape_string($s);
  184. }
  185. static function error($link=null)
  186. {
  187. if ($link === null)
  188. $link = self::$defaultLink;
  189. if ($link !== null)
  190. return mysql_error($link);
  191. else
  192. return mysql_error();
  193. }
  194. static function errno($link=null)
  195. {
  196. if ($link === null)
  197. $link = self::$defaultLink;
  198. if ($link !== null)
  199. return mysql_errno($link);
  200. else
  201. return mysql_errno();
  202. }
  203. static function select_db($dbName, $link=null)
  204. {
  205. if ($link === null)
  206. $link = self::$defaultLink;
  207. if ($link !== null)
  208. return mysql_select_db($dbName, $link);
  209. else
  210. return mysql_select_db($dbName);
  211. }
  212. static function ping($link=null)
  213. {
  214. if ($link === null)
  215. $link = self::$defaultLink;
  216. if ($link !== null)
  217. return mysql_ping($link);
  218. else
  219. return mysql_ping();
  220. }
  221. static function _query($sql, $link=null)
  222. {
  223. if ($link !== null)
  224. return mysql_query($sql, $link);
  225. else
  226. return mysql_query($sql);
  227. }
  228. static function insert_id($link=null)
  229. {
  230. if ($link === null)
  231. $link = self::$defaultLink;
  232. if ($link !== null)
  233. return mysql_insert_id($link);
  234. else
  235. return mysql_insert_id();
  236. }
  237. static function affected_rows($link=null)
  238. {
  239. if ($link === null)
  240. $link = self::$defaultLink;
  241. if ($link !== null)
  242. return mysql_affected_rows($link);
  243. else
  244. return mysql_affected_rows();
  245. }
  246. static $linkCache = array();
  247. static function connect($server, $username, $password)
  248. {
  249. $hash = md5(serialize(array($server, $username, $password)));
  250. if (!isset(self::$linkCache[$hash]))
  251. {
  252. $link = mysql_connect($server, $username, $password);
  253. if (!$link)
  254. {
  255. $n = Mysql::errno();
  256. $e = Mysql::error();
  257. Mysql::logError("connect", "{$n}: {$e}");
  258. }
  259. else
  260. {
  261. Mysql::query("set character_set_client='utf8'", $link);
  262. Mysql::query("set character_set_connection='utf8'", $link);
  263. Mysql::query("set character_set_results='utf8'", $link);
  264. }
  265. self::$linkCache[$hash] = $link;
  266. }
  267. return self::$linkCache[$hash];
  268. }
  269. }
  270. class QueryIterator implements Iterator {
  271. function __construct($sql, $link){
  272. $this->sql = $sql;
  273. $this->link = $link;
  274. $this->res = null;
  275. $this->cur = false;
  276. $this->key = null;
  277. }
  278. function current(){
  279. return $this->cur;
  280. }
  281. function key(){
  282. if ($this->key){
  283. return $this->cur[$this->key];
  284. }
  285. return false;
  286. }
  287. function valid(){
  288. return ($this->cur !== false);
  289. }
  290. function next(){
  291. $this->cur = ($this->res) ? mysql_fetch_assoc($this->res) : false;
  292. return $this->current();
  293. }
  294. function rewind(){
  295. if ($this->res){
  296. mysql_free_result($this->res);
  297. $this->res = null;
  298. }
  299. $this->res = Mysql::query($this->sql, $this->link);
  300. $this->next();
  301. // getting index for key collumn
  302. if ($this->cur){
  303. $k = array_keys($this->cur);
  304. $this->key = $k[0];
  305. }else{
  306. $this->key = false;
  307. }
  308. }
  309. function __destruct(){
  310. if ($this->res) {
  311. mysql_free_result($this->res);
  312. }
  313. }
  314. }
  315. ?>