Implement ISearchableGroupBackend

Signed-off-by: Claus-Justus Heine <himself@claus-justus-heine.de>
This commit is contained in:
Claus-Justus Heine
2023-08-22 12:35:26 +02:00
parent 662b849ed9
commit 7da80d207a
5 changed files with 115 additions and 12 deletions

View File

@@ -31,7 +31,11 @@ use OCP\Group\Backend\ABackend;
use OCP\Group\Backend\ICountUsersBackend; use OCP\Group\Backend\ICountUsersBackend;
use OCP\Group\Backend\IGroupDetailsBackend; use OCP\Group\Backend\IGroupDetailsBackend;
use OCP\Group\Backend\IIsAdminBackend; use OCP\Group\Backend\IIsAdminBackend;
use OCP\Group\Backend\ISearchableGroupBackend;
use OCP\ILogger; use OCP\ILogger;
use OCP\IUserManager;
use OC\User\LazyUser;
/** /**
* The SQL group backend manager. * The SQL group backend manager.
@@ -41,7 +45,8 @@ use OCP\ILogger;
final class GroupBackend extends ABackend implements final class GroupBackend extends ABackend implements
ICountUsersBackend, ICountUsersBackend,
IGroupDetailsBackend, IGroupDetailsBackend,
IIsAdminBackend IIsAdminBackend,
ISearchableGroupBackend
{ {
const USER_SQL_GID = "user_sql"; const USER_SQL_GID = "user_sql";
@@ -354,16 +359,16 @@ final class GroupBackend extends ABackend implements
["app" => $this->appName] ["app" => $this->appName]
); );
$cacheKey = self::class . "group_users_" . $gid . "_" . $search . "_" $cacheKey = self::class . "group_uids_" . $gid . "_" . $search . "_"
. $limit . "_" . $offset; . $limit . "_" . $offset;
$users = $this->cache->get($cacheKey); $uids = $this->cache->get($cacheKey);
if (!is_null($users)) { if (!is_null($uids)) {
$this->logger->debug( $this->logger->debug(
"Returning from cache usersInGroup($gid, $search, $limit, $offset): count(" "Returning from cache usersInGroup($gid, $search, $limit, $offset): count("
. count($users) . ")", ["app" => $this->appName] . count($uids) . ")", ["app" => $this->appName]
); );
return $users; return $uids;
} }
$uids = $this->groupRepository->findAllUidsBySearchTerm( $uids = $this->groupRepository->findAllUidsBySearchTerm(
@@ -383,6 +388,50 @@ final class GroupBackend extends ABackend implements
return $uids; return $uids;
} }
/**
* @inheritdoc
*/
public function searchInGroup(string $gid, string $search = '', int $limit = -1, int $offset = 0): array
{
$this->logger->debug(
"Entering searchInGroup($gid, $search, $limit, $offset)",
["app" => $this->appName]
);
$cacheKey = self::class . "group_users_" . $gid . "_" . $search . "_"
. $limit . "_" . $offset;
$names = $this->cache->get($cacheKey);
if ($names === null) {
$names = $this->groupRepository->findAllUsersBySearchTerm(
$this->substituteGid($gid), "%" . $search . "%", $limit, $offset
);
if ($names === false) {
return [];
}
$this->cache->set($cacheKey, $names);
$this->logger->debug(
"Using from DB searchInGroup($gid, $search, $limit, $offset): count("
. count($names) . ")", ["app" => $this->appName]
);
} else {
$this->logger->debug(
"Using from cache searchInGroup($gid, $search, $limit, $offset): count("
. count($names) . ")", ["app" => $this->appName]
);
}
$users = [];
$userManager = \OCP\Server::get(IUserManager::class);
foreach ($names as $uid => $name) {
$users[$uid] = new LazyUser($uid, $userManager, $name);
}
return $users;
}
/** /**
* @inheritdoc * @inheritdoc
*/ */

View File

@@ -32,6 +32,7 @@ final class Query
const COUNT_GROUPS = "count_groups"; const COUNT_GROUPS = "count_groups";
const COUNT_USERS = "count_users"; const COUNT_USERS = "count_users";
const FIND_GROUP = "find_group"; const FIND_GROUP = "find_group";
const FIND_GROUP_UIDS = "find_group_uids";
const FIND_GROUP_USERS = "find_group_users"; const FIND_GROUP_USERS = "find_group_users";
const FIND_GROUPS = "find_groups"; const FIND_GROUPS = "find_groups";
const FIND_USER_BY_UID = "find_user_by_uid"; const FIND_USER_BY_UID = "find_user_by_uid";

