diff --git a/lib/DB/GeophotoMapper.php b/lib/DB/GeophotoMapper.php index c0c9beab3..d6c05a841 100644 --- a/lib/DB/GeophotoMapper.php +++ b/lib/DB/GeophotoMapper.php @@ -12,61 +12,200 @@ namespace OCA\Maps\DB; +use OCP\AppFramework\Db\DoesNotExistException; +use OCP\AppFramework\Db\MultipleObjectsReturnedException; +use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; -use OCP\AppFramework\Db\Mapper; +use OCP\AppFramework\Db\QBMapper; -class GeophotoMapper extends Mapper { +class GeophotoMapper extends QBMapper { public function __construct(IDBConnection $db) { parent::__construct($db, 'maps_photos'); } + /** + * @param $id + * @return mixed|\OCP\AppFramework\Db\Entity + * @throws \OCP\AppFramework\Db\DoesNotExistException + * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException + * @throws \OCP\DB\Exception + */ public function find($id) { - $sql = 'SELECT * FROM `*PREFIX*maps_photos` ' . - 'WHERE `id` = ?'; - return $this->findEntity($sql, [$id]); + $qb = $this->db->getQueryBuilder(); + + $qb->select("*") + ->from($this->getTableName()) + ->where( + $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_STR)) + ); + + return $this->findEntity($qb); } - public function findByFileId($userId, $fileId) { - try { - $sql = 'SELECT * FROM `*PREFIX*maps_photos` ' . - 'WHERE `user_id` = ? ' . - 'AND `file_id` = ? '; - return $this->findEntity($sql, [$userId, $fileId]); - } - catch (\Throwable $e) { - return null; - } + /** + * @param $fileId + * @param $userId + * @return mixed|\OCP\AppFramework\Db\Entity + * @throws \OCP\AppFramework\Db\DoesNotExistException + * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException + * @throws \OCP\DB\Exception + */ + public function findByFileIdUserId($fileId, $userId) { + $qb = $this->db->getQueryBuilder(); + + $qb->select("*") + ->from($this->getTableName()) + ->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + )->andWhere( + $qb->expr()->eq('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_STR)) + ); + + return $this->findEntity($qb); } + /** + * @param $fileId + * @return mixed|\OCP\AppFramework\Db\Entity + * @throws \OCP\AppFramework\Db\DoesNotExistException + * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException + * @throws \OCP\DB\Exception + */ + public function findByFileId($fileId) { + $qb = $this->db->getQueryBuilder(); + + $qb->select("*") + ->from($this->getTableName()) + ->where( + $qb->expr()->eq('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_STR)) + ); + + return $this->findEntity($qb); + } + + /** + * @param $userId + * @param $limit + * @param $offset + * @return array|\OCP\AppFramework\Db\Entity[] + * @throws \OCP\DB\Exception + */ public function findAll($userId, $limit=null, $offset=null) { - $sql = 'SELECT * FROM `*PREFIX*maps_photos` where `user_id` = ? and `lat` is not null and `lng` is not null ORDER BY `date_taken` ASC'; - return $this->findEntities($sql, [$userId], $limit, $offset); + $qb = $this->db->getQueryBuilder(); + + $qb->select("*") + ->from($this->getTableName()) + ->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + )->andWhere( + $qb->expr()->isNotNull('lat') + )->andWhere( + $qb->expr()->isNotNull('lng') + )->orderBy('date_taken', 'ASC'); + if (!is_null($offset)) { + $qb->setFirstResult($offset); + } + if (!is_null($limit)) { + $qb->setMaxResults($limit); + } + return $this->findEntities($qb); } + /** + * @param $userId + * @param $limit + * @param $offset + * @return array|\OCP\AppFramework\Db\Entity[] + * @throws \OCP\DB\Exception + */ public function findAllNonLocalized($userId, $limit=null, $offset=null) { - $sql = 'SELECT * FROM `*PREFIX*maps_photos` where `user_id` = ? and (`lat` is null or `lng` is null) ORDER BY `date_taken` ASC'; - return $this->findEntities($sql, [$userId], $limit, $offset); + $qb = $this->db->getQueryBuilder(); + + $qb->select("*") + ->from($this->getTableName()) + ->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + )->andWhere( + $qb->expr()->orX( + $qb->expr()->isNull('lat'), + $qb->expr()->isNull('lng') + ) + )->orderBy('date_taken', 'ASC'); + if (!is_null($offset)) { + $qb->setFirstResult($offset); + } + if (!is_null($limit)) { + $qb->setMaxResults($limit); + } + return $this->findEntities($qb); } + /** + * @param $fileId + * @return int + * @throws \OCP\DB\Exception + */ public function deleteByFileId($fileId) { - $sql = 'DELETE FROM `*PREFIX*maps_photos` where `file_id` = ?'; - return $this->execute($sql, [$fileId]); + $qb = $this->db->getQueryBuilder(); + + $qb->delete($this->getTableName()) + ->where( + $qb->expr()->eq('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_STR)) + ); + + return $qb->executeStatement(); } + /** + * @param $fileId + * @param $userId + * @return int + * @throws \OCP\DB\Exception + */ public function deleteByFileIdUserId($fileId, $userId) { - $sql = 'DELETE FROM `*PREFIX*maps_photos` where `file_id` = ? and `user_id` = ?'; - return $this->execute($sql, [$fileId, $userId]); + $qb = $this->db->getQueryBuilder(); + + $qb->delete($this->getTableName()) + ->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + )->andWhere( + $qb->expr()->eq('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_STR)) + ); + return $qb->executeStatement(); } + /** + * @param $userId + * @return int + * @throws \OCP\DB\Exception + */ public function deleteAll($userId) { - $sql = 'DELETE FROM `*PREFIX*maps_photos` where `user_id` = ?'; - return $this->execute($sql, [$userId]); + $qb = $this->db->getQueryBuilder(); + + $qb->delete($this->getTableName()) + ->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ); + return $qb->executeStatement(); } + /** + * @param $fileId + * @param $lat + * @param $lng + * @return int + * @throws \OCP\DB\Exception + */ public function updateByFileId($fileId, $lat, $lng) { - $sql = 'UPDATE `*PREFIX*maps_photos` set `lat` = ? , `lng` = ? where `file_id` = ?'; - return $this->execute($sql, [$lat, $lng, $fileId]); + $qb = $this->db->getQueryBuilder(); + + $qb->update($this->getTableName()) + ->set('lat', $qb->createNamedParameter($lat)) + ->set('lng', $qb->createNamedParameter($lng)) + ->where($qb->expr()->eq('file_id', $qb->createNamedParameter($fileId))); + + return $qb->executeStatement(); } } diff --git a/lib/Service/PhotofilesService.php b/lib/Service/PhotofilesService.php index f1e025973..500a81faa 100644 --- a/lib/Service/PhotofilesService.php +++ b/lib/Service/PhotofilesService.php @@ -16,6 +16,7 @@ use OCA\Maps\Helper\ExifDataInvalidException; use OCA\Maps\Helper\ExifDataNoLocationException; use OCA\Maps\Helper\ExifGeoData; +use OCP\AppFramework\Db\DoesNotExistException; use OCP\Files\FileInfo; use OCP\ICacheFactory; use OCP\IL10N; @@ -157,15 +158,14 @@ public function updateByFileNow(Node $file) { if (!is_null($exif)) { $ownerId = $file->getOwner()->getUID(); // in case there is no entry for this file yet (normally there is because non-localized photos are added) - if ($this->photoMapper->findByFileId($ownerId, $file->getId()) === null) { - // TODO insert for all users having access to this file, not just the owner - $this->insertPhoto($file, $ownerId, $exif); - } - else { - $this->updatePhoto($file, $exif); + try { + $this->photoMapper->findByFileIdUserId($file->getId(), $ownerId); + $this->updatePhoto($file, $exif); $this->photosCache->clear($ownerId); $this->nonLocalizedPhotosCache->clear($ownerId); - } + } catch (DoesNotExistException $exception) { + $this->insertPhoto($file, $ownerId, $exif); + } } } } @@ -227,7 +227,7 @@ private function setDirectoriesCoords($userId, $paths, $lats, $lngs) { $nodes = $dir->getDirectoryListing(); foreach($nodes as $node) { if ($this->isPhoto($node) && $node->isUpdateable()) { - $photo = $this->photoMapper->findByFileId($userId, $node->getId()); + $photo = $this->photoMapper->findByFileIdUserId($node->getId(), $userId); $done[] = [ 'path' => preg_replace('/^files/', '', $node->getInternalPath()), 'lat' => $lat, @@ -256,7 +256,7 @@ private function setFilesCoords($userId, $paths, $lats, $lngs) { if ($this->isPhoto($file) && $file->isUpdateable()) { $lat = (count($lats) > $i) ? $lats[$i] : $lats[0]; $lng = (count($lngs) > $i) ? $lngs[$i] : $lngs[0]; - $photo = $this->photoMapper->findByFileId($userId, $file->getId()); + $photo = $this->photoMapper->findByFileIdUserId($file->getId(), $userId); $done[] = [ 'path' => preg_replace('/^files/', '', $file->getInternalPath()), 'lat' => $lat, @@ -281,7 +281,7 @@ public function resetPhotosFilesCoords($userId, $paths) { if ($userFolder->nodeExists($cleanpath)) { $file = $userFolder->get($cleanpath); if ($this->isPhoto($file) && $file->isUpdateable()) { - $photo = $this->photoMapper->findByFileId($userId, $file->getId()); + $photo = $this->photoMapper->findByFileIdUserId($file->getId(), $userId); $done[] = [ 'path' => preg_replace('/^files/', '', $file->getInternalPath()), 'lat' => null, @@ -309,7 +309,9 @@ public function addPhotoNow($photo, $userId) { // so we need to be sure it's not inserted several times // by checking if it already exists in DB // OR by using file_id in primary key - if ($this->photoMapper->findByFileId($userId, $photo->getId()) === null) { + try { + $this->photoMapper->findByFileIdUserId($photo->getId(), $userId); + } catch (DoesNotExistException $exception) { $this->insertPhoto($photo, $userId, $exif); } $this->photosCache->clear($userId);