Completed
Push — master ( 531f03...9281ce )
by Alexander
07:05 queued 03:48
created

QueryBuilder::setPage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Class for query building
4
 *
5
 * @file      QueryBuilder.php
6
 *
7
 * PHP version 7.0+
8
 *
9
 * @author    Alexander Yancharuk <alex at itvault dot info>
10
 * @copyright © 2012-2018 Alexander Yancharuk
11
 * @date      Сбт Июл 07 21:55:54 2012
12
 * @license   The BSD 3-Clause License
13
 *            <https://tldrlegal.com/license/bsd-3-clause-license-(revised)>
14
 */
15
16
namespace Veles\Model;
17
18
use Exception;
19
use Veles\DataBase\Db;
20
use Veles\DataBase\DbFilter;
21
use Veles\DataBase\DbPaginator;
22
23
/**
24
 * Класс QueryBuilder
25
 * @author  Alexander Yancharuk <alex at itvault dot info>
26
 */
27
class QueryBuilder implements QueryBuilderInterface
28
{
29
	/**
30
	 * @param $filter DbFilter
31
	 *
32
	 * @return array
33
	 */
34 2
	protected function extractParams(DbFilter $filter)
35
	{
36
		return [
37 2
			'where'  => $filter->getWhere(),
38 2
			'group'  => $filter->getGroup(),
39 2
			'having' => $filter->getHaving(),
40 2
			'order'  => $filter->getOrder()
41
		];
42
	}
43
44
	/**
45
	 * Построение sql-запроса для insert
46
	 *
47
	 * @param ActiveRecord $model Экземпляр модели
48
	 *
49
	 * @return string
50
	 * @throws Exception
51
	 */
52 2
	public function insert(ActiveRecord $model)
53
	{
54 2
		$arr = ['fields' => '', 'values' => ''];
55
56 2
		foreach ($model->getMap() as $property => $value) {
57 2
			$value = $this->sanitize($model, $property);
58
59 2
			if (null === $value) {
60 2
				continue;
61
			}
62
63 2
			$arr['fields'] .= "\"$property\", ";
64 2
			$arr['values'] .= "$value, ";
65
		}
66
67 2
		$arr = array_map(
68 2
			function ($val) {
69 2
				return rtrim($val, ', ');
70 2
			},
71 2
			$arr
72
		);
73
74
		$sql = '
75
			INSERT
76 2
				"' . $model::TBL_NAME . "\"
77 2
				($arr[fields])
78
			VALUES
79 2
				($arr[values])
80
		";
81
82 2
		return $sql;
83
	}
84
85
	/**
86
	 * Функция безопасности переменных
87
	 *
88
	 * @param ActiveRecord $model
89
	 * @param mixed        $property
90
	 *
91
	 * @return mixed
92
	 * @throws Exception
93
	 */
94 4
	private function sanitize(ActiveRecord $model, $property)
95
	{
96 4
		if (!isset($model->$property)) {
97 2
			return null;
98
		}
99
100 4
		switch ($model->getMap()[$property]) {
101 4
			case 'int':
102 4
				$value = (int) $model->$property;
103 4
				break;
104 4
			case 'float':
105 2
				$value = (float) $model->$property;
106 2
				break;
107 4
			case 'string':
108 4
				$value = Db::escape($model->$property);
109 4
				break;
110
			default:
111 2
				$value = null;
112 2
				break;
113
		}
114
115 4
		return $value;
116
	}
117
118
	/**
119
	 * Построение sql-запроса для update
120
	 *
121
	 * @param ActiveRecord $model Экземпляр модели
122
	 *
123
	 * @return string $sql
124
	 * @throws Exception
125
	 */
126 2
	public function update(ActiveRecord $model)
127
	{
128 2
		$params = '';
129 2
		$table  = $model::TBL_NAME;
130 2
		$properties = array_diff(array_keys($model->getMap()), ['id']);
131
132 2
		foreach ($properties as $property) {
133 2
			$value = $this->sanitize($model, $property);
134
135 2
			if (null === $value) {
136
				continue;
137
			}
138
139 2
			$params .= "\"$property\" = $value, ";
140
		}
141
142 2
		$params = rtrim($params, ', ');
143
144
		$sql = "
145
			UPDATE
146 2
				\"$table\"
147
			SET
148 2
				$params
149
			WHERE
150 2
				id = $model->id
151
		";
152
153 2
		return $sql;
154
	}
155
156
	/**
157
	 * Построение sql-запроса для select
158
	 * @param ActiveRecord $model Экземпляр модели
159
	 * @param int $identifier primary key
160
	 * @return string $sql
161
	 */
162 2
	public function getById(ActiveRecord $model, $identifier)
163
	{
164 2
		$identifier = (int) $identifier;
165 2
		$table      = $model::TBL_NAME;
166
167
		$sql = "
168
			SELECT *
169
			FROM
170 2
				\"$table\"
171
			WHERE
172 2
				id = $identifier
173
			LIMIT 1
174
		";
175
176 2
		return $sql;
177
	}
178
179
	/**
180
	 * Построение sql-запроса для delete
181
	 *
182
	 * @param ActiveRecord $model Экземпляр модели
183
	 * @param array        $ids   Массив ID для удаления
184
	 *
185
	 * @throws Exception
186
	 * @return string $sql
187
	 */
188 4
	public function delete(ActiveRecord $model, array $ids)
189
	{
190 4
		foreach ($ids as &$value) {
191 4
			$value = (int) $value;
192
		};
193
194 4
		$ids   = implode(',', $ids);
195 4
		$table = $model::TBL_NAME;
196
197
		$sql = "
198
			DELETE FROM
199 4
				\"$table\"
200
			WHERE
201 4
				id IN ($ids)
202
		";
203
204 4
		return $sql;
205
	}
206
207
	/**
208
	 * Построение запроса получения списка объектов
209
	 *
210
	 * @param ActiveRecord  $model  Экземпляр модели
211
	 * @param bool|DbFilter $filter Экземпляр фильтра
212
	 *
213
	 * @return string
214
	 */
215 4
	public function find(ActiveRecord $model, $filter)
216
	{
217 4
		$fields = '"' . implode('", "', array_keys($model->getMap())) . '"';
218 4
		$where = $group = $having = $order = '';
219
220 4
		if ($filter instanceof DbFilter) {
221 2
			$params = $this->extractParams($filter);
222 2
			extract($params, EXTR_IF_EXISTS);
223
		}
224
225
		$sql = "
226
			SELECT
227 4
				$fields
228
			FROM
229 4
				\"" . $model::TBL_NAME . "\"
230 4
			$where
231 4
			$group
232 4
			$having
233 4
			$order
234
		";
235
236 4
		return rtrim($sql);
237
	}
238
239
	/**
240
	 * Построение произвольного запроса с постраничным выводом
241
	 *
242
	 * @param string      $sql   Запрос
243
	 * @param DbPaginator $pager Экземпляр постраничного вывода
244
	 *
245
	 * @return string
246
	 */
247 2
	public function setPage($sql, DbPaginator $pager)
248
	{
249 2
		$sql = str_replace('SELECT', 'SELECT SQL_CALC_FOUND_ROWS', $sql);
250 2
		return $sql . $pager->getSqlLimit();
251
	}
252
}
253