• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

LibreSign / libresign / 21293358735

23 Jan 2026 04:30PM UTC coverage: 45.267%. First build
21293358735

Pull #6548

github

web-flow
Merge 34dc69686 into 3b6e6d7e8
Pull Request #6548: fix: reduce N+1

33 of 68 new or added lines in 6 files covered. (48.53%)

7446 of 16449 relevant lines covered (45.27%)

4.93 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

23.58
/lib/Db/IdentifyMethodMapper.php
1
<?php
2

3
declare(strict_types=1);
4
/**
5
 * SPDX-FileCopyrightText: 2020-2024 LibreCode coop and contributors
6
 * SPDX-License-Identifier: AGPL-3.0-or-later
7
 */
8

9
namespace OCA\Libresign\Db;
10

11
use OCP\AppFramework\Db\QBMapper;
12
use OCP\Comments\ICommentsManager;
13
use OCP\DB\QueryBuilder\IQueryBuilder;
14
use OCP\IDBConnection;
15

16
/**
17
 * @template-extends QBMapper<IdentifyMethod>
18
 */
19
class IdentifyMethodMapper extends QBMapper {
20
        /**
21
         * @var IdentifyMethod[][]
22
         */
23
        private array $methodsBySignRequest = [];
24
        public function __construct(IDBConnection $db) {
25
                parent::__construct($db, 'libresign_identify_method');
47✔
26
        }
27

28
        /**
29
         * @return IdentifyMethod[]
30
         */
31
        public function getIdentifyMethodsFromSignRequestId(int $signRequestId): array {
32
                if (!empty($this->methodsBySignRequest[$signRequestId])) {
13✔
33
                        return $this->methodsBySignRequest[$signRequestId];
1✔
34
                }
35
                $qb = $this->db->getQueryBuilder();
13✔
36
                $qb->select('im.*')
13✔
37
                        ->from('libresign_identify_method', 'im')
13✔
38
                        ->where(
13✔
39
                                $qb->expr()->eq('im.sign_request_id', $qb->createNamedParameter($signRequestId, IQueryBuilder::PARAM_INT))
13✔
40
                        );
13✔
41
                $cursor = $qb->executeQuery();
13✔
42
                $this->methodsBySignRequest[$signRequestId] = [];
13✔
43
                while ($row = $cursor->fetch()) {
13✔
44
                        /** @var IdentifyMethod */
45
                        $this->methodsBySignRequest[$signRequestId][] = $this->mapRowToEntity($row);
7✔
46
                }
47
                return $this->methodsBySignRequest[$signRequestId];
13✔
48
        }
49

50
        /**
51
         * @param int[] $signRequestIds
52
         * @return array<int, IdentifyMethod[]>
53
         */
54
        public function getIdentifyMethodsFromSignRequestIds(array $signRequestIds): array {
55
                if (empty($signRequestIds)) {
3✔
NEW
56
                        return [];
×
57
                }
58

59
                $missing = array_diff($signRequestIds, array_keys($this->methodsBySignRequest));
3✔
60

61
                if (!empty($missing)) {
3✔
NEW
62
                        $qb = $this->db->getQueryBuilder();
×
NEW
63
                        $qb->select('im.*')
×
NEW
64
                                ->from('libresign_identify_method', 'im')
×
NEW
65
                                ->where($qb->expr()->in('im.sign_request_id', $qb->createNamedParameter($missing, IQueryBuilder::PARAM_INT_ARRAY)));
×
66

NEW
67
                        $cursor = $qb->executeQuery();
×
NEW
68
                        while ($row = $cursor->fetch()) {
×
NEW
69
                                $entity = $this->mapRowToEntity($row);
×
NEW
70
                                $signRequestId = $entity->getSignRequestId();
×
NEW
71
                                $this->methodsBySignRequest[$signRequestId][] = $entity;
×
72
                        }
NEW
73
                        $cursor->closeCursor();
×
74
                }
75

76
                return array_map(fn ($id) => $this->methodsBySignRequest[$id] ?? [], $signRequestIds);
3✔
77
        }
78

79
        public function neutralizeDeletedUser(string $userId, string $displayName): void {
80
                $update = $this->db->getQueryBuilder();
×
81
                $qb = $this->db->getQueryBuilder();
×
82
                $qb->select('im.id')
×
83
                        ->addSelect('im.metadata')
×
84
                        ->from('libresign_identify_method', 'im')
×
85
                        ->where($qb->expr()->in('im.identifier_key', $qb->createNamedParameter(['account', 'email'], IQueryBuilder::PARAM_STR_ARRAY), IQueryBuilder::PARAM_STR_ARRAY))
×
86
                        ->andWhere($qb->expr()->eq('im.identifier_value', $qb->createNamedParameter($userId)));
×
87
                $cursor = $qb->executeQuery();
×
88
                while ($row = $cursor->fetch()) {
×
89
                        if (is_string($row['metadata']) && !empty($row['metadata'])) {
×
90
                                $row['metadata'] = json_decode($row['metadata'], true);
×
91
                        }
92
                        $row['metadata']['deleted_account'] = [
×
93
                                'account' => $userId,
×
94
                                'display_name' => $displayName,
×
95
                        ];
×
96
                        $update->update('libresign_identify_method')
×
97
                                ->set('identifier_value', $update->createNamedParameter(ICommentsManager::DELETED_USER))
×
98
                                ->set('metadata', $update->createNamedParameter($row['metadata'], IQueryBuilder::PARAM_JSON))
×
99
                                ->where($update->expr()->eq('id', $update->createNamedParameter($row['id'])));
×
100
                        $update->executeStatement();
×
101
                }
102
        }
103

104
        public function deleteBySignRequestId(int $signRequestId): void {
105
                $qb = $this->db->getQueryBuilder();
3✔
106
                $qb->delete('libresign_identify_method')
3✔
107
                        ->where(
3✔
108
                                $qb->expr()->eq('sign_request_id', $qb->createNamedParameter($signRequestId, IQueryBuilder::PARAM_INT))
3✔
109
                        )
3✔
110
                        ->executeStatement();
3✔
111
                unset($this->methodsBySignRequest[$signRequestId]);
3✔
112
        }
113

114
        /**
115
         * @return array<string, string>[]
116
         */
117
        public function searchByIdentifierValue(string $search, string $userId, string $method, int $limit = 20, int $offset = 0): array {
118
                $qb = $this->db->getQueryBuilder();
×
119

120
                $latestQb = $this->db->getQueryBuilder();
×
121
                $latestQb->select('im2.identifier_key')
×
122
                        ->addSelect('im2.identifier_value')
×
123
                        ->addSelect($latestQb->func()->max('sr2.created_at', 'created_at'))
×
124
                        ->from('libresign_identify_method', 'im2')
×
125
                        ->join('im2', 'libresign_sign_request', 'sr2',
×
126
                                $latestQb->expr()->eq('sr2.id', 'im2.sign_request_id')
×
127
                        )
×
128
                        ->join('im2', 'libresign_file', 'f2',
×
129
                                $latestQb->expr()->eq('f2.id', 'sr2.file_id')
×
130
                        )
×
131
                        ->where($latestQb->expr()->eq('f2.user_id', $latestQb->createNamedParameter($userId)));
×
132
                if (!empty($method)) {
×
133
                        $latestQb->andWhere($latestQb->expr()->eq('im2.identifier_key', $latestQb->createNamedParameter($method)));
×
134
                }
135
                $latestQb->andWhere(
×
136
                        $latestQb->expr()->orX(
×
137
                                $latestQb->expr()->iLike(
×
138
                                        'im2.identifier_value',
×
139
                                        $latestQb->createNamedParameter('%' . $this->db->escapeLikeParameter($search) . '%')
×
140
                                ),
×
141
                                $latestQb->expr()->iLike(
×
142
                                        'sr2.display_name',
×
143
                                        $latestQb->createNamedParameter('%' . $this->db->escapeLikeParameter($search) . '%')
×
144
                                )
×
145
                        )
×
146
                )
×
147
                        ->groupBy('im2.identifier_key')
×
148
                        ->addGroupBy('im2.identifier_value');
×
149

150
                foreach ($latestQb->getParameters() as $name => $value) {
×
151
                        $qb->setParameter($name, $value);
×
152
                }
153

154
                $qb->select('im.identifier_key', 'im.identifier_value', 'sr.display_name')
×
155
                        ->from('libresign_identify_method', 'im')
×
156
                        ->join('im', $qb->createFunction('(' . $latestQb->getSQL() . ')'), 'latest',
×
157
                                $qb->expr()->andX(
×
158
                                        $qb->expr()->eq('latest.identifier_key', 'im.identifier_key'),
×
159
                                        $qb->expr()->eq('latest.identifier_value', 'im.identifier_value')
×
160
                                )
×
161
                        )
×
162
                        ->join('im', 'libresign_sign_request', 'sr',
×
163
                                $qb->expr()->eq('sr.id', 'im.sign_request_id'),
×
164
                        )
×
165
                        ->where($qb->expr()->neq('im.identifier_value', $qb->createNamedParameter('deleted_users')))
×
166
                        ->setMaxResults($limit)
×
167
                        ->setFirstResult($offset);
×
168

169
                $cursor = $qb->executeQuery();
×
170
                $return = [];
×
171
                while ($row = $cursor->fetch()) {
×
172
                        $return[] = $row;
×
173
                }
174
                return $return;
×
175
        }
176
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc