Completed
Push — fix_broken_js_unit_test-d6ae96... ( d6ae96 )
by Thomas
21:39
created

Cache::update()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 19
rs 9.4285
cc 1
eloc 12
nc 1
nop 1
1
<?php
2
/**
3
 * ownCloud - Calendar App
4
 *
5
 * @author Georg Ehrke
6
 * @copyright 2014 Georg Ehrke <[email protected]>
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
10
 * License as published by the Free Software Foundation; either
11
 * version 3 of the License, or any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public
19
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 */
22
namespace OCA\Calendar\Cache\Object;
23
24
use OCA\Calendar\Db\Mapper;
25
use OCA\Calendar\Db\ObjectFactory;
26
use OCA\Calendar\Db\ObjectType;
27
use OCA\Calendar\ICalendar;
28
use OCA\Calendar\Utility\ObjectUtility;
29
use OCA\Calendar\IObject;
30
use OCA\Calendar\IObjectCollection;
31
32
use OCP\AppFramework\Db\DoesNotExistException;
33
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
34
use OCP\IDBConnection;
35
36
class Cache extends Mapper {
37
38
	/**
39
	 * @var ICalendar
40
	 */
41
	protected $calendar;
42
43
44
	/**
45
	 * attributes to query
46
	 * @var string
47
	 */
48
	protected $attributes;
49
50
51
	/**
52
	 * @param IDBConnection $db
53
	 * @param ICalendar $calendar
54
	 * @param ObjectFactory $objectFactory
55
	 * @throws \InvalidArgumentException
56
	 */
57
	public function __construct(IDBConnection $db, ICalendar $calendar,
58
								ObjectFactory $objectFactory){
59
		parent::__construct($db, 'clndr_objcache', $objectFactory);
60
		$this->calendar = $calendar;
61
62
		if ($calendar->getId() === null) {
63
			throw new \InvalidArgumentException(
64
				'Given calendar parameter is missing Id property!'
65
			);
66
		}
67
68
		$this->generateAttributes();
69
	}
70
71
72
	/**
73
	 * @param IObject $object
74
	 * @return IObject
75
	 */
76
	public function insert(IObject $object) {
77
		$calendarId = $this->calendar->getId();
78
79
		//TODO - (maybe) check if uri exists already
80
81
		$sql  = 'INSERT INTO `' . $this->getTableName() . '` ';
82
		$sql .= '(`calendarid`,`uri`,`type`,`etag`,';
83
		$sql .= '`startdate`,`enddate`,`repeating`,`summary`, `calendardata`, `lastmodified`) ';
84
		$sql .= 'VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
85
86
		$stmt = $this->execute($sql, [
87
			$calendarId, $object->getUri(), $object->getType(),
88
			$object->getEtag(true), $this->getUTC($object->getStartDate()), $this->getUTC($object->getEndDate()),
89
			$object->getRepeating(), $object->getSummary(), $object->getCalendarData(),
90
			$this->getUTC($object->getLastModified())
91
		]);
92
93
		$object->setId((int) $this->db->lastInsertId($this->getTableName()));
94
95
		$stmt->closeCursor();
96
97
		return $object;
98
	}
99
100
101
	/**
102
	 * @param IObject $object
103
	 * @return IObject
104
	 */
105
	public function update(IObject $object) {
106
		$calendarId = $this->calendar->getId();
107
108
		//TODO - (maybe) check uri exists already
109
110
		$sql  = 'UPDATE `' . $this->getTableName() . '` SET ';
111
		$sql .= '`type` = ?, `etag` = ?, `startdate` = ?, `enddate` = ?, ';
112
		$sql .= '`repeating` = ?, `summary` = ?, `calendardata` = ?, ';
113
		$sql .= '`lastmodified` = ? WHERE `uri` = ? and `calendarid` = ?';
114
115
		$stmt = $this->execute($sql, [
116
			$object->getType(), $object->getEtag(true), $this->getUTC($object->getStartDate()), $this->getUTC($object->getEndDate()),
117
			$object->getRepeating(), $object->getSummary(), $object->getCalendarData(),
118
			$this->getUTC($object->getLastModified()), $object->getUri(), $calendarId
119
		]);
120
		$stmt->closeCursor();
121
122
		return $object;
123
	}
124
125
126
	/**
127
	 * Finds an item from user by it's uri
128
	 * @param string $uri
129
	 * @param integer $type
130
	 * @throws DoesNotExistException: if the item does not exist
131
	 * @throws MultipleObjectsReturnedException
132
	 * @return IObject
133
	 */
134
	public function find($uri, $type=ObjectType::ALL){
135
		//TODO - add $this->calendar to returned object
136
		$sql  = 'SELECT ' . $this->attributes . ' FROM `' . $this->getTableName() . '` ';
137
		$sql .= 'WHERE `uri` = ? AND `calendarid` = ?';
138
		$params = [$uri, $this->calendar->getId()];
139
140
		$this->addTypeQuery($type, $sql, $params);
141
142
		return $this->findEntity($sql, $params);
143
	}
144
145
146
	/**
147
	 * Finds all Items of calendar $calendarId
148
	 * @param integer $type
149
	 * @param integer $limit
150
	 * @param integer $offset
151
	 * @return IObjectCollection
152
	 */
153
	public function findAll($type=ObjectType::ALL, $limit=null, $offset=null){
154
		$sql  = 'SELECT ' . $this->attributes . ' FROM `' . $this->getTableName() . '` ';
155
		$sql .= 'WHERE `calendarid` = ?';
156
		$params = [$this->calendar->getId()];
157
158
		$this->addTypeQuery($type, $sql, $params);
159
160
		return $this->findEntities($sql, $params, $limit, $offset);
161
	}
162
163
164
	/**
165
	 * Finds all Items of calendar $calendarId
166
	 * @param integer $type
167
	 * @return array
168
	 */
169
	public function listAll($type=ObjectType::ALL){
170
		$sql  = 'SELECT `uri` FROM `' . $this->getTableName() . '` ';
171
		$sql .= 'WHERE `calendarid` = ?';
172
		$params = [$this->calendar->getId()];
173
174
		$this->addTypeQuery($type, $sql, $params);
175
		$result = $this->execute($sql, $params);
176
177
		$list = [];
178
		while($row = $result->fetch()){
179
			$list[] = $row['uri'];
180
		}
181
182
		return $list;
183
	}
184
185
186
	/**
187
	 * Finds all Items of calendar $calendarId from $start to $end
188
	 * @param \DateTime $start
189
	 * @param \DateTime $end
190
	 * @param integer $type
191
	 * @param integer $limit
192
	 * @param integer $offset
193
	 * @return IObjectCollection
194
	 */
195
	public function findAllInPeriod(\DateTime $start, \DateTime $end,
196
									$type=ObjectType::ALL,
197
									$limit=null, $offset=null) {
198
		$sql  = 'SELECT ' . $this->attributes . ' FROM `' . $this->getTableName() . '` ';
199
		$sql .= 'WHERE `calendarid` = ?';
200
		$params = [$this->calendar->getId()];
201
202
		$this->addTypeQuery($type, $sql, $params);
203
		$this->addPeriodQuery($start, $end, $sql, $params);
204
205
		return $this->findEntities($sql, $params, $limit, $offset);
206
	}
207
208
209
	/**
210
	 * number of objects in a calendar
211
	 * @throws DoesNotExistException: if the item does not exist
212
	 * @return integer
213
	 */
214
	public function count(){
215
		$sql  = 'SELECT COUNT(*) AS `count` ';
216
		$sql .= 'FROM `' . $this->getTableName() . '` ';
217
		$sql .= 'WHERE `calendarid` = ?';
218
		$params = [$this->calendar->getId()];
219
220
		$row = $this->findOneQuery($sql, $params);
221
		return intval($row['count']);
222
	}
223
224
225
	/**
226
	 * delete multiple objects based on their objectUris
227
	 * @param array $objectUris
228
	 */
229
	public function deleteList(array $objectUris=[]) {
230
		if (empty($objectUris) === true) {
231
			return;
232
		}
233
234
		$sql  = 'DELETE FROM `' . $this->getTableName() . '` ';
235
		$sql .= 'WHERE `calendarid` = ? AND (';
236
		$params = [$this->calendar->getId()];
237
238
		$sqlElements = [];
239
		foreach($objectUris as $objectUri) {
240
			$sqlElements[] = '`uri` = ?';
241
			$params[] = $objectUri;
242
		}
243
244
		if (count($sqlElements) === 0) {
245
			return;
246
		}
247
248
		$sql .= implode(' OR ', $sqlElements);
249
		$sql .= ')';
250
251
		$this->execute($sql, $params);
252
	}
253
254
255
	/**
256
	 * delete all objects from cache
257
	 */
258
	public function clear() {
259
		$sql  = 'DELETE FROM `' . $this->getTableName() . '` ';
260
		$sql .= 'WHERE `calendarid` = ?';
261
		$params = [$this->calendar->getId()];
262
263
		$this->execute($sql, $params);
264
	}
265
266
267
	/**
268
	 * get UTC from a datetime object
269
	 * @param \DateTime $datetime
270
	 * @return string
271
	 */
272
	private function getUTC(\DateTime $datetime){
273
		return ObjectUtility::getUTCforMDB($datetime);
274
	}
275
276
277
	/**
278
	 * @param integer $type
279
	 * @param string &$sql
280
	 * @param array &$params
281
	 * @return void
282
	 */
283
	private function addTypeQuery($type, &$sql, &$params) {
284
		$sqlElements = array();
285
286
		if (ObjectType::EVENT & $type) {
287
			$sqlElements[] = '`type` = ?';
288
			$params[] = ObjectType::EVENT;
289
		}
290
		if (ObjectType::JOURNAL & $type) {
291
			$sqlElements[] = '`type` = ?';
292
			$params[] = ObjectType::JOURNAL;
293
		}
294
		if (ObjectType::TODO & $type) {
295
			$sqlElements[] = '`type` = ?';
296
			$params[] = ObjectType::TODO;
297
		}
298
299
		if (count($sqlElements) === 0) {
300
			return;
301
		}
302
303
		$sql .= ' AND (';
304
		$sql .= implode(' OR ', $sqlElements);
305
		$sql .= ') ';
306
	}
307
308
309
	/**
310
	 * @param \DateTime $start
311
	 * @param \DateTime $end
312
	 * @param string &$sql
313
	 * @param array &$params
314
	 */
315
	private function addPeriodQuery(\DateTime $start, \DateTime $end, &$sql, &$params) {
316
		$sql .= ' AND ((`startdate` >= ? AND `startdate` <= ?) ';
317
		$sql .= 'OR (`enddate` >= ? AND `enddate` <= ?) ';
318
		$sql .= 'OR (`startdate` <= ? AND `enddate` >= ?) ';
319
		$sql .= 'OR (`startdate` <= ? AND `repeating` = 1)) ';
320
		$sql .= 'ORDER BY `repeating` ';
321
322
		$utcStart = $this->getUTC($start);
323
		$utcEnd = $this->getUTC($end);
324
325
		$params = array_merge($params, array(
326
			$utcStart,
327
			$utcEnd,
328
			$utcStart,
329
			$utcEnd,
330
			$utcStart,
331
			$utcEnd,
332
			$utcEnd
333
		));
334
	}
335
336
337
	/**
338
	 * generate attributes to query
339
	 */
340
	private function generateAttributes() {
341
		$this->attributes = implode(', ', [
342
			'`id`',
343
			'`uri`',
344
			'`etag`',
345
			'`calendardata`'
346
		]);
347
	}
348
}