public class LuceneExecutor implements Runnable {\r
\r
\r
- private static final int INDEX_VERSION = 3;\r
+ private static final int INDEX_VERSION = 4;\r
\r
private static final String FIELD_OBJECT_TYPE = "type";\r
private static final String FIELD_ISSUE = "issue";\r
throw new RuntimeException(e);\r
}\r
}\r
-\r
\r
/**\r
* Returns the author for the commit, if this information is available.\r
* @param repositoryName\r
* @param issueId\r
* @throws Exception\r
+ * @return true, if deleted, false if no record was deleted\r
*/\r
- private void deleteIssue(String repositoryName, String issueId) throws Exception {\r
+ private boolean deleteIssue(String repositoryName, String issueId) throws Exception {\r
BooleanQuery query = new BooleanQuery();\r
Term objectTerm = new Term(FIELD_OBJECT_TYPE, SearchObjectType.issue.name());\r
query.add(new TermQuery(objectTerm), Occur.MUST);\r
query.add(new TermQuery(issueidTerm), Occur.MUST);\r
\r
IndexWriter writer = getIndexWriter(repositoryName);\r
+ int numDocsBefore = writer.numDocs();\r
writer.deleteDocuments(query);\r
writer.commit();\r
+ int numDocsAfter = writer.numDocs();\r
+ if (numDocsBefore == numDocsAfter) {\r
+ logger.debug(MessageFormat.format("no records found to delete {0}", query.toString()));\r
+ return false;\r
+ } else {\r
+ logger.debug(MessageFormat.format("deleted {0} records with {1}", numDocsBefore - numDocsAfter, query.toString()));\r
+ return true;\r
+ }\r
}\r
\r
/**\r
* @param branch\r
* @param path\r
* @throws Exception\r
+ * @return true, if deleted, false if no record was deleted\r
*/\r
- private void deleteBlob(String repositoryName, String branch, String path) throws Exception {\r
- BooleanQuery query = new BooleanQuery();\r
- Term objectTerm = new Term(FIELD_OBJECT_TYPE, SearchObjectType.blob.name());\r
- query.add(new TermQuery(objectTerm), Occur.MUST);\r
- Term branchTerm = new Term(FIELD_BRANCH, branch);\r
- query.add(new TermQuery(branchTerm), Occur.MUST);\r
- Term pathTerm = new Term(FIELD_PATH, path);\r
- query.add(new TermQuery(pathTerm), Occur.MUST);\r
+ public boolean deleteBlob(String repositoryName, String branch, String path) throws Exception {\r
+ String pattern = MessageFormat.format("{0}:'{'0} AND {1}:\"'{'1'}'\" AND {2}:\"'{'2'}'\"", FIELD_OBJECT_TYPE, FIELD_BRANCH, FIELD_PATH);\r
+ String q = MessageFormat.format(pattern, SearchObjectType.blob.name(), branch, path);\r
\r
+ BooleanQuery query = new BooleanQuery();\r
+ StandardAnalyzer analyzer = new StandardAnalyzer(LUCENE_VERSION);\r
+ QueryParser qp = new QueryParser(LUCENE_VERSION, FIELD_SUMMARY, analyzer);\r
+ query.add(qp.parse(q), Occur.MUST);\r
+\r
IndexWriter writer = getIndexWriter(repositoryName);\r
- writer.deleteDocuments(query);\r
+ int numDocsBefore = writer.numDocs();\r
+ writer.deleteDocuments(query); \r
writer.commit();\r
+ int numDocsAfter = writer.numDocs();\r
+ if (numDocsBefore == numDocsAfter) {\r
+ logger.debug(MessageFormat.format("no records found to delete {0}", query.toString()));\r
+ return false;\r
+ } else {\r
+ logger.debug(MessageFormat.format("deleted {0} records with {1}", numDocsBefore - numDocsAfter, query.toString()));\r
+ return true;\r
+ }\r
}\r
\r
/**\r
IssueModel issue = IssueUtils.getIssue(repository, issueId);\r
if (issue == null) {\r
// issue was deleted, remove from index\r
- deleteIssue(model.name, issueId);\r
+ if (!deleteIssue(model.name, issueId)) {\r
+ logger.error(MessageFormat.format("Failed to delete issue {0} from Lucene index!", issueId));\r
+ }\r
} else {\r
// issue was updated\r
index(model.name, issue);\r
qp = new QueryParser(LUCENE_VERSION, FIELD_CONTENT, analyzer);\r
qp.setAllowLeadingWildcard(true);\r
query.add(qp.parse(text), Occur.SHOULD);\r
-\r
+ \r
IndexSearcher searcher;\r
if (repositories.length == 1) {\r
// single repository search\r
MultiSourceReader reader = new MultiSourceReader(rdrs);\r
searcher = new IndexSearcher(reader);\r
}\r
+ \r
Query rewrittenQuery = searcher.rewrite(query);\r
+ logger.debug(rewrittenQuery.toString());\r
+\r
TopScoreDocCollector collector = TopScoreDocCollector.create(5000, true);\r
searcher.search(rewrittenQuery, collector);\r
int offset = Math.max(0, (page - 1) * pageSize);\r
package com.gitblit.tests;\r
\r
import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertFalse;\r
+import static org.junit.Assert.assertTrue;\r
\r
import java.util.ArrayList;\r
import java.util.List;\r
import org.eclipse.jgit.lib.Repository;\r
import org.junit.Test;\r
\r
-import com.gitblit.GitBlit;\r
import com.gitblit.LuceneExecutor;\r
import com.gitblit.models.RefModel;\r
import com.gitblit.models.RepositoryModel;\r
import com.gitblit.models.SearchResult;\r
import com.gitblit.utils.FileUtils;\r
import com.gitblit.utils.JGitUtils;\r
-import com.gitblit.utils.StringUtils;\r
\r
/**\r
* Tests Lucene indexing and querying.\r
lucene.close();\r
assertEquals(10, results.size());\r
}\r
+ \r
+ @Test\r
+ public void testDeleteBlobFromIndex() throws Exception {\r
+ // start with a fresh reindex of entire repository\r
+ LuceneExecutor lucene = new LuceneExecutor(null, GitBlitSuite.REPOSITORIES);\r
+ Repository repository = GitBlitSuite.getHelloworldRepository();\r
+ RepositoryModel model = newRepositoryModel(repository);\r
+ lucene.reindex(model, repository);\r
+ \r
+ // now delete a blob\r
+ assertTrue(lucene.deleteBlob(model.name, "refs/heads/master", "java.java"));\r
+ assertFalse(lucene.deleteBlob(model.name, "refs/heads/master", "java.java"));\r
+ }\r
}
\ No newline at end of file