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.

232 lines
6.9 KiB

  1. <?php
  2. /**
  3. * Класс модели данных
  4. *
  5. * @copyright NetMonsters <team@netmonsters.ru>
  6. * @link http://netmonsters.ru
  7. * @package Majestic
  8. * @subpackage Model
  9. * @since 2011-11-11
  10. */
  11. /**
  12. * @property SqlDbDriver $db
  13. */
  14. abstract class SqlModel extends Model
  15. {
  16. /**
  17. * @param string $ident
  18. * @return string Quoted identifier.
  19. */
  20. public function identify($ident)
  21. {
  22. return $this->db->quoteIdentifier($ident);
  23. }
  24. /**
  25. * @param mixed $value
  26. * @return string Quoted value.
  27. */
  28. public function quote($value)
  29. {
  30. return $this->db->quote($value);
  31. }
  32. /**
  33. * @param int $id
  34. * @return object
  35. */
  36. public function get($id)
  37. {
  38. $sql = 'SELECT * FROM :table WHERE :pk=?';
  39. return $this->fetch($sql, $id);
  40. }
  41. /**
  42. * @param array $data
  43. * @param mixed $where
  44. * @return int Number of affected rows
  45. */
  46. public function update($data, $where)
  47. {
  48. if (is_int($where) || $where === (string)(int)$where) {
  49. $where = $this->identify($this->key) . '=' . (int)$where;
  50. }
  51. return parent::update($data, $where);
  52. }
  53. /**
  54. * @param int $id Int id
  55. * @return int Number of affected rows
  56. */
  57. public function delete($id)
  58. {
  59. $where = $this->identify($this->key) . '=' . (int)$id;
  60. return $this->db->delete($this->table(), $where);
  61. }
  62. /**
  63. * Creates order sql string
  64. *
  65. * @param array $params
  66. * @param array $sortable
  67. * @return string
  68. */
  69. protected function order($params, $sortable = array('id'))
  70. {
  71. $sql = '';
  72. if (isset($params['sort'])) {
  73. if (!is_array($params['sort'])) {
  74. if (isset($params['order'])) {
  75. $params['order'] = array($params['sort'] => $params['order']);
  76. }
  77. $params['sort'] = array($params['sort']);
  78. }
  79. $order_list = array();
  80. for ($i = 0; $i < count($params['sort']); $i++) {
  81. $order = (isset($params['order'][$params['sort'][$i]]) && $params['order'][$params['sort'][$i]] == 'desc') ? 'DESC' : 'ASC';
  82. if (in_array($params['sort'][$i], $sortable)) {
  83. $order_list[] = $this->identify($params['sort'][$i]) . ' ' . $order;
  84. }
  85. }
  86. if ($order_list) {
  87. $sql = ' ORDER BY ' . implode(',', $order_list);
  88. }
  89. }
  90. return $sql;
  91. }
  92. /**
  93. * Searches using like
  94. *
  95. * @param array $params
  96. * @param array $searchable
  97. * @param string $table_prefix
  98. * @return string
  99. */
  100. protected function search($params, $searchable = array('id'), $table_prefix = '')
  101. {
  102. $sql = '';
  103. if (isset($params['q']) && isset($params['qt']) && in_array($params['qt'], $searchable)) {
  104. if ($table_prefix) {
  105. $sql = $table_prefix . '.';
  106. }
  107. $sql .= $this->identify($params['qt']) . ' LIKE ' . $this->quote('%' . $params['q'] . '%');
  108. }
  109. return $sql;
  110. }
  111. /**
  112. * This method appends to params table and primary key.
  113. * So they can be accessed through `:table` and `:pk` placeholders.
  114. *
  115. * @param string $sql
  116. * @param array $params
  117. * @return DbStatement
  118. */
  119. protected function query($sql, $params = array())
  120. {
  121. if (!is_array($params)) {
  122. $params = array($params);
  123. }
  124. $params = array(
  125. 'table' => new DbExpr($this->identify($this->table())),
  126. 'pk' => new DbExpr($this->identify($this->key)),
  127. ) + $params;
  128. return $this->db->query($sql, $params);
  129. }
  130. /**
  131. * @param string $data Request
  132. * @param array $params Request parameters
  133. * @param string $field Requested field name
  134. * @param CacheKey $cache_key Key for caching in
  135. * @return mixed
  136. */
  137. protected function fetchField($data, $params = array(), $field, $cache_key = null)
  138. {
  139. if (!$cache_key || !$result = $cache_key->get()) {
  140. $result = $this->query($data, $params)->fetchField($field);
  141. if ($cache_key) {
  142. $cache_key->set($result);
  143. }
  144. }
  145. return $result;
  146. }
  147. /**
  148. * @param string $data Request
  149. * @param array $params Request parameters
  150. * @param CacheKey $cache_key Key for caching in
  151. * @return mixed
  152. */
  153. protected function fetch($data, $params = array(), $cache_key = null)
  154. {
  155. if (!$cache_key || !$result = $cache_key->get()) {
  156. $result = $this->query($data, $params)->fetch();
  157. if ($cache_key) {
  158. $cache_key->set($result);
  159. }
  160. }
  161. return $result;
  162. }
  163. /**
  164. * @param string $data
  165. * @param array $params
  166. * @param CacheKey $cache_key
  167. * @return array
  168. */
  169. protected function fetchAll($data, $params = array(), $cache_key = null)
  170. {
  171. if (!$cache_key || !$result = $cache_key->get()) {
  172. $result = $this->query($data, $params)->fetchAll();
  173. if ($cache_key) {
  174. $cache_key->set($result);
  175. }
  176. }
  177. return $result;
  178. }
  179. /**
  180. * @param $select array
  181. * @param $distinct string|bool
  182. * @param $where array @ex array('field=?' => $value, 'field=1')
  183. * @param $order array @ex array('sort' => array('field1', 'field2'), 'order' => array('field2' => 'desc'))
  184. * @param $limit string @ex '30' or '30,30'
  185. * @param $heaving TODO
  186. * @param $group_by TODO
  187. * @param $sql_expression null|string
  188. * @param $sql_expression_params array
  189. * @param $cache_key CacheKey|null
  190. * @return SqlResultProvider
  191. */
  192. public function find($select, $distinct, $where, $order, $limit, $heaving = null, $group_by = null, $sql_expression = null, $sql_expression_params = array(), $cache_key = null)
  193. {
  194. $select = $this->db->selectExpr($select, $distinct);
  195. $where = $this->db->whereExpr($where);
  196. $group_by = $this->db->groupByExpr($group_by);
  197. $order = isset($order['sort']) ? $this->order($order, $order['sort']) : false;
  198. $limit = $this->db->limitExpr($limit);
  199. $result_items = $this->fetchAll(
  200. (($sql_expression) ? $sql_expression : ('SELECT ' . $select . ' FROM ' . $this->table()))
  201. . (($where) ? (' WHERE ' . $where) : '')
  202. . (($group_by) ? (' GROUP BY ' . $group_by) : '')
  203. . (($order) ? ($order) : '')
  204. . (($limit) ? (' LIMIT ' . $limit) : ''),
  205. $sql_expression_params,
  206. $cache_key
  207. );
  208. return new SqlResultProvider($result_items);
  209. }
  210. /**
  211. * @param $sql_expression null
  212. * @param $sql_expression_params array
  213. * @return SqlCriteria
  214. */
  215. public function criteria($sql_expression = null, $sql_expression_params = array())
  216. {
  217. return new SqlCriteria($this, $sql_expression, $sql_expression_params);
  218. }
  219. }