mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-15 22:13:08 +00:00
Merge pull request #9125 from tdonohue/add_isNotMemberOf_endpoints
Add `isNotMemberOf` searches for Groups and EPersons (for improved performance on Edit Group pages)
This commit is contained in:
@@ -83,13 +83,14 @@ public abstract class AbstractHibernateDSODAO<T extends DSpaceObject> extends Ab
|
||||
if (CollectionUtils.isNotEmpty(metadataFields) || StringUtils.isNotBlank(additionalWhere)) {
|
||||
//Add the where query on metadata
|
||||
query.append(" WHERE ");
|
||||
// Group the 'OR' clauses below in outer parentheses, e.g. "WHERE (clause1 OR clause2 OR clause3)".
|
||||
// Grouping these 'OR' clauses allows for later code to append 'AND' clauses without unexpected behaviors
|
||||
query.append("(");
|
||||
for (int i = 0; i < metadataFields.size(); i++) {
|
||||
MetadataField metadataField = metadataFields.get(i);
|
||||
if (StringUtils.isNotBlank(operator)) {
|
||||
query.append(" (");
|
||||
query.append("lower(STR(" + metadataField.toString()).append(".value)) ").append(operator)
|
||||
.append(" lower(:queryParam)");
|
||||
query.append(")");
|
||||
if (i < metadataFields.size() - 1) {
|
||||
query.append(" OR ");
|
||||
}
|
||||
@@ -102,6 +103,7 @@ public abstract class AbstractHibernateDSODAO<T extends DSpaceObject> extends Ab
|
||||
}
|
||||
query.append(additionalWhere);
|
||||
}
|
||||
query.append(")");
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -184,32 +184,98 @@ public class EPersonServiceImpl extends DSpaceObjectServiceImpl<EPerson> impleme
|
||||
|
||||
@Override
|
||||
public List<EPerson> search(Context context, String query, int offset, int limit) throws SQLException {
|
||||
try {
|
||||
List<EPerson> ePerson = new ArrayList<>();
|
||||
EPerson person = find(context, UUID.fromString(query));
|
||||
if (person != null) {
|
||||
ePerson.add(person);
|
||||
}
|
||||
return ePerson;
|
||||
} catch (IllegalArgumentException e) {
|
||||
List<EPerson> ePersons = new ArrayList<>();
|
||||
UUID uuid = UUIDUtils.fromString(query);
|
||||
if (uuid == null) {
|
||||
// Search by firstname & lastname (NOTE: email will also be included automatically)
|
||||
MetadataField firstNameField = metadataFieldService.findByElement(context, "eperson", "firstname", null);
|
||||
MetadataField lastNameField = metadataFieldService.findByElement(context, "eperson", "lastname", null);
|
||||
if (StringUtils.isBlank(query)) {
|
||||
query = null;
|
||||
}
|
||||
return ePersonDAO.search(context, query, Arrays.asList(firstNameField, lastNameField),
|
||||
Arrays.asList(firstNameField, lastNameField), offset, limit);
|
||||
ePersons = ePersonDAO.search(context, query, Arrays.asList(firstNameField, lastNameField),
|
||||
Arrays.asList(firstNameField, lastNameField), offset, limit);
|
||||
} else {
|
||||
// Search by UUID
|
||||
EPerson person = find(context, uuid);
|
||||
if (person != null) {
|
||||
ePersons.add(person);
|
||||
}
|
||||
}
|
||||
return ePersons;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int searchResultCount(Context context, String query) throws SQLException {
|
||||
MetadataField firstNameField = metadataFieldService.findByElement(context, "eperson", "firstname", null);
|
||||
MetadataField lastNameField = metadataFieldService.findByElement(context, "eperson", "lastname", null);
|
||||
if (StringUtils.isBlank(query)) {
|
||||
query = null;
|
||||
int result = 0;
|
||||
UUID uuid = UUIDUtils.fromString(query);
|
||||
if (uuid == null) {
|
||||
// Count results found by firstname & lastname (email is also included automatically)
|
||||
MetadataField firstNameField = metadataFieldService.findByElement(context, "eperson", "firstname", null);
|
||||
MetadataField lastNameField = metadataFieldService.findByElement(context, "eperson", "lastname", null);
|
||||
if (StringUtils.isBlank(query)) {
|
||||
query = null;
|
||||
}
|
||||
result = ePersonDAO.searchResultCount(context, query, Arrays.asList(firstNameField, lastNameField));
|
||||
} else {
|
||||
// Search by UUID
|
||||
EPerson person = find(context, uuid);
|
||||
if (person != null) {
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
return ePersonDAO.searchResultCount(context, query, Arrays.asList(firstNameField, lastNameField));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EPerson> searchNonMembers(Context context, String query, Group excludeGroup, int offset, int limit)
|
||||
throws SQLException {
|
||||
List<EPerson> ePersons = new ArrayList<>();
|
||||
UUID uuid = UUIDUtils.fromString(query);
|
||||
if (uuid == null) {
|
||||
// Search by firstname & lastname (NOTE: email will also be included automatically)
|
||||
MetadataField firstNameField = metadataFieldService.findByElement(context, "eperson", "firstname", null);
|
||||
MetadataField lastNameField = metadataFieldService.findByElement(context, "eperson", "lastname", null);
|
||||
if (StringUtils.isBlank(query)) {
|
||||
query = null;
|
||||
}
|
||||
ePersons = ePersonDAO.searchNotMember(context, query, Arrays.asList(firstNameField, lastNameField),
|
||||
excludeGroup, Arrays.asList(firstNameField, lastNameField),
|
||||
offset, limit);
|
||||
} else {
|
||||
// Search by UUID
|
||||
EPerson person = find(context, uuid);
|
||||
// Verify EPerson is NOT a member of the given excludeGroup before adding
|
||||
if (person != null && !groupService.isDirectMember(excludeGroup, person)) {
|
||||
ePersons.add(person);
|
||||
}
|
||||
}
|
||||
|
||||
return ePersons;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int searchNonMembersCount(Context context, String query, Group excludeGroup) throws SQLException {
|
||||
int result = 0;
|
||||
UUID uuid = UUIDUtils.fromString(query);
|
||||
if (uuid == null) {
|
||||
// Count results found by firstname & lastname (email is also included automatically)
|
||||
MetadataField firstNameField = metadataFieldService.findByElement(context, "eperson", "firstname", null);
|
||||
MetadataField lastNameField = metadataFieldService.findByElement(context, "eperson", "lastname", null);
|
||||
if (StringUtils.isBlank(query)) {
|
||||
query = null;
|
||||
}
|
||||
result = ePersonDAO.searchNotMemberCount(context, query, Arrays.asList(firstNameField, lastNameField),
|
||||
excludeGroup);
|
||||
} else {
|
||||
// Search by UUID
|
||||
EPerson person = find(context, uuid);
|
||||
// Verify EPerson is NOT a member of the given excludeGroup before counting
|
||||
if (person != null && !groupService.isDirectMember(excludeGroup, person)) {
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -460,17 +460,17 @@ public class GroupServiceImpl extends DSpaceObjectServiceImpl<Group> implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Group> search(Context context, String groupIdentifier) throws SQLException {
|
||||
return search(context, groupIdentifier, -1, -1);
|
||||
public List<Group> search(Context context, String query) throws SQLException {
|
||||
return search(context, query, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Group> search(Context context, String groupIdentifier, int offset, int limit) throws SQLException {
|
||||
public List<Group> search(Context context, String query, int offset, int limit) throws SQLException {
|
||||
List<Group> groups = new ArrayList<>();
|
||||
UUID uuid = UUIDUtils.fromString(groupIdentifier);
|
||||
UUID uuid = UUIDUtils.fromString(query);
|
||||
if (uuid == null) {
|
||||
//Search by group name
|
||||
groups = groupDAO.findByNameLike(context, groupIdentifier, offset, limit);
|
||||
groups = groupDAO.findByNameLike(context, query, offset, limit);
|
||||
} else {
|
||||
//Search by group id
|
||||
Group group = find(context, uuid);
|
||||
@@ -483,12 +483,12 @@ public class GroupServiceImpl extends DSpaceObjectServiceImpl<Group> implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public int searchResultCount(Context context, String groupIdentifier) throws SQLException {
|
||||
public int searchResultCount(Context context, String query) throws SQLException {
|
||||
int result = 0;
|
||||
UUID uuid = UUIDUtils.fromString(groupIdentifier);
|
||||
UUID uuid = UUIDUtils.fromString(query);
|
||||
if (uuid == null) {
|
||||
//Search by group name
|
||||
result = groupDAO.countByNameLike(context, groupIdentifier);
|
||||
result = groupDAO.countByNameLike(context, query);
|
||||
} else {
|
||||
//Search by group id
|
||||
Group group = find(context, uuid);
|
||||
@@ -500,6 +500,44 @@ public class GroupServiceImpl extends DSpaceObjectServiceImpl<Group> implements
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Group> searchNonMembers(Context context, String query, Group excludeParentGroup,
|
||||
int offset, int limit) throws SQLException {
|
||||
List<Group> groups = new ArrayList<>();
|
||||
UUID uuid = UUIDUtils.fromString(query);
|
||||
if (uuid == null) {
|
||||
// Search by group name
|
||||
groups = groupDAO.findByNameLikeAndNotMember(context, query, excludeParentGroup, offset, limit);
|
||||
} else if (!uuid.equals(excludeParentGroup.getID())) {
|
||||
// Search by group id
|
||||
Group group = find(context, uuid);
|
||||
// Verify it is NOT a member of the given excludeParentGroup before adding
|
||||
if (group != null && !isMember(excludeParentGroup, group)) {
|
||||
groups.add(group);
|
||||
}
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int searchNonMembersCount(Context context, String query, Group excludeParentGroup) throws SQLException {
|
||||
int result = 0;
|
||||
UUID uuid = UUIDUtils.fromString(query);
|
||||
if (uuid == null) {
|
||||
// Search by group name
|
||||
result = groupDAO.countByNameLikeAndNotMember(context, query, excludeParentGroup);
|
||||
} else if (!uuid.equals(excludeParentGroup.getID())) {
|
||||
// Search by group id
|
||||
Group group = find(context, uuid);
|
||||
// Verify it is NOT a member of the given excludeParentGroup before adding
|
||||
if (group != null && !isMember(excludeParentGroup, group)) {
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Context context, Group group) throws SQLException {
|
||||
if (group.isPermanent()) {
|
||||
|
@@ -33,11 +33,68 @@ public interface EPersonDAO extends DSpaceObjectDAO<EPerson>, DSpaceObjectLegacy
|
||||
|
||||
public EPerson findByNetid(Context context, String netid) throws SQLException;
|
||||
|
||||
/**
|
||||
* Search all EPersons by the given MetadataField objects, sorting by the given sort fields.
|
||||
* <P>
|
||||
* NOTE: As long as a query is specified, the EPerson's email address is included in the search alongside any given
|
||||
* metadata fields.
|
||||
*
|
||||
* @param context DSpace context
|
||||
* @param query the text to search EPersons for
|
||||
* @param queryFields the metadata fields to search within (email is also included automatically)
|
||||
* @param sortFields the metadata field(s) to sort the results by
|
||||
* @param offset the position of the first result to return
|
||||
* @param limit how many results return
|
||||
* @return List of matching EPerson objects
|
||||
* @throws SQLException if an error occurs
|
||||
*/
|
||||
public List<EPerson> search(Context context, String query, List<MetadataField> queryFields,
|
||||
List<MetadataField> sortFields, int offset, int limit) throws SQLException;
|
||||
|
||||
/**
|
||||
* Count number of EPersons who match a search on the given metadata fields. This returns the count of total
|
||||
* results for the same query using the 'search()', and therefore can be used to provide pagination.
|
||||
*
|
||||
* @param context DSpace context
|
||||
* @param query the text to search EPersons for
|
||||
* @param queryFields the metadata fields to search within (email is also included automatically)
|
||||
* @return total number of EPersons who match the query
|
||||
* @throws SQLException if an error occurs
|
||||
*/
|
||||
public int searchResultCount(Context context, String query, List<MetadataField> queryFields) throws SQLException;
|
||||
|
||||
/**
|
||||
* Search all EPersons via their firstname, lastname, email (fuzzy match), limited to those EPersons which are NOT
|
||||
* a member of the given group. This may be used to search across EPersons which are valid to add as members to the
|
||||
* given group.
|
||||
*
|
||||
* @param context The DSpace context
|
||||
* @param query the text to search EPersons for
|
||||
* @param queryFields the metadata fields to search within (email is also included automatically)
|
||||
* @param excludeGroup Group to exclude results from. Members of this group will never be returned.
|
||||
* @param offset the position of the first result to return
|
||||
* @param limit how many results return
|
||||
* @return EPersons matching the query (which are not members of the given group)
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
List<EPerson> searchNotMember(Context context, String query, List<MetadataField> queryFields, Group excludeGroup,
|
||||
List<MetadataField> sortFields, int offset, int limit) throws SQLException;
|
||||
|
||||
/**
|
||||
* Count number of EPersons that match a given search (fuzzy match) across firstname, lastname and email. This
|
||||
* search is limited to those EPersons which are NOT a member of the given group. This may be used
|
||||
* (with searchNotMember()) to perform a paginated search across EPersons which are valid to add to the given group.
|
||||
*
|
||||
* @param context The DSpace context
|
||||
* @param query querystring to fuzzy match against.
|
||||
* @param queryFields the metadata fields to search within (email is also included automatically)
|
||||
* @param excludeGroup Group to exclude results from. Members of this group will never be returned.
|
||||
* @return Groups matching the query (which are not members of the given parent)
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
int searchNotMemberCount(Context context, String query, List<MetadataField> queryFields, Group excludeGroup)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Find all EPersons who are a member of one or more of the listed groups in a paginated fashion. This returns
|
||||
* EPersons ordered by UUID.
|
||||
|
@@ -135,6 +135,38 @@ public interface GroupDAO extends DSpaceObjectDAO<Group>, DSpaceObjectLegacySupp
|
||||
*/
|
||||
int countByNameLike(Context context, String groupName) throws SQLException;
|
||||
|
||||
/**
|
||||
* Search all groups via their name (fuzzy match), limited to those groups which are NOT a member of the given
|
||||
* parent group. This may be used to search across groups which are valid to add to the given parent group.
|
||||
* <P>
|
||||
* NOTE: The parent group itself is also excluded from the search.
|
||||
*
|
||||
* @param context The DSpace context
|
||||
* @param groupName Group name to fuzzy match against.
|
||||
* @param excludeParent Parent Group to exclude results from. Groups under this parent will never be returned.
|
||||
* @param offset Offset to use for pagination (-1 to disable)
|
||||
* @param limit The maximum number of results to return (-1 to disable)
|
||||
* @return Groups matching the query (which are not members of the given parent)
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
List<Group> findByNameLikeAndNotMember(Context context, String groupName, Group excludeParent,
|
||||
int offset, int limit) throws SQLException;
|
||||
|
||||
/**
|
||||
* Count number of groups that match a given name (fuzzy match), limited to those groups which are NOT a member of
|
||||
* the given parent group. This may be used (with findByNameLikeAndNotMember()) to search across groups which are
|
||||
* valid to add to the given parent group.
|
||||
* <P>
|
||||
* NOTE: The parent group itself is also excluded from the count.
|
||||
*
|
||||
* @param context The DSpace context
|
||||
* @param groupName Group name to fuzzy match against.
|
||||
* @param excludeParent Parent Group to exclude results from. Groups under this parent will never be returned.
|
||||
* @return Groups matching the query (which are not members of the given parent)
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
int countByNameLikeAndNotMember(Context context, String groupName, Group excludeParent) throws SQLException;
|
||||
|
||||
/**
|
||||
* Find a group by its name and the membership of the given EPerson
|
||||
*
|
||||
|
@@ -70,17 +70,9 @@ public class EPersonDAOImpl extends AbstractHibernateDSODAO<EPerson> implements
|
||||
String queryString = "SELECT " + EPerson.class.getSimpleName()
|
||||
.toLowerCase() + " FROM EPerson as " + EPerson.class
|
||||
.getSimpleName().toLowerCase() + " ";
|
||||
if (query != null) {
|
||||
query = "%" + query.toLowerCase() + "%";
|
||||
}
|
||||
Query hibernateQuery = getSearchQuery(context, queryString, query, queryFields, sortFields, null);
|
||||
|
||||
if (0 <= offset) {
|
||||
hibernateQuery.setFirstResult(offset);
|
||||
}
|
||||
if (0 <= limit) {
|
||||
hibernateQuery.setMaxResults(limit);
|
||||
}
|
||||
Query hibernateQuery = getSearchQuery(context, queryString, query, queryFields, null,
|
||||
sortFields, null, limit, offset);
|
||||
return list(hibernateQuery);
|
||||
}
|
||||
|
||||
@@ -92,6 +84,28 @@ public class EPersonDAOImpl extends AbstractHibernateDSODAO<EPerson> implements
|
||||
return count(hibernateQuery);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EPerson> searchNotMember(Context context, String query, List<MetadataField> queryFields,
|
||||
Group excludeGroup, List<MetadataField> sortFields,
|
||||
int offset, int limit) throws SQLException {
|
||||
String queryString = "SELECT " + EPerson.class.getSimpleName()
|
||||
.toLowerCase() + " FROM EPerson as " + EPerson.class
|
||||
.getSimpleName().toLowerCase() + " ";
|
||||
|
||||
Query hibernateQuery = getSearchQuery(context, queryString, query, queryFields, excludeGroup,
|
||||
sortFields, null, limit, offset);
|
||||
return list(hibernateQuery);
|
||||
}
|
||||
|
||||
public int searchNotMemberCount(Context context, String query, List<MetadataField> queryFields,
|
||||
Group excludeGroup) throws SQLException {
|
||||
String queryString = "SELECT count(*) FROM EPerson as " + EPerson.class.getSimpleName().toLowerCase();
|
||||
|
||||
Query hibernateQuery = getSearchQuery(context, queryString, query, queryFields, excludeGroup,
|
||||
Collections.EMPTY_LIST, null, -1, -1);
|
||||
return count(hibernateQuery);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EPerson> findAll(Context context, MetadataField metadataSortField, String sortField, int pageSize,
|
||||
int offset) throws SQLException {
|
||||
@@ -105,8 +119,8 @@ public class EPersonDAOImpl extends AbstractHibernateDSODAO<EPerson> implements
|
||||
sortFields = Collections.singletonList(metadataSortField);
|
||||
}
|
||||
|
||||
Query query = getSearchQuery(context, queryString, null, ListUtils.EMPTY_LIST, sortFields, sortField, pageSize,
|
||||
offset);
|
||||
Query query = getSearchQuery(context, queryString, null, ListUtils.EMPTY_LIST, null,
|
||||
sortFields, sortField, pageSize, offset);
|
||||
return list(query);
|
||||
|
||||
}
|
||||
@@ -178,43 +192,88 @@ public class EPersonDAOImpl extends AbstractHibernateDSODAO<EPerson> implements
|
||||
protected Query getSearchQuery(Context context, String queryString, String queryParam,
|
||||
List<MetadataField> queryFields, List<MetadataField> sortFields, String sortField)
|
||||
throws SQLException {
|
||||
return getSearchQuery(context, queryString, queryParam, queryFields, sortFields, sortField, -1, -1);
|
||||
return getSearchQuery(context, queryString, queryParam, queryFields, null, sortFields, sortField, -1, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a search query across EPersons based on the given metadata fields and sorted based on the given metadata
|
||||
* field(s) or database column.
|
||||
* <P>
|
||||
* NOTE: the EPerson's email address is included in the search alongside any given metadata fields.
|
||||
*
|
||||
* @param context DSpace Context
|
||||
* @param queryString String which defines the beginning "SELECT" for the SQL query
|
||||
* @param queryParam Actual text being searched for
|
||||
* @param queryFields List of metadata fields to search within
|
||||
* @param excludeGroup Optional Group which should be excluded from search. Any EPersons who are members
|
||||
* of this group will not be included in the results.
|
||||
* @param sortFields Optional List of metadata fields to sort by (should not be specified if sortField is used)
|
||||
* @param sortField Optional database column to sort on (should not be specified if sortFields is used)
|
||||
* @param pageSize how many results return
|
||||
* @param offset the position of the first result to return
|
||||
* @return built Query object
|
||||
* @throws SQLException if error occurs
|
||||
*/
|
||||
protected Query getSearchQuery(Context context, String queryString, String queryParam,
|
||||
List<MetadataField> queryFields, List<MetadataField> sortFields, String sortField,
|
||||
int pageSize, int offset) throws SQLException {
|
||||
|
||||
List<MetadataField> queryFields, Group excludeGroup,
|
||||
List<MetadataField> sortFields, String sortField,
|
||||
int pageSize, int offset) throws SQLException {
|
||||
// Initialize SQL statement using the passed in "queryString"
|
||||
StringBuilder queryBuilder = new StringBuilder();
|
||||
queryBuilder.append(queryString);
|
||||
|
||||
Set<MetadataField> metadataFieldsToJoin = new LinkedHashSet<>();
|
||||
metadataFieldsToJoin.addAll(queryFields);
|
||||
metadataFieldsToJoin.addAll(sortFields);
|
||||
|
||||
// Append necessary join information for MetadataFields we will search within
|
||||
if (!CollectionUtils.isEmpty(metadataFieldsToJoin)) {
|
||||
addMetadataLeftJoin(queryBuilder, EPerson.class.getSimpleName().toLowerCase(), metadataFieldsToJoin);
|
||||
}
|
||||
if (queryParam != null) {
|
||||
// Always append a search on EPerson "email" based on query
|
||||
if (StringUtils.isNotBlank(queryParam)) {
|
||||
addMetadataValueWhereQuery(queryBuilder, queryFields, "like",
|
||||
EPerson.class.getSimpleName().toLowerCase() + ".email like :queryParam");
|
||||
}
|
||||
// If excludeGroup is specified, exclude members of that group from results
|
||||
// This uses a subquery to find the excluded group & verify that it is not in the EPerson list of "groups"
|
||||
if (excludeGroup != null) {
|
||||
// If query params exist, then we already have a WHERE clause (see above) and just need to append an AND
|
||||
if (StringUtils.isNotBlank(queryParam)) {
|
||||
queryBuilder.append(" AND ");
|
||||
} else {
|
||||
// no WHERE clause yet, so this is the start of the WHERE
|
||||
queryBuilder.append(" WHERE ");
|
||||
}
|
||||
queryBuilder.append("(FROM Group g where g.id = :group_id) NOT IN elements (")
|
||||
.append(EPerson.class.getSimpleName().toLowerCase()).append(".groups)");
|
||||
}
|
||||
// Add sort/order by info to query, if specified
|
||||
if (!CollectionUtils.isEmpty(sortFields) || StringUtils.isNotBlank(sortField)) {
|
||||
addMetadataSortQuery(queryBuilder, sortFields, Collections.singletonList(sortField));
|
||||
}
|
||||
|
||||
// Create the final SQL SELECT statement (based on included params above)
|
||||
Query query = createQuery(context, queryBuilder.toString());
|
||||
// Set pagesize & offset for pagination
|
||||
if (pageSize > 0) {
|
||||
query.setMaxResults(pageSize);
|
||||
}
|
||||
if (offset > 0) {
|
||||
query.setFirstResult(offset);
|
||||
}
|
||||
// Set all parameters to the SQL SELECT statement (based on included params above)
|
||||
if (StringUtils.isNotBlank(queryParam)) {
|
||||
query.setParameter("queryParam", "%" + queryParam.toLowerCase() + "%");
|
||||
}
|
||||
for (MetadataField metadataField : metadataFieldsToJoin) {
|
||||
query.setParameter(metadataField.toString(), metadataField.getID());
|
||||
}
|
||||
if (excludeGroup != null) {
|
||||
query.setParameter("group_id", excludeGroup.getID());
|
||||
}
|
||||
|
||||
query.setHint("org.hibernate.cacheable", Boolean.TRUE);
|
||||
|
||||
return query;
|
||||
}
|
||||
|
@@ -164,6 +164,41 @@ public class GroupDAOImpl extends AbstractHibernateDSODAO<Group> implements Grou
|
||||
return count(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Group> findByNameLikeAndNotMember(Context context, String groupName, Group excludeParent,
|
||||
int offset, int limit) throws SQLException {
|
||||
Query query = createQuery(context,
|
||||
"FROM Group " +
|
||||
"WHERE lower(name) LIKE lower(:group_name) " +
|
||||
"AND id != :parent_id " +
|
||||
"AND (from Group g where g.id = :parent_id) not in elements (parentGroups)");
|
||||
query.setParameter("parent_id", excludeParent.getID());
|
||||
query.setParameter("group_name", "%" + StringUtils.trimToEmpty(groupName) + "%");
|
||||
|
||||
if (0 <= offset) {
|
||||
query.setFirstResult(offset);
|
||||
}
|
||||
if (0 <= limit) {
|
||||
query.setMaxResults(limit);
|
||||
}
|
||||
query.setHint("org.hibernate.cacheable", Boolean.TRUE);
|
||||
|
||||
return list(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countByNameLikeAndNotMember(Context context, String groupName, Group excludeParent) throws SQLException {
|
||||
Query query = createQuery(context,
|
||||
"SELECT count(*) FROM Group " +
|
||||
"WHERE lower(name) LIKE lower(:group_name) " +
|
||||
"AND id != :parent_id " +
|
||||
"AND (from Group g where g.id = :parent_id) not in elements (parentGroups)");
|
||||
query.setParameter("parent_id", excludeParent.getID());
|
||||
query.setParameter("group_name", "%" + StringUtils.trimToEmpty(groupName) + "%");
|
||||
|
||||
return count(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Context context, Group group) throws SQLException {
|
||||
Query query = getHibernateSession(context)
|
||||
@@ -213,6 +248,7 @@ public class GroupDAOImpl extends AbstractHibernateDSODAO<Group> implements Grou
|
||||
return list(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countByParent(Context context, Group parent) throws SQLException {
|
||||
Query query = createQuery(context, "SELECT count(g) FROM Group g JOIN g.parentGroups pg " +
|
||||
"WHERE pg.id = :parent_id");
|
||||
|
@@ -98,9 +98,9 @@ public interface EPersonService extends DSpaceObjectService<EPerson>, DSpaceObje
|
||||
*
|
||||
* @param context The relevant DSpace Context.
|
||||
* @param query The search string
|
||||
* @param offset Inclusive offset
|
||||
* @param offset Inclusive offset (the position of the first result to return)
|
||||
* @param limit Maximum number of matches returned
|
||||
* @return array of EPerson objects
|
||||
* @return List of matching EPerson objects
|
||||
* @throws SQLException An exception that provides information on a database access error or other errors.
|
||||
*/
|
||||
public List<EPerson> search(Context context, String query, int offset, int limit)
|
||||
@@ -118,6 +118,34 @@ public interface EPersonService extends DSpaceObjectService<EPerson>, DSpaceObje
|
||||
public int searchResultCount(Context context, String query)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Find the EPersons that match the search query which are NOT currently members of the given Group. The search
|
||||
* query is run against firstname, lastname or email.
|
||||
*
|
||||
* @param context DSpace context
|
||||
* @param query The search string
|
||||
* @param excludeGroup Group to exclude results from. Members of this group will never be returned.
|
||||
* @param offset Inclusive offset (the position of the first result to return)
|
||||
* @param limit Maximum number of matches returned
|
||||
* @return List of matching EPerson objects
|
||||
* @throws SQLException if error
|
||||
*/
|
||||
List<EPerson> searchNonMembers(Context context, String query, Group excludeGroup,
|
||||
int offset, int limit) throws SQLException;
|
||||
|
||||
/**
|
||||
* Returns the total number of EPersons that match the search query which are NOT currently members of the given
|
||||
* Group. The search query is run against firstname, lastname or email. Can be used with searchNonMembers() to
|
||||
* support pagination
|
||||
*
|
||||
* @param context DSpace context
|
||||
* @param query The search string
|
||||
* @param excludeGroup Group to exclude results from. Members of this group will never be returned.
|
||||
* @return List of matching EPerson objects
|
||||
* @throws SQLException if error
|
||||
*/
|
||||
int searchNonMembersCount(Context context, String query, Group excludeGroup) throws SQLException;
|
||||
|
||||
/**
|
||||
* Find all the {@code EPerson}s in a specific order by field.
|
||||
* The sortable fields are:
|
||||
|
@@ -261,37 +261,67 @@ public interface GroupService extends DSpaceObjectService<Group>, DSpaceObjectLe
|
||||
public List<Group> findAll(Context context, int sortField) throws SQLException;
|
||||
|
||||
/**
|
||||
* Find the groups that match the search query across eperson_group_id or name
|
||||
* Find the Groups that match the query across both Group name and Group ID. This is an unpaginated search,
|
||||
* which means it will load all matching groups into memory at once. This may provide POOR PERFORMANCE when a large
|
||||
* number of groups are matched.
|
||||
*
|
||||
* @param context DSpace context
|
||||
* @param groupIdentifier The group name or group ID
|
||||
* @return array of Group objects
|
||||
* @param context DSpace context
|
||||
* @param query The search string used to search across group name or group ID
|
||||
* @return List of matching Group objects
|
||||
* @throws SQLException if error
|
||||
*/
|
||||
public List<Group> search(Context context, String groupIdentifier) throws SQLException;
|
||||
List<Group> search(Context context, String query) throws SQLException;
|
||||
|
||||
/**
|
||||
* Find the groups that match the search query across eperson_group_id or name
|
||||
* Find the Groups that match the query across both Group name and Group ID. This method supports pagination,
|
||||
* which provides better performance than the above non-paginated search() method.
|
||||
*
|
||||
* @param context DSpace context
|
||||
* @param groupIdentifier The group name or group ID
|
||||
* @param offset Inclusive offset
|
||||
* @param limit Maximum number of matches returned
|
||||
* @return array of Group objects
|
||||
* @param context DSpace context
|
||||
* @param query The search string used to search across group name or group ID
|
||||
* @param offset Inclusive offset (the position of the first result to return)
|
||||
* @param limit Maximum number of matches returned
|
||||
* @return List of matching Group objects
|
||||
* @throws SQLException if error
|
||||
*/
|
||||
public List<Group> search(Context context, String groupIdentifier, int offset, int limit) throws SQLException;
|
||||
List<Group> search(Context context, String query, int offset, int limit) throws SQLException;
|
||||
|
||||
/**
|
||||
* Returns the total number of groups returned by a specific query, without the overhead
|
||||
* of creating the Group objects to store the results.
|
||||
* Returns the total number of Groups returned by a specific query. Search is performed based on Group name
|
||||
* and Group ID. May be used with search() above to support pagination of matching Groups.
|
||||
*
|
||||
* @param context DSpace context
|
||||
* @param query The search string
|
||||
* @param query The search string used to search across group name or group ID
|
||||
* @return the number of groups matching the query
|
||||
* @throws SQLException if error
|
||||
*/
|
||||
public int searchResultCount(Context context, String query) throws SQLException;
|
||||
int searchResultCount(Context context, String query) throws SQLException;
|
||||
|
||||
/**
|
||||
* Find the groups that match the search query which are NOT currently members (subgroups)
|
||||
* of the given parentGroup
|
||||
*
|
||||
* @param context DSpace context
|
||||
* @param query The search string used to search across group name or group ID
|
||||
* @param excludeParentGroup Parent group to exclude results from
|
||||
* @param offset Inclusive offset (the position of the first result to return)
|
||||
* @param limit Maximum number of matches returned
|
||||
* @return List of matching Group objects
|
||||
* @throws SQLException if error
|
||||
*/
|
||||
List<Group> searchNonMembers(Context context, String query, Group excludeParentGroup,
|
||||
int offset, int limit) throws SQLException;
|
||||
|
||||
/**
|
||||
* Returns the total number of groups that match the search query which are NOT currently members (subgroups)
|
||||
* of the given parentGroup. Can be used with searchNonMembers() to support pagination.
|
||||
*
|
||||
* @param context DSpace context
|
||||
* @param query The search string used to search across group name or group ID
|
||||
* @param excludeParentGroup Parent group to exclude results from
|
||||
* @return the number of Groups matching the query
|
||||
* @throws SQLException if error
|
||||
*/
|
||||
int searchNonMembersCount(Context context, String query, Group excludeParentGroup) throws SQLException;
|
||||
|
||||
/**
|
||||
* Return true if group has no direct or indirect members
|
||||
|
Reference in New Issue
Block a user