PageRenderTime 45ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/src/app/model/Db.php

https://bitbucket.org/Pozadi/myfin/
PHP | 253 lines | 185 code | 59 blank | 9 comment | 44 complexity | 4fb5ef7ec411ce49459aa1b52eb96fb2 MD5 | raw file
  1. <?php
  2. /**
  3. * Description of Db
  4. *
  5. * @author roman
  6. */
  7. class Db {
  8. private static $_lastQuery;
  9. private static $_lastResult;
  10. private static $_link;
  11. private static $_lastQueryTime = 0;
  12. private static $_fullQueryTime = 0;
  13. public static function connect() {
  14. if (self::$_link !== null)
  15. return true;
  16. if (!(self::$_link = mysql_connect(get_config('db_host'),
  17. get_config('db_user'),
  18. get_config('db_password')
  19. ))) {
  20. Messages::addError('Ошибка базы данных<br>Не могу соединиться с сервером<br>' . mysql_error());
  21. return false;
  22. }
  23. if (false == self::justQuery("SET NAMES utf8"))
  24. return false;
  25. if (!mysql_select_db(get_config('db_db_name'), self::$_link)
  26. && !self::_tryCreateDb()) {
  27. Messages::addError('Ошибка базы данных<br>Не могу выбрать базу данных<br>' . mysql_error());
  28. return false;
  29. }
  30. if (!self::_checkTables())
  31. return false;
  32. // Установка timezone для бд
  33. $z = intval( date('Z') );
  34. $z = sprintf('%s%02d:%02d', $z < 0 ? '-' : '+', abs( $z ) / 3600, abs( $z ) % 60);
  35. if (!self::justQuery("SET time_zone = @s", $z))
  36. return false;
  37. return self::$_link;
  38. }
  39. public static function selectGetArray() {
  40. if (func_num_args() == 0)
  41. return null;
  42. $sql = self::_buildReq(func_get_args());
  43. $result = self::justQuery($sql);
  44. if ($result) {
  45. $return = array();
  46. while ($row = mysql_fetch_assoc($result))
  47. $return[] = $row;
  48. return $return;
  49. }
  50. return null;
  51. }
  52. public static function selectGetVerticalArray() {
  53. if (func_num_args() == 0)
  54. return null;
  55. $sql = self::_buildReq(func_get_args());
  56. $result = self::justQuery($sql);
  57. if ($result) {
  58. $return = array();
  59. while ($row = mysql_fetch_array($result))
  60. $return[] = $row[0];
  61. return $return;
  62. }
  63. return null;
  64. }
  65. public static function selectGetValue() {
  66. if (func_num_args() == 0)
  67. return null;
  68. $sql = self::_buildReq(func_get_args());
  69. $result = self::justQuery($sql);
  70. if ($result)
  71. return @mysql_result($result, 0);
  72. return null;
  73. }
  74. public static function justQuery() {
  75. if (func_num_args() == 0)
  76. return null;
  77. if (false === self::connect())
  78. return null;
  79. $tmp = func_get_args();
  80. // Заменяем все вхождения имен таблиц по умолчанию на значения из конфига
  81. // Немного опасная реализация, но если осторожно то можно,
  82. // и в старом коде ничего менять не надо
  83. $tmp[0] = str_replace(array_keys(get_config( 'db_table' )),
  84. get_config( 'db_table' ), $tmp[0]);
  85. $sql = self::_buildReq($tmp);
  86. self::$_lastQuery = $sql;
  87. $startTime = Util::microtime_float();
  88. self::$_lastResult = mysql_query($sql, self::$_link);
  89. $endTime = Util::microtime_float();
  90. self::$_lastQueryTime = $endTime - $startTime;
  91. self::$_fullQueryTime += self::$_lastQueryTime;
  92. if (self::$_lastResult === false)
  93. Messages::addError('Ошибка базы данных<br>' . Db::lastError());
  94. Messages::addDebug($sql . "\n" .
  95. (self::$_lastResult === false ? Db::lastError() : 'OK') .
  96. "\n" . number_format(self::$_lastQueryTime, 10));
  97. return self::$_lastResult;
  98. }
  99. public static function buildReq() {
  100. if (func_num_args() == 0)
  101. return null;
  102. return self::_buildReq(func_get_args());
  103. }
  104. public static function lastError() {
  105. return "<code>" . mysql_error() . "\n<br/>\nЗапрос: " . self::$_lastQuery . "</code>";
  106. }
  107. public static function insertedId() {
  108. return mysql_insert_id();
  109. }
  110. public static function getNumRows() {
  111. return mysql_num_rows(self::$_lastResult);
  112. }
  113. public static function getFullQueryTime() {
  114. return self::$_fullQueryTime;
  115. }
  116. private static function _buildReq($arg_list) {
  117. $template = $arg_list[0];
  118. unset($arg_list[0]);
  119. $result = '';
  120. for ($i = 0; $i < strlen($template); $i++) {
  121. $ss = substr($template, $i, 2);
  122. if (in_array($ss, array('@i', '@s', '@f', '@a', '@n', '@l')) && count($arg_list) > 0) {
  123. if ($ss == '@i') // целое
  124. $val = intval((string)array_shift($arg_list));
  125. if ($ss == '@s') // строка
  126. $val = "'" . mysql_escape_string(array_shift($arg_list)) . "'";
  127. if ($ss == '@l') // строка без кавычек
  128. $val = mysql_escape_string(array_shift($arg_list));
  129. if ($ss == '@f') // дробное
  130. $val = floatval(array_shift($arg_list));
  131. if ($ss == '@a') { // массив целых
  132. $tmp = array_shift($arg_list);
  133. foreach ($tmp as $id => $v) {
  134. $tmp[$id] = intval(trim($v));
  135. }
  136. $val = '(' . implode($tmp, ', ') . ')';
  137. }
  138. if ($ss == '@n') // строка в обратных кавычках
  139. $val = "`" . mysql_escape_string(array_shift($arg_list)) . "`";
  140. $result .= $val;
  141. $i++;
  142. } else
  143. $result .= substr($template, $i, 1);
  144. }
  145. return $result;
  146. }
  147. private static function _tryCreateDb() {
  148. if (!self::justQuery('CREATE DATABASE @n', get_config('db_db_name')))
  149. return false;
  150. return mysql_select_db(get_config('db_db_name'), self::$_link);
  151. }
  152. private static function _checkTables() {
  153. $tables = self::selectGetVerticalArray('show tables');
  154. if (!is_array($tables))
  155. return false;
  156. $tabl_sql['events'] = 'CREATE TABLE events (
  157. `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  158. `user_id` int(10) unsigned NOT NULL DEFAULT \'0\',
  159. `type` tinyint(1) NOT NULL,
  160. `value` bigint(20) NOT NULL,
  161. `date` datetime NOT NULL,
  162. `description` varchar(300) NOT NULL,
  163. `purse_id` int(10) unsigned NOT NULL DEFAULT \'0\',
  164. PRIMARY KEY (`id`)
  165. ) ENGINE=MyISAM DEFAULT CHARSET=utf8';
  166. $tabl_sql['ev2tag'] = 'CREATE TABLE `ev2tag` (
  167. `ev_id` bigint(20) unsigned NOT NULL,
  168. `tag_id` int(10) unsigned NOT NULL,
  169. `user_id` int(10) unsigned NOT NULL DEFAULT \'0\',
  170. PRIMARY KEY (`ev_id`,`tag_id`)
  171. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;';
  172. $tabl_sql['tags'] = 'CREATE TABLE tags (
  173. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  174. `name` varchar(30) NOT NULL,
  175. PRIMARY KEY (`id`),
  176. UNIQUE KEY `name` (`name`)
  177. ) ENGINE=MyISAM DEFAULT CHARSET=utf8';
  178. $tabl_sql['users'] = 'CREATE TABLE `users` (
  179. `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
  180. `ident_hash` VARCHAR( 32 ) NOT NULL ,
  181. `email` VARCHAR( 50 ) NOT NULL ,
  182. `name` VARCHAR( 50 ) NOT NULL
  183. ) ENGINE = MYISAM DEFAULT CHARSET=utf8';
  184. foreach ($tabl_sql as $key => $value) {
  185. $name = tn($key);
  186. if (!in_array($name, $tables)
  187. && !self::justQuery($value)) {
  188. Messages::addError('Не удалось создать таблицу ' . $name);
  189. return false;
  190. }
  191. }
  192. return true;
  193. }
  194. }