Passed
Push — fix-wrong-clustering ( ff2ddc )
by Branko
02:27
created

FaceMapper   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 141
Duplicated Lines 0 %

Test Coverage

Coverage 3.16%

Importance

Changes 0
Metric Value
eloc 90
dl 0
loc 141
ccs 3
cts 95
cp 0.0316
rs 10
c 0
b 0
f 0
wmc 11

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 2 1
A countFaces() 0 19 2
A find() 0 7 1
A findAllFromPerson() 0 7 1
A getPersonOnFile() 0 18 1
A getOldestCreatedFaceWithoutPerson() 0 19 2
A removeFaces() 0 5 1
A getFaces() 0 12 1
A findFacesFromPerson() 0 14 1
1
<?php
2
namespace OCA\FaceRecognition\Db;
3
4
use OCP\IDBConnection;
5
use OCP\AppFramework\Db\QBMapper;
6
use OCP\AppFramework\Db\DoesNotExistException;
7
use OCP\DB\QueryBuilder\IQueryBuilder;
8
9
class FaceMapper extends QBMapper {
10 4
	public function __construct(IDBConnection $db) {
11 4
		parent::__construct($db, 'face_recognition_faces', '\OCA\FaceRecognition\Db\Face');
12 4
	}
13
14
	public function find (int $faceId): Face {
15
		$qb = $this->db->getQueryBuilder();
16
		$qb->select('id', 'image', 'person', 'left', 'right', 'top', 'bottom', 'descriptor')
17
			->from('face_recognition_faces', 'f')
18
			->andWhere($qb->expr()->eq('id', $qb->createNamedParameter($faceId)));
19
		$faces = $this->findEntity($qb);
20
		return $faces;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $faces returns the type OCP\AppFramework\Db\Entity which includes types incompatible with the type-hinted return OCA\FaceRecognition\Db\Face.
Loading history...
21
	}
22
23
	public function findAllFromPerson (int $personId): array {
24
		$qb = $this->db->getQueryBuilder();
25
		$qb->select('id', 'image', 'person', 'left', 'right', 'top', 'bottom', 'descriptor')
26
			->from('face_recognition_faces', 'f')
27
			->where($qb->expr()->eq('person', $qb->createNamedParameter($personId)));
28
		$faces = $this->findEntities($qb);
29
		return $faces;
30
	}
31
32
	/**
33
	 * Counts all the faces that belong to images of a given user, created using given model
34
	 *
35
	 * @param string $userId User to which faces and associated images belongs to
36
	 * @param int $model Model ID
37
	 * @param bool $onlyWithoutPersons True if we need to count only faces which are not having person associated for it.
38
	 * If false, all faces are counted.
39
	 */
40
	public function countFaces(string $userId, int $model, bool $onlyWithoutPersons=false): int {
41
		$qb = $this->db->getQueryBuilder();
42
		$qb = $qb
43
			->select($qb->createFunction('COUNT(' . $qb->getColumnName('f.id') . ')'))
44
			->from('face_recognition_faces', 'f')
45
			->innerJoin('f', 'face_recognition_images' ,'i', $qb->expr()->eq('f.image', 'i.id'))
46
			->where($qb->expr()->eq('user', $qb->createParameter('user')))
47
			->andWhere($qb->expr()->eq('model', $qb->createParameter('model')));
48
		if ($onlyWithoutPersons) {
49
			$qb = $qb->andWhere($qb->expr()->isNull('person'));
50
		}
51
		$query = $qb
52
			->setParameter('user', $userId)
53
			->setParameter('model', $model);
54
		$resultStatement = $query->execute();
55
		$data = $resultStatement->fetch(\PDO::FETCH_NUM);
56
		$resultStatement->closeCursor();
57
58
		return (int)$data[0];
59
	}
60
61
	/**
62
	 * Gets oldest created face from database, for a given user and model, that is not associated with a person.
63
	 *
64
	 * @param string $userId User to which faces and associated images belongs to
65
	 * @param int $model Model ID
66
	 *
67
	 * @return Face Oldest face, if any is found
68
	 * @throws DoesNotExistException If there is no faces in database without person for a given user and model.
69
	 */
70
	public function getOldestCreatedFaceWithoutPerson(string $userId, int $model): Face {
71
		$qb = $this->db->getQueryBuilder();
72
		$qb
73
			->select('f.id', 'f.creation_time')
74
			->from('face_recognition_faces', 'f')
75
			->innerJoin('f', 'face_recognition_images' ,'i', $qb->expr()->eq('f.image', 'i.id'))
76
			->where($qb->expr()->eq('user', $qb->createNamedParameter($userId)))
77
			->andWhere($qb->expr()->eq('model', $qb->createNamedParameter($model)))
78
			->andWhere($qb->expr()->isNull('person'))
79
			->orderBy('f.creation_time', 'ASC');
80
		$cursor = $qb->execute();
81
		$row = $cursor->fetch();
82
		if($row === false) {
83
			$cursor->closeCursor();
84
			throw new DoesNotExistException("No faces found and we should have at least one");
85
		}
86
		$face = $this->mapRowToEntity($row);
87
		$cursor->closeCursor();
88
		return $face;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $face returns the type OCP\AppFramework\Db\Entity which includes types incompatible with the type-hinted return OCA\FaceRecognition\Db\Face.
Loading history...
89
	}
90
91
	public function getFaces(string $userId, $model): array {
92
		$qb = $this->db->getQueryBuilder();
93
		$query = $qb
0 ignored issues
show
Unused Code introduced by
The assignment to $query is dead and can be removed.
Loading history...
94
			->select('f.id', 'f.person', 'f.descriptor')
95
			->from('face_recognition_faces', 'f')
96
			->innerJoin('f', 'face_recognition_images' ,'i', $qb->expr()->eq('f.image', 'i.id'))
97
			->where($qb->expr()->eq('user', $qb->createParameter('user')))
98
			->andWhere($qb->expr()->eq('model', $qb->createParameter('model')))
99
			->setParameter('user', $userId)
100
			->setParameter('model', $model);
101
		$faces = $this->findEntities($qb);
102
		return $faces;
103
	}
104
105
	public function findFacesFromPerson(string $userId, int $personId, int $model, $limit = null, $offset = null): array {
106
		$qb = $this->db->getQueryBuilder();
107
		$qb->select('f.id', 'f.image', 'f.person')
108
			->from('face_recognition_faces', 'f')
109
			->innerJoin('f', 'face_recognition_images' ,'i', $qb->expr()->eq('f.image', 'i.id'))
110
			->where($qb->expr()->eq('user', $qb->createNamedParameter($userId)))
111
			->andWhere($qb->expr()->eq('person', $qb->createNamedParameter($personId)))
112
			->andWhere($qb->expr()->eq('model', $qb->createNamedParameter($model)));
113
114
		$qb->setMaxResults($limit);
115
		$qb->setFirstResult($offset);
116
117
		$faces = $this->findEntities($qb);
118
		return $faces;
119
	}
120
121
122
	public function getPersonOnFile(string $userId, int $personId, int $fileId, int $model): array {
123
		$qb = $this->db->getQueryBuilder();
124
		$qb->select('f.id', 'left', 'right', 'top', 'bottom')
125
			->from('face_recognition_faces', 'f')
126
			->innerJoin('f', 'face_recognition_persons' ,'p', $qb->expr()->eq('f.person', 'p.id'))
127
			->innerJoin('f', 'face_recognition_images' ,'i', $qb->expr()->eq('f.image', 'i.id'))
128
			->where($qb->expr()->eq('p.user', $qb->createParameter('user')))
129
			->andWhere($qb->expr()->eq('person', $qb->createParameter('person')))
130
			->andWhere($qb->expr()->eq('file', $qb->createParameter('file_id')))
131
			->andWhere($qb->expr()->eq('model', $qb->createParameter('model')))
132
			->andWhere($qb->expr()->eq('p.is_valid', $qb->createParameter('is_valid')))
133
			->setParameter('user', $userId)
134
			->setParameter('person', $personId)
135
			->setParameter('file_id', $fileId)
136
			->setParameter('model', $model)
137
			->setParameter('is_valid', true);
138
		$faces = $this->findEntities($qb);
139
		return $faces;
140
	}
141
142
	/**
143
	 * @param int $imageId Image for which to delete faces for
144
	 */
145
	public function removeFaces(int $imageId) {
146
		$qb = $this->db->getQueryBuilder();
147
		$qb->delete($this->getTableName())
148
			->where($qb->expr()->eq('image', $qb->createNamedParameter($imageId)))
149
			->execute();
150
	}
151
152
}
153