You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

261 lines
6.2 KiB

  1. <?php
  2. /**
  3. * Класс модели данных
  4. *
  5. * @copyright NetMonsters <team@netmonsters.ru>
  6. * @link
  7. * @package Majestic
  8. * @subpackage DB
  9. * @since
  10. * @version SVN: $Id$
  11. * @filesource $URL$
  12. */
  13. abstract class Model
  14. {
  15. private $handler;
  16. protected $table = false;
  17. protected $primary_key = 'id';
  18. function __construct()
  19. {
  20. $this->handler = DBConnector::getConnect(Env::getParam('db_settings'));
  21. }
  22. /**
  23. * Выполняет запрос и возвращает сырой результат
  24. *
  25. * @param string $sql
  26. * @return resource
  27. */
  28. function exec($sql)
  29. {
  30. if (DEBUG_ENABLE) {
  31. $time = microtime(true);
  32. }
  33. $res = DBConnector::query($this->handler, $sql);
  34. if ($error = DBConnector::error($this->handler)) {
  35. throw new MJException("<b>Query Error:</b>\n".$sql."\n<b>Error:</b>\n".$error, 1);
  36. }
  37. if (DEBUG_ENABLE) {
  38. DBConnector::$queries[] = $sql.'; ('.round((microtime(true)-$time)*1000, 1).'ms)';
  39. }
  40. return $res;
  41. }
  42. /**
  43. * Выполняет запрос и возвращает объект результата
  44. *
  45. * @param string $sql
  46. * @return object
  47. */
  48. function query($sql)
  49. {
  50. $res = $this->exec($sql);
  51. switch (strtolower(substr($sql, 0, 6))) {
  52. case 'select':
  53. case '(selec':
  54. return new ModelSelectResult($res);
  55. case 'insert':
  56. case 'replac':
  57. return new ModelInsertResult($this->handler, $res); //$res for postgreSQL
  58. default:
  59. return new ModelChangeResult($this->handler, $res); //$res for postgreSQL
  60. }
  61. }
  62. /**
  63. * Экранирует строку
  64. *
  65. * @param mixed $data - строка для экранирования
  66. * @return mixed
  67. */
  68. function escape($data)
  69. {
  70. if(is_array($data)){
  71. foreach($data as $id => $val){
  72. $data[$id] = DBConnector::escape($this->handler, $val);
  73. }
  74. return $data;
  75. }
  76. return DBConnector::escape($this->handler, $data);
  77. }
  78. //////////////////////////
  79. function update($id, $data)
  80. {
  81. $sql = '';
  82. foreach ($data as $key => $val) {
  83. $sql .= $key."='".$this->escape($val)."', ";
  84. }
  85. return $this->query('UPDATE '.$this->table.' SET '.rtrim($sql, ', ').' WHERE '.$this->primary_key.'='.(int) $id);
  86. }
  87. function insert($data, $postfix = '')
  88. {
  89. $keys = array();
  90. $values = array();
  91. foreach ($data as $key => $val) {
  92. $keys[] = $key;
  93. $values[] = $this->escape($val);
  94. }
  95. return $this->query('INSERT INTO '.$this->table.' ('.implode(',', $keys).") VALUES('".implode("','", $values)."') ".$postfix);
  96. }
  97. function delete($id)
  98. {
  99. return $this->query('DELETE FROM '.$this->table.' WHERE '.$this->primary_key.'='.(int) $id);
  100. }
  101. function get($id)
  102. {
  103. return $this->query('SELECT * FROM '.$this->table.' WHERE '.$this->primary_key.'='.(int) $id);
  104. }
  105. function getList($limit = false, $sort = 'ASC')
  106. {
  107. return $this->query('SELECT *
  108. FROM '.$this->table.'
  109. ORDER BY '.$this->primary_key.' '.($sort == 'ASC' ? 'ASC' : 'DESC')
  110. .($limit !== false ? ' LIMIT '.(int) $limit : ''))->fetchAll();
  111. }
  112. function setAutocommit($set)
  113. {
  114. return DBConnector::autocommit($this->handler, (bool) $set);
  115. }
  116. function commit()
  117. {
  118. return DBConnector::commit($this->handler);
  119. }
  120. function rollback()
  121. {
  122. return DBConnector::rollback($this->handler);
  123. }
  124. /**
  125. * Возвращает значение поля $table
  126. * @return string
  127. */
  128. function getTableName()
  129. {
  130. return $this->table;
  131. }
  132. }
  133. class ModelResult
  134. {
  135. function __call($name, $args)
  136. {
  137. throw new MJException('Call undeclared method "'.$name.'" in "'.get_class($this).'" class', -1);
  138. }
  139. }
  140. class ModelSelectResult extends ModelResult
  141. {
  142. public $result;
  143. function __construct($res)
  144. {
  145. $this->result = $res;
  146. }
  147. function fetch($class_name = false)
  148. {
  149. return DBConnector::fetchObject($this->result, $class_name);
  150. }
  151. function fetchField($field, $default = false)
  152. {
  153. $row = $this->fetch();
  154. return isset($row->$field) ? $row->$field : $default;
  155. }
  156. function fetchAll($key = false)
  157. {
  158. $array = array();
  159. if ($key) {
  160. while ($row = DBConnector::fetchObject($this->result)) {
  161. $array[$row->$key] = $row;
  162. }
  163. } else {
  164. while ($row = DBConnector::fetchObject($this->result)) {
  165. $array[] = $row;
  166. }
  167. }
  168. return $array;
  169. }
  170. /**
  171. * Fetches all SQL result rows as an array of key-value pairs.
  172. *
  173. * The first column is the key, the second column is the
  174. * value.
  175. *
  176. * @return array
  177. */
  178. public function fetchPairs()
  179. {
  180. if (!method_exists('DBConnector', 'fetchArray')) {
  181. throw new Exception('Method not implemented yet.');
  182. }
  183. $data = array();
  184. while ($row = DBConnector::fetchArray($this->result, DBConnector::FETCH_NUM)) {
  185. $data[$row[0]] = $row[1];
  186. }
  187. return $data;
  188. }
  189. function count()
  190. {
  191. return DBConnector::numRows($this->result);
  192. }
  193. function free()
  194. {
  195. DBConnector::free($this->result);
  196. }
  197. function __destruct() {
  198. $this->free();
  199. }
  200. }
  201. class ModelChangeResult extends ModelResult
  202. {
  203. public $affected;
  204. function __construct($resource, $result)
  205. {
  206. $this->affected = DBConnector::affectedRows($resource, $result);
  207. }
  208. function count()
  209. {
  210. return $this->affected;
  211. }
  212. }
  213. class ModelInsertResult extends ModelChangeResult
  214. {
  215. public $id;
  216. function __construct($resource, $result)
  217. {
  218. parent::__construct($resource, $result);
  219. $this->id = DBConnector::getId($resource);
  220. }
  221. function getId()
  222. {
  223. return $this->id;
  224. }
  225. }
  226. ?>