Passed
Push — qbmapper ( 34b884...fb19ee )
by Matias
02:21
created

FaceMapper   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 157
Duplicated Lines 0 %

Test Coverage

Coverage 3.13%

Importance

Changes 0
Metric Value
eloc 89
dl 0
loc 157
ccs 3
cts 96
cp 0.0313
rs 10
c 0
b 0
f 0
wmc 12

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 2 1
A getPersonOnFile() 0 18 1
A countFaces() 0 19 2
A getOldestCreatedFaceWithoutPerson() 0 11 1
A removeFaces() 0 5 1
A find() 0 7 1
A frFindEntities() 0 12 2
A getFaces() 0 12 1
A findAllFromPerson() 0 7 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 {
0 ignored issues
show
Unused Code introduced by
The parameter $userId is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

70
	public function getOldestCreatedFaceWithoutPerson(/** @scrutinizer ignore-unused */ string $userId, int $model): Face {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $model is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

70
	public function getOldestCreatedFaceWithoutPerson(string $userId, /** @scrutinizer ignore-unused */ int $model): Face {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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($user)))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $user does not exist. Did you maybe mean $userId?
Loading history...
77
			->andWhere($qb->expr()->eq('model', $qb->createNamedParameter(1)))
78
			->andWhere($qb->expr()->isNull('person'));
79
		$face = $this->findEntity($qb);
80
		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...
81
	}
82
83
	public function getFaces(string $userId, $model): array {
84
		$qb = $this->db->getQueryBuilder();
85
		$query = $qb
0 ignored issues
show
Unused Code introduced by
The assignment to $query is dead and can be removed.
Loading history...
86
			->select('f.id', 'f.person', 'f.descriptor')
87
			->from('face_recognition_faces', 'f')
88
			->innerJoin('f', 'face_recognition_images' ,'i', $qb->expr()->eq('f.image', 'i.id'))
89
			->where($qb->expr()->eq('user', $qb->createParameter('user')))
90
			->andWhere($qb->expr()->eq('model', $qb->createParameter('model')))
91
			->setParameter('user', $userId)
92
			->setParameter('model', $model);
93
		$faces = $this->frFindEntities($qb);
94
		return $faces;
95
	}
96
97
	public function findFacesFromPerson(string $userId, int $personId, int $model, $limit = null, $offset = null): array {
98
		$qb = $this->db->getQueryBuilder();
99
		$qb->select('f.id', 'f.image', 'f.person')
100
			->from('face_recognition_faces', 'f')
101
			->innerJoin('f', 'face_recognition_images' ,'i', $qb->expr()->eq('f.image', 'i.id'))
102
			->where($qb->expr()->eq('user', $qb->createNamedParameter($userId)))
103
			->andWhere($qb->expr()->eq('person', $qb->createNamedParameter($personId)))
104
			->andWhere($qb->expr()->eq('model', $qb->createNamedParameter($model)));
105
106
		$qb->setMaxResults($limit);
107
		$qb->setFirstResult($offset);
108
109
		$faces = $this->findEntities($qb);
110
		return $faces;
111
	}
112
113
114
	public function getPersonOnFile(string $userId, int $personId, int $fileId, int $model): array {
115
		$qb = $this->db->getQueryBuilder();
116
		$qb->select('f.id', 'left', 'right', 'top', 'bottom')
117
			->from('face_recognition_faces', 'f')
118
			->innerJoin('f', 'face_recognition_persons' ,'p', $qb->expr()->eq('f.person', 'p.id'))
119
			->innerJoin('f', 'face_recognition_images' ,'i', $qb->expr()->eq('f.image', 'i.id'))
120
			->where($qb->expr()->eq('p.user', $qb->createParameter('user')))
121
			->andWhere($qb->expr()->eq('person', $qb->createParameter('person')))
122
			->andWhere($qb->expr()->eq('file', $qb->createParameter('file_id')))
123
			->andWhere($qb->expr()->eq('model', $qb->createParameter('model')))
124
			->andWhere($qb->expr()->eq('p.is_valid', $qb->createParameter('is_valid')))
125
			->setParameter('user', $userId)
126
			->setParameter('person', $personId)
127
			->setParameter('file_id', $fileId)
128
			->setParameter('model', $model)
129
			->setParameter('is_valid', true);
130
		$faces = $this->frFindEntities($qb);
131
		return $faces;
132
	}
133
134
	/**
135
	 * @param int $imageId Image for which to delete faces for
136
	 */
137
	public function removeFaces(int $imageId) {
138
		$qb = $this->db->getQueryBuilder();
139
		$qb->delete($this->getTableName())
140
			->where($qb->expr()->eq('image', $qb->createNamedParameter($imageId)))
141
			->execute();
142
	}
143
144
	/**
145
	 * Runs a sql query and returns an array of entities
146
	 *
147
	 * todo: stolen from QBMapper. However, this class is in use from 14.0 only.
148
	 * If we use it, we are "locked" ourselves to versions >= 14.0
149
	 *
150
	 * @param IQueryBuilder $query
151
	 * @return Entity[] all fetched entities
152
	 * @since 14.0.0
153
	 */
154
	protected function frFindEntities(IQueryBuilder $query): array {
155
		$cursor = $query->execute();
156
157
		$entities = [];
158
159
		while($row = $cursor->fetch()){
160
			$entities[] = $this->mapRowToEntity($row);
161
		}
162
163
		$cursor->closeCursor();
164
165
		return $entities;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $entities returns an array which contains values of type OCP\AppFramework\Db\Entity which are incompatible with the documented value type OCA\FaceRecognition\Db\Entity.
Loading history...
166
	}
167
168
}
169