View File

@@ -223,6 +223,27 @@ class DataQuery
return $result->fetchFirstColumn(); return $result->fetchFirstColumn();
} }
/**
* Fetch values from all columns which the given query returns.
*
* @param string $queryName The query to execute.
* @param array $params The query parameters to bind.
* @param int $limit Results limit. Defaults to -1 (no limit).
* @param int $offset Results offset. Defaults to 0.
*
* @return array|bool Queried column or FALSE on failure.
*/
public function queryColumns(
$queryName, $params = [], $limit = -1, $offset = 0
) {
$result = $this->execQuery($queryName, $params, $limit, $offset);
if ($result === false) {
return false;
}
return $result->fetchAll();
}
/** /**
* Fetch entity returned by the given query. * Fetch entity returned by the given query.
* *

View File

@@ -154,14 +154,23 @@ class QueryProvider implements \ArrayAccess
"FROM $group g " . "FROM $group g " .
"WHERE g.$gGID = :$gidParam", "WHERE g.$gGID = :$gidParam",
Query::FIND_GROUP_USERS => Query::FIND_GROUP_UIDS =>
"SELECT DISTINCT ug.$ugUID AS uid " . "SELECT DISTINCT u.$uUID AS uid " .
"FROM $userGroup ug " . "FROM $user u " .
"LEFT JOIN $user u ON u.$uUID = ug.$ugUID " . "LEFT JOIN $userGroup ug ON u.$uUID = ug.$ugUID " .
"WHERE ug.$ugGID LIKE :$gidParam " . "WHERE ug.$ugGID LIKE :$gidParam " .
"AND ug.$ugUID LIKE :$searchParam " . "AND u.$uUID LIKE :$searchParam " .
(empty($uDisabled) ? "" : "AND NOT u.$uDisabled ") . (empty($uDisabled) ? "" : "AND NOT u.$uDisabled ") .
"ORDER BY ug.$ugUID", "ORDER BY u.$uUID",
Query::FIND_GROUP_USERS =>
"SELECT DISTINCT u.$uUID AS uid, u.$uName AS name " .
"FROM $user u " .
"LEFT JOIN $userGroup ug ON u.$uUID = ug.$ugUID " .
"WHERE ug.$ugGID LIKE :$gidParam " .
"AND u.$uUID LIKE :$searchParam " .
(empty($uDisabled) ? "" : "AND NOT u.$uDisabled ") .
"ORDER BY u.$uUID",
Query::FIND_GROUPS => Query::FIND_GROUPS =>
"SELECT $groupColumns " . "SELECT $groupColumns " .

View File

@@ -92,10 +92,33 @@ class GroupRepository
$gid, $search = "", $limit = -1, $offset = 0 $gid, $search = "", $limit = -1, $offset = 0
) { ) {
return $this->dataQuery->queryColumn( return $this->dataQuery->queryColumn(
Query::FIND_GROUP_UIDS,
[Query::GID_PARAM => $gid, Query::SEARCH_PARAM => $search], $limit,
$offset
);
}
/**
* Get a list of all user IDs and their display-name belonging to the group.
*
* @param string $gid The group ID.
* @param string $search The UID search term. Defaults to "" (empty string).
* @param int $limit (optional) Results limit.
* Defaults to -1 (no limit).
* @param int $offset (optional) Results offset. Defaults to 0.
*
* @return array<string, string> Array of display-names indexed by UIDs belonging to the group
* or FALSE on failure.
*/
public function findAllUsersBySearchTerm(
$gid, $search = "", $limit = -1, $offset = 0
) {
$data = $this->dataQuery->queryColumns(
Query::FIND_GROUP_USERS, Query::FIND_GROUP_USERS,
[Query::GID_PARAM => $gid, Query::SEARCH_PARAM => $search], $limit, [Query::GID_PARAM => $gid, Query::SEARCH_PARAM => $search], $limit,
$offset $offset
); );
return array_column($data, QUERY::NAME_PARAM, Query::UID_PARAM);
} }
/** /**