aboutsummaryrefslogtreecommitdiffstats
path: root/apps/user_ldap/lib
diff options
context:
space:
mode:
authorArthur Schiwon <blizzz@arthur-schiwon.de>2021-01-08 11:54:07 +0100
committerArthur Schiwon <blizzz@arthur-schiwon.de>2021-01-11 13:43:34 +0100
commit45e3261ad5961e78ab919f14ff9234da0ba740b5 (patch)
treeea33f4a3b761acb4edfcf0165d17966ba0126d41 /apps/user_ldap/lib
parent8b656e321bbf358d8074ce8a3976fac5defdece0 (diff)
downloadnextcloud-server-45e3261ad5961e78ab919f14ff9234da0ba740b5.tar.gz
nextcloud-server-45e3261ad5961e78ab919f14ff9234da0ba740b5.zip
respect DB limits limit per statement and query
Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
Diffstat (limited to 'apps/user_ldap/lib')
-rw-r--r--apps/user_ldap/lib/Mapping/AbstractMapping.php51
1 files changed, 45 insertions, 6 deletions
diff --git a/apps/user_ldap/lib/Mapping/AbstractMapping.php b/apps/user_ldap/lib/Mapping/AbstractMapping.php
index f9f2b125d0e..d6b3ed646d3 100644
--- a/apps/user_ldap/lib/Mapping/AbstractMapping.php
+++ b/apps/user_ldap/lib/Mapping/AbstractMapping.php
@@ -30,6 +30,7 @@ namespace OCA\User_LDAP\Mapping;
use Doctrine\DBAL\Exception;
use OC\DB\QueryBuilder\QueryBuilder;
use OCP\DB\IPreparedStatement;
+use OCP\DB\QueryBuilder\IQueryBuilder;
/**
* Class AbstractMapping
@@ -199,19 +200,57 @@ abstract class AbstractMapping {
return $this->cache[$fdn];
}
- public function getListOfIdsByDn(array $fdns): array {
+ protected function prepareListOfIdsQuery(array $dnList): IQueryBuilder {
$qb = $this->dbc->getQueryBuilder();
$qb->select('owncloud_name', 'ldap_dn')
->from($this->getTableName(false))
- ->where($qb->expr()->in('ldap_dn', $qb->createNamedParameter($fdns, QueryBuilder::PARAM_STR_ARRAY)));
- $stmt = $qb->execute();
+ ->where($qb->expr()->in('ldap_dn', $qb->createNamedParameter($dnList, QueryBuilder::PARAM_STR_ARRAY)));
+ return $qb;
+ }
- $results = $stmt->fetchAll(\Doctrine\DBAL\FetchMode::ASSOCIATIVE);
- foreach ($results as $key => $entry) {
- unset($results[$key]);
+ protected function collectResultsFromListOfIdsQuery(IQueryBuilder $qb, array &$results): void {
+ $stmt = $qb->execute();
+ while ($entry = $stmt->fetch(\Doctrine\DBAL\FetchMode::ASSOCIATIVE)) {
$results[$entry['ldap_dn']] = $entry['owncloud_name'];
$this->cache[$entry['ldap_dn']] = $entry['owncloud_name'];
}
+ $stmt->closeCursor();
+ }
+
+ public function getListOfIdsByDn(array $fdns): array {
+ $totalDBParamLimit = 65000;
+ $sliceSize = 1000;
+ $maxSlices = $totalDBParamLimit / $sliceSize;
+ $results = [];
+
+ $slice = 1;
+ $fdnsSlice = count($fdns) > $sliceSize ? array_slice($fdns, 0, $sliceSize) : $fdns;
+ $qb = $this->prepareListOfIdsQuery($fdnsSlice);
+
+ while (isset($fdnsSlice[999])) {
+ // Oracle does not allow more than 1000 values in the IN list,
+ // but allows slicing
+ $slice++;
+ $fdnsSlice = array_slice($fdns, $sliceSize * ($slice - 1), $sliceSize);
+
+ if (!isset($qb)) {
+ $qb = $this->prepareListOfIdsQuery($fdnsSlice);
+ continue;
+ }
+
+ if (!empty($fdnsSlice)) {
+ $qb->orWhere($qb->expr()->in('ldap_dn', $qb->createNamedParameter($fdnsSlice, QueryBuilder::PARAM_STR_ARRAY)));
+ }
+
+ if ($slice % $maxSlices === 0) {
+ $this->collectResultsFromListOfIdsQuery($qb, $results);
+ unset($qb);
+ }
+ }
+
+ if (isset($qb)) {
+ $this->collectResultsFromListOfIdsQuery($qb, $results);
+ }
return $results;
}