mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-07-04 08:28:44 +02:00
More flexible delete and query api (#1790)
Replaces the filter and delete by repository api's with a more flexible api, which allows to filter and delete by any id part.
This commit is contained in:
@@ -94,7 +94,7 @@ public class RepositoryIndexer implements Indexer<Repository> {
|
||||
if (Repository.class.equals(index.getDetails().getType())) {
|
||||
index.delete().byId(Id.of(Repository.class, repository.getId()));
|
||||
} else {
|
||||
index.delete().byRepository(repository);
|
||||
index.delete().by(Repository.class, repository).execute();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,10 +24,12 @@
|
||||
|
||||
package sonia.scm.search;
|
||||
|
||||
import sonia.scm.repository.Repository;
|
||||
|
||||
final class FieldNames {
|
||||
private FieldNames(){}
|
||||
|
||||
static final String ID = "_id";
|
||||
static final String REPOSITORY = "_repository";
|
||||
static final String REPOSITORY = Names.field(Repository.class);
|
||||
static final String PERMISSION = "_permission";
|
||||
}
|
||||
|
||||
@@ -31,17 +31,18 @@ import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.StringField;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static sonia.scm.search.FieldNames.ID;
|
||||
import static sonia.scm.search.FieldNames.PERMISSION;
|
||||
import static sonia.scm.search.FieldNames.REPOSITORY;
|
||||
|
||||
class LuceneIndex<T> implements Index<T>, AutoCloseable {
|
||||
|
||||
@@ -127,8 +128,8 @@ class LuceneIndex<T> implements Index<T>, AutoCloseable {
|
||||
@Override
|
||||
public void byId(Id<T> id) {
|
||||
try {
|
||||
long count = writer.deleteDocuments(idTerm(id));
|
||||
LOG.debug("delete {} document(s) by id {} from index {}", count, id, details);
|
||||
LOG.debug("delete document(s) by id {} from index {}", id, details);
|
||||
writer.deleteDocuments(idTerm(id));
|
||||
} catch (IOException e) {
|
||||
throw new SearchEngineException("failed to delete document from index", e);
|
||||
}
|
||||
@@ -137,26 +138,43 @@ class LuceneIndex<T> implements Index<T>, AutoCloseable {
|
||||
@Override
|
||||
public void all() {
|
||||
try {
|
||||
long count = writer.deleteAll();
|
||||
LOG.debug("deleted all {} documents from index {}", count, details);
|
||||
LOG.debug("deleted all documents from index {}", details);
|
||||
writer.deleteAll();
|
||||
} catch (IOException ex) {
|
||||
throw new SearchEngineException("failed to delete documents by type " + searchableType.getName() + " from index", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void byRepository(String repositoryId) {
|
||||
public DeleteBy by(Class<?> type, String id) {
|
||||
return new LuceneDeleteBy(type, id);
|
||||
}
|
||||
}
|
||||
|
||||
private class LuceneDeleteBy implements DeleteBy {
|
||||
|
||||
private final Map<Class<?>, String> map = new HashMap<>();
|
||||
|
||||
private LuceneDeleteBy(Class<?> type, String id) {
|
||||
map.put(type, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeleteBy and(Class<?> type, String id) {
|
||||
map.put(type, id);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
Query query = Queries.filterQuery(map);
|
||||
try {
|
||||
long count = writer.deleteDocuments(repositoryTerm(repositoryId));
|
||||
LOG.debug("deleted {} documents by repository {} from index {}", count, repositoryId, details);
|
||||
} catch (IOException ex) {
|
||||
throw new SearchEngineException("failed to delete documents by repository " + repositoryId + " from index", ex);
|
||||
LOG.debug("delete document(s) by query {} from index {}", query, details);
|
||||
writer.deleteDocuments(query);
|
||||
} catch (IOException e) {
|
||||
throw new SearchEngineException("failed to delete document from index", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private Term repositoryTerm(String repositoryId) {
|
||||
return new Term(REPOSITORY, repositoryId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,4 +48,8 @@ final class Names {
|
||||
}
|
||||
return nameFromAnnotation;
|
||||
}
|
||||
|
||||
public static String field(Class<?> type) {
|
||||
return "_" + create(type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.lucene.search.BooleanClause.Occur.MUST;
|
||||
|
||||
@@ -38,18 +38,30 @@ final class Queries {
|
||||
private Queries() {
|
||||
}
|
||||
|
||||
private static Query repositoryQuery(String repositoryId) {
|
||||
return new TermQuery(new Term(FieldNames.REPOSITORY, repositoryId));
|
||||
}
|
||||
|
||||
static Query filter(Query query, QueryBuilder.QueryParams params) {
|
||||
Optional<String> repositoryId = params.getRepositoryId();
|
||||
if (repositoryId.isPresent()) {
|
||||
return new BooleanQuery.Builder()
|
||||
.add(query, MUST)
|
||||
.add(repositoryQuery(repositoryId.get()), MUST)
|
||||
.build();
|
||||
Map<Class<?>, String> filters = params.getFilters();
|
||||
if (!filters.isEmpty()) {
|
||||
BooleanQuery.Builder builder = builder(filters);
|
||||
builder.add(query, MUST);
|
||||
return builder.build();
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
static Query filterQuery(Map<Class<?>, String> filters) {
|
||||
return builder(filters).build();
|
||||
}
|
||||
|
||||
private static BooleanQuery.Builder builder(Map<Class<?>, String> filters) {
|
||||
BooleanQuery.Builder builder = new BooleanQuery.Builder();
|
||||
for (Map.Entry<Class<?>, String> e : filters.entrySet()) {
|
||||
Term term = createTerm(e.getKey(), e.getValue());
|
||||
builder.add(new TermQuery(term), MUST);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static Term createTerm(Class<?> type, String id) {
|
||||
return new Term(Names.field(type), id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.google.common.annotations.VisibleForTesting;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -70,6 +71,10 @@ class SharableIndexWriter {
|
||||
return writer.deleteDocuments(term);
|
||||
}
|
||||
|
||||
long deleteDocuments(Query query) throws IOException {
|
||||
return writer.deleteDocuments(query);
|
||||
}
|
||||
|
||||
long deleteAll() throws IOException {
|
||||
return writer.deleteAll();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user