Skip to content

Commit 49a0b19

Browse files
authored
Merge pull request #6550 from LibreSign/backport/6548/stable33
[stable33] fix: reduce N+1
2 parents bed321d + 8227f11 commit 49a0b19

File tree

6 files changed

+111
-26
lines changed

6 files changed

+111
-26
lines changed

lib/Db/IdentifyMethodMapper.php

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,35 @@ public function getIdentifyMethodsFromSignRequestId(int $signRequestId): array {
4747
return $this->methodsBySignRequest[$signRequestId];
4848
}
4949

50+
/**
51+
* @param int[] $signRequestIds
52+
* @return array<int, IdentifyMethod[]>
53+
*/
54+
public function getIdentifyMethodsFromSignRequestIds(array $signRequestIds): array {
55+
if (empty($signRequestIds)) {
56+
return [];
57+
}
58+
59+
$missing = array_diff($signRequestIds, array_keys($this->methodsBySignRequest));
60+
61+
if (!empty($missing)) {
62+
$qb = $this->db->getQueryBuilder();
63+
$qb->select('im.*')
64+
->from('libresign_identify_method', 'im')
65+
->where($qb->expr()->in('im.sign_request_id', $qb->createNamedParameter($missing, IQueryBuilder::PARAM_INT_ARRAY)));
66+
67+
$cursor = $qb->executeQuery();
68+
while ($row = $cursor->fetch()) {
69+
$entity = $this->mapRowToEntity($row);
70+
$signRequestId = $entity->getSignRequestId();
71+
$this->methodsBySignRequest[$signRequestId][] = $entity;
72+
}
73+
$cursor->closeCursor();
74+
}
75+
76+
return array_map(fn ($id) => $this->methodsBySignRequest[$id] ?? [], $signRequestIds);
77+
}
78+
5079
public function neutralizeDeletedUser(string $userId, string $displayName): void {
5180
$update = $this->db->getQueryBuilder();
5281
$qb = $this->db->getQueryBuilder();
@@ -59,8 +88,6 @@ public function neutralizeDeletedUser(string $userId, string $displayName): void
5988
while ($row = $cursor->fetch()) {
6089
if (is_string($row['metadata']) && !empty($row['metadata'])) {
6190
$row['metadata'] = json_decode($row['metadata'], true);
62-
} else {
63-
$row['metadata'] = [];
6491
}
6592
$row['metadata']['deleted_account'] = [
6693
'account' => $userId,

lib/Service/File/EnvelopeAssembler.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,16 @@ public function buildEnvelopeChildData(File $childFile, \OCA\Libresign\Service\F
6060
$fileData->visibleElements = [];
6161

6262
$signRequests = $this->signRequestMapper->getByFileId($childFile->getId());
63+
if (empty($signRequests)) {
64+
return $fileData;
65+
}
66+
$signRequestIds = array_column(array_map(fn ($sr) => ['id' => $sr->getId()], $signRequests), 'id');
67+
$identifyMethodsBatch = $this->identifyMethodService
68+
->setIsRequest(false)
69+
->getIdentifyMethodsFromSignRequestIds($signRequestIds);
70+
6371
foreach ($signRequests as $signRequest) {
64-
$identifyMethods = $this->identifyMethodService
65-
->setIsRequest(false)
66-
->getIdentifyMethodsFromSignRequestId($signRequest->getId());
72+
$identifyMethods = $identifyMethodsBatch[$signRequest->getId()] ?? [];
6773

6874
$email = '';
6975
foreach ($identifyMethods[IdentifyMethodService::IDENTIFY_EMAIL] ?? [] as $identifyMethod) {

lib/Service/File/SignersLoader.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,16 @@ public function loadLibreSignSigners(
4141
return;
4242
}
4343
$signers = $this->signRequestMapper->getByFileId($file->getId());
44+
if (empty($signers)) {
45+
return;
46+
}
47+
$signRequestIds = array_column(array_map(fn ($s) => ['id' => $s->getId()], $signers), 'id');
48+
$identifyMethodsBatch = $this->identifyMethodService
49+
->setIsRequest(false)
50+
->getIdentifyMethodsFromSignRequestIds($signRequestIds);
51+
4452
foreach ($signers as $signer) {
45-
$identifyMethods = $this->identifyMethodService
46-
->setIsRequest(false)
47-
->getIdentifyMethodsFromSignRequestId($signer->getId());
53+
$identifyMethods = $identifyMethodsBatch[$signer->getId()] ?? [];
4854
if (!empty($fileData->signers)) {
4955
$found = array_filter($fileData->signers, function (stdClass $found) use ($identifyMethods) {
5056
if (!isset($found->uid)) {

lib/Service/FileService.php

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -484,13 +484,16 @@ private function getLatestSignedDateFromEnvelope(): ?\DateTime {
484484
$childrenFiles = $this->fileMapper->getChildrenFiles($this->file->getId());
485485
$latestDate = null;
486486

487-
foreach ($childrenFiles as $childFile) {
488-
$signRequests = $this->signRequestMapper->getByFileId($childFile->getId());
489-
foreach ($signRequests as $signRequest) {
490-
$signed = $signRequest->getSigned();
491-
if ($signed && (!$latestDate || $signed > $latestDate)) {
492-
$latestDate = $signed;
493-
}
487+
$childFileIds = array_map(fn ($childFile) => $childFile->getId(), $childrenFiles);
488+
if (empty($childFileIds)) {
489+
return null;
490+
}
491+
492+
$signRequests = $this->signRequestMapper->getByMultipleFileId($childFileIds);
493+
foreach ($signRequests as $signRequest) {
494+
$signed = $signRequest->getSigned();
495+
if ($signed && (!$latestDate || $signed > $latestDate)) {
496+
$latestDate = $signed;
494497
}
495498
}
496499

@@ -556,10 +559,7 @@ public function toArray(): array {
556559
}
557560

558561
private function computeEnvelopeSignersProgress(): void {
559-
if (!$this->file || $this->file->getParentFileId()) {
560-
return;
561-
}
562-
if (empty($this->fileData->signers)) {
562+
if (!$this->file || $this->file->getParentFileId() || empty($this->fileData->signers)) {
563563
return;
564564
}
565565

@@ -568,13 +568,20 @@ private function computeEnvelopeSignersProgress(): void {
568568
return;
569569
}
570570

571-
$signRequestsByFileId = [];
571+
$childFileIds = array_map(fn ($childFile) => $childFile->getId(), $childrenFiles);
572+
$allSignRequests = $this->signRequestMapper->getByMultipleFileId($childFileIds);
573+
574+
$signRequestsByFileId = array_fill_keys($childFileIds, []);
575+
foreach ($allSignRequests as $signRequest) {
576+
$signRequestsByFileId[$signRequest->getFileId()][] = $signRequest;
577+
}
578+
572579
$identifyMethodsBySignRequest = [];
573-
foreach ($childrenFiles as $child) {
574-
$signRequestsByFileId[$child->getId()] = $this->signRequestMapper->getByFileId($child->getId());
575-
foreach ($signRequestsByFileId[$child->getId()] as $sr) {
576-
$identifyMethodsBySignRequest[$sr->getId()] = $this->identifyMethodService->setIsRequest(false)->getIdentifyMethodsFromSignRequestId($sr->getId());
577-
}
580+
if (!empty($allSignRequests)) {
581+
$allSignRequestIds = array_map(fn ($sr) => $sr->getId(), $allSignRequests);
582+
$identifyMethodsBySignRequest = $this->identifyMethodService
583+
->setIsRequest(false)
584+
->getIdentifyMethodsFromSignRequestIds($allSignRequestIds);
578585
}
579586

580587
$this->envelopeProgressService->computeProgress(

lib/Service/IdentifyMethodService.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,39 @@ public function getIdentifyMethodsFromSignRequestId(int $signRequestId): array {
206206
return $return;
207207
}
208208

209+
/**
210+
* @param int[] $signRequestIds
211+
* @return array<int, array<string,array<IIdentifyMethod>>>
212+
*/
213+
public function getIdentifyMethodsFromSignRequestIds(array $signRequestIds): array {
214+
if (empty($signRequestIds)) {
215+
return [];
216+
}
217+
218+
$entitiesBySignRequest = $this->identifyMethodMapper->getIdentifyMethodsFromSignRequestIds($signRequestIds);
219+
220+
foreach ($entitiesBySignRequest as $entities) {
221+
foreach ($entities as $entity) {
222+
$this->setCurrentIdentifyMethod($entity);
223+
$this->getInstanceOfIdentifyMethod($entity->getIdentifierKey(), $entity->getIdentifierValue());
224+
}
225+
}
226+
227+
$results = [];
228+
foreach ($signRequestIds as $signRequestId) {
229+
$results[$signRequestId] = [];
230+
foreach ($this->identifyMethods as $methodName => $list) {
231+
foreach ($list as $method) {
232+
if ($method->getEntity()->getSignRequestId() === $signRequestId) {
233+
$results[$signRequestId][$methodName][] = $method;
234+
}
235+
}
236+
}
237+
}
238+
239+
return $results;
240+
}
241+
209242
public function getIdentifiedMethod(int $signRequestId): IIdentifyMethod {
210243
$matrix = $this->getIdentifyMethodsFromSignRequestId($signRequestId);
211244
[$identifiedMethod, $firstMethod] = $this->findMethodsInMatrix($matrix);

lib/Service/SignerIndexProvider.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,15 @@ public function __construct(
2121
* @return array<string, SignRequest[]>
2222
*/
2323
public function build(array $signRequests): array {
24+
if (empty($signRequests)) {
25+
return [];
26+
}
27+
$signRequestIds = array_column(array_map(fn ($sr) => ['id' => $sr->getId()], $signRequests), 'id');
28+
$identifyMethodsBatch = $this->identifyMethodService->getIdentifyMethodsFromSignRequestIds($signRequestIds);
29+
2430
$index = [];
2531
foreach ($signRequests as $signRequest) {
26-
$identifyMethods = $this->identifyMethodService->getIdentifyMethodsFromSignRequestId($signRequest->getId());
32+
$identifyMethods = $identifyMethodsBatch[$signRequest->getId()] ?? [];
2733
foreach ($identifyMethods as $methodInstances) {
2834
foreach ($methodInstances as $identifyMethod) {
2935
$entity = $identifyMethod->getEntity();

0 commit comments

Comments
 (0)