package org.sonar.server.project.es;
+import java.util.Date;
import java.util.Iterator;
import javax.annotation.Nullable;
import org.elasticsearch.action.index.IndexRequest;
@Override
protected long doIndex(long lastUpdatedAt) {
- return doIndex(createBulkIndexer(false), (String) null);
+ return doIndex(createBulkIndexer(false), lastUpdatedAt, null);
}
public void index(String projectUuid) {
- index(lastUpdatedAt -> doIndex(createBulkIndexer(false), projectUuid));
+ doIndex(createBulkIndexer(false), 0L, projectUuid);
}
public void deleteProject(String uuid) {
esClient
.prepareDelete(INDEX_PROJECT_MEASURES, TYPE_PROJECT_MEASURES, uuid)
.setRefresh(true)
- .setRouting(uuid)
.get();
}
- private long doIndex(BulkIndexer bulk, @Nullable String projectUuid) {
- DbSession dbSession = dbClient.openSession(false);
- try {
- ProjectMeasuresResultSetIterator rowIt = ProjectMeasuresResultSetIterator.create(dbClient, dbSession, projectUuid);
- doIndex(bulk, rowIt);
+ private long doIndex(BulkIndexer bulk, long lastUpdatedAt, @Nullable String projectUuid) {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ ProjectMeasuresResultSetIterator rowIt = ProjectMeasuresResultSetIterator.create(dbClient, dbSession, lastUpdatedAt, projectUuid);
+ long maxDate = doIndex(bulk, rowIt);
rowIt.close();
- return 0L;
- } finally {
- dbClient.closeSession(dbSession);
+ return maxDate;
}
}
- private static void doIndex(BulkIndexer bulk, Iterator<ProjectMeasuresDoc> docs) {
+ private static long doIndex(BulkIndexer bulk, Iterator<ProjectMeasuresDoc> docs) {
bulk.start();
+ long maxDate = 0L;
while (docs.hasNext()) {
ProjectMeasuresDoc doc = docs.next();
bulk.add(newIndexRequest(doc));
+
+ Date analysisDate = doc.getAnalysedAt();
+ // it's more efficient to sort programmatically than in SQL on some databases (MySQL for instance)
+ maxDate = Math.max(maxDate, analysisDate == null ? 0L : analysisDate.getTime());
}
bulk.stop();
+ return maxDate;
}
private BulkIndexer createBulkIndexer(boolean large) {
"LEFT OUTER JOIN snapshots s ON s.component_uuid=p.uuid AND s.islast=? " +
"WHERE p.enabled=? AND p.scope=? AND p.qualifier=?";
+ private static final String DATE_FILTER = " AND s.created_at>?";
+
private static final String PROJECT_FILTER = " AND p.uuid=?";
private ProjectMeasuresResultSetIterator(PreparedStatement stmt) throws SQLException {
super(stmt);
}
- static ProjectMeasuresResultSetIterator create(DbClient dbClient, DbSession session, @Nullable String projectUuid) {
+ static ProjectMeasuresResultSetIterator create(DbClient dbClient, DbSession session, long afterDate, @Nullable String projectUuid) {
try {
-
String sql = SQL_ALL;
+ sql += afterDate <= 0L ? "" : DATE_FILTER;
sql += projectUuid == null ? "" : PROJECT_FILTER;
PreparedStatement stmt = dbClient.getMyBatis().newScrollingSelectStatement(session, sql);
stmt.setBoolean(1, true);
stmt.setBoolean(2, true);
stmt.setString(3, Scopes.PROJECT);
stmt.setString(4, Qualifiers.PROJECT);
+ int index = 5;
+ if (afterDate > 0L) {
+ stmt.setLong(index, afterDate);
+ index++;
+ }
if (projectUuid != null) {
- stmt.setString(5, projectUuid);
+ stmt.setString(index, projectUuid);
}
return new ProjectMeasuresResultSetIterator(stmt);
} catch (SQLException e) {
.setKey(rs.getString(2))
.setName(rs.getString(3));
long analysisDate = rs.getLong(4);
- doc.setAnalysedAt(analysisDate != 0 ? new Date(analysisDate) : null);
+ doc.setAnalysedAt(rs.wasNull() ? null : new Date(analysisDate));
return doc;
}
}
componentDbTester.insertProjectAndSnapshot(newProjectDto());
componentDbTester.insertProjectAndSnapshot(newProjectDto());
- Map<String, ProjectMeasuresDoc> docsById = createResultSetAndReturnDocsById(project.uuid());
+ Map<String, ProjectMeasuresDoc> docsById = createResultSetAndReturnDocsById(0L, project.uuid());
assertThat(docsById).hasSize(1);
ProjectMeasuresDoc doc = docsById.get(project.uuid());
assertThat(doc.getAnalysedAt()).isNotNull().isEqualTo(new Date(analysis.getCreatedAt()));
}
+ @Test
+ public void return_only_docs_after_date() throws Exception {
+ ComponentDto project1 = newProjectDto();
+ dbClient.componentDao().insert(dbSession, project1);
+ dbClient.snapshotDao().insert(dbSession, newAnalysis(project1).setCreatedAt(1_000_000L));
+ ComponentDto project2 = newProjectDto();
+ dbClient.componentDao().insert(dbSession, project2);
+ dbClient.snapshotDao().insert(dbSession, newAnalysis(project2).setCreatedAt(2_000_000L));
+ dbSession.commit();
+
+ Map<String, ProjectMeasuresDoc> docsById = createResultSetAndReturnDocsById(1_500_000L, null);
+
+ assertThat(docsById).hasSize(1);
+ assertThat(docsById.get(project2.uuid())).isNotNull();
+ }
+
@Test
public void return_nothing_on_unknown_project() throws Exception {
componentDbTester.insertProjectAndSnapshot(newProjectDto());
- Map<String, ProjectMeasuresDoc> docsById = createResultSetAndReturnDocsById("UNKNOWN");
+ Map<String, ProjectMeasuresDoc> docsById = createResultSetAndReturnDocsById(0L, "UNKNOWN");
assertThat(docsById).isEmpty();
}
private Map<String, ProjectMeasuresDoc> createResultSetAndReturnDocsById() {
- return createResultSetAndReturnDocsById(null);
+ return createResultSetAndReturnDocsById(0L, null);
}
- private Map<String, ProjectMeasuresDoc> createResultSetAndReturnDocsById(@Nullable String projectUuid) {
- ProjectMeasuresResultSetIterator it = ProjectMeasuresResultSetIterator.create(dbTester.getDbClient(), dbTester.getSession(), projectUuid);
+ private Map<String, ProjectMeasuresDoc> createResultSetAndReturnDocsById(long date, @Nullable String projectUuid) {
+ ProjectMeasuresResultSetIterator it = ProjectMeasuresResultSetIterator.create(dbTester.getDbClient(), dbTester.getSession(), date, projectUuid);
Map<String, ProjectMeasuresDoc> docsById = Maps.uniqueIndex(it, ProjectMeasuresDoc::getId);
it.close();
return docsById;