@Override
public String toString() {
if (StringUtils.equals(mode, PastSnapshotFinderByVersion.MODE)) {
- return String.format("Compare to version " + modeParameter + "(" + targetDate + ")");
+ return String.format("Compare to version " + modeParameter + "(" + getDate() + ")");
}
if (StringUtils.equals(mode, PastSnapshotFinderByDays.MODE)) {
- return String.format("Compare over " + modeParameter + " days (" + targetDate + ")");
+ return String.format("Compare over " + modeParameter + " days (" + getDate() + ")");
}
if (StringUtils.equals(mode, CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS)) {
- return String.format("Compare to previous analysis " + " (" + targetDate + ")");
+ return String.format("Compare to previous analysis " + " (" + getDate() + ")");
}
if (StringUtils.equals(mode, PastSnapshotFinderByDate.MODE)) {
- return String.format("Compare to date " + targetDate);
+ return String.format("Compare to date " + getDate());
}
return ReflectionToStringBuilder.toString(this);
}
PastSnapshot findFromDays(Snapshot projectSnapshot, int days) {
Date targetDate = DateUtils.addDays(projectSnapshot.getCreatedAt(), -days);
- String hql = "from " + Snapshot.class.getSimpleName() + " where resourceId=:resourceId AND status=:status AND createdAt>=:from AND createdAt<:to order by createdAt asc";
+ String hql = "from " + Snapshot.class.getSimpleName() + " where resourceId=:resourceId AND status=:status AND createdAt<:date order by createdAt asc";
List<Snapshot> snapshots = session.createQuery(hql)
- .setParameter("from", targetDate)
- .setParameter("to", projectSnapshot.getCreatedAt())
+ .setParameter("date", projectSnapshot.getCreatedAt())
.setParameter("resourceId", projectSnapshot.getResourceId())
.setParameter("status", Snapshot.STATUS_PROCESSED)
- .setMaxResults(1)
.getResultList();
if (snapshots.isEmpty()) {
return null;
}
- return new PastSnapshot(MODE, targetDate, snapshots.get(0)).setModeParameter(String.valueOf(days));
+
+ Snapshot snapshot = getNearestToTarget(snapshots, targetDate);
+ return new PastSnapshot(MODE, targetDate, snapshot).setModeParameter(String.valueOf(days));
+ }
+
+ static Snapshot getNearestToTarget(List<Snapshot> snapshots, Date currentDate, int distanceInDays) {
+ Date targetDate = DateUtils.addDays(currentDate, -distanceInDays);
+ return getNearestToTarget(snapshots, targetDate);
+ }
+
+ static Snapshot getNearestToTarget(List<Snapshot> snapshots, Date targetDate) {
+ long bestDistance = Long.MAX_VALUE;
+ Snapshot nearest = null;
+ for (Snapshot snapshot : snapshots) {
+ long distance = distance(snapshot.getCreatedAt(), targetDate);
+ if (distance <= bestDistance) {
+ bestDistance = distance;
+ nearest = snapshot;
+ }
+ }
+ return nearest;
+ }
+
+ static long distance(Date d1, Date d2) {
+ return Math.abs(d1.getTime() - d2.getTime());
}
}
*/
package org.sonar.batch.components;
+import org.hamcrest.core.IsNull;
import org.junit.Test;
import org.sonar.api.database.model.Snapshot;
import org.sonar.jpa.test.AbstractDbUnitTestCase;
import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.nullValue;
public class PastSnapshotFinderByDaysTest extends AbstractDbUnitTestCase {
+ private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+
@Test
public void shouldGetNextSnapshot() throws ParseException {
setupData("shared");
@Test
public void shouldNotFindSelf() throws ParseException {
- setupData("shared");
+ setupData("shouldNotFindSelf");
Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1009); // 2008-11-16
PastSnapshotFinderByDays finder = new PastSnapshotFinderByDays(getSession());
assertThat(finder.findFromDays(projectSnapshot, 1), nullValue());
}
+ @Test
+ public void shouldLocateNearestSnapshotBefore() throws ParseException {
+ Date current = dateFormat.parse("2010-10-20");
+ // distance: 15 => target is 2010-10-05
+
+ List<Snapshot> snapshots = Arrays.asList(
+ newSnapshot(1, "2010-09-30"),
+ newSnapshot(2, "2010-10-03"),// -2 days
+ newSnapshot(3, "2010-10-08"),// +3 days
+ newSnapshot(4, "2010-10-12") // + 7 days
+ );
+ assertThat(PastSnapshotFinderByDays.getNearestToTarget(snapshots, current, 15).getId(), is(2));
+ }
+
+ @Test
+ public void shouldLocateNearestSnapshotAfter() throws ParseException {
+ Date current = dateFormat.parse("2010-10-20");
+ // distance: 15 => target is 2010-10-05
+
+ List<Snapshot> snapshots = Arrays.asList(
+ newSnapshot(1, "2010-09-30"),
+ newSnapshot(2, "2010-10-01"),// -4 days
+ newSnapshot(3, "2010-10-08"),// +3 days
+ newSnapshot(4, "2010-10-12") // + 7 days
+ );
+ assertThat(PastSnapshotFinderByDays.getNearestToTarget(snapshots, current, 15).getId(), is(3));
+ }
+
+ @Test
+ public void shouldReturnNullIfNoSnapshots() throws ParseException {
+ Date current = dateFormat.parse("2010-10-20");
+ List<Snapshot> snapshots = Collections.emptyList();
+ assertThat(PastSnapshotFinderByDays.getNearestToTarget(snapshots, current, 15), IsNull.nullValue());
+ }
+
+ private Snapshot newSnapshot(int id, String date) throws ParseException {
+ Snapshot snapshot = new Snapshot();
+ snapshot.setId(id);
+ snapshot.setCreatedAt(dateFormat.parse(date));
+ return snapshot;
+ }
}
--- /dev/null
+<dataset>
+
+ <!-- project -->
+ <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
+ root_id="[null]"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]"/>
+
+ <!-- package -->
+ <projects long_name="[null]" id="2" scope="DIR" qualifier="PAC" kee="project:org.foo" name="org.foo"
+ root_id="1"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]"/>
+
+ <!-- file -->
+ <projects long_name="org.foo.Bar" id="3" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar"
+ name="Bar" root_id="[null]"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]"/>
+
+
+ <!-- current analysis : 2008-11-16 -->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1009" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-16 13:58:00.00" version="[null]" path=""
+ status="U" islast="false" depth="0" />
+
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1010" project_id="2" parent_snapshot_id="1009" root_project_id="1" root_snapshot_id="1009"
+ scope="DIR" qualifier="PAC" created_at="2008-11-16 13:58:00.00" version="[null]" path="1009."
+ status="U" islast="false" depth="1" />
+
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1011" project_id="3" parent_snapshot_id="1010" root_project_id="1" root_snapshot_id="1009"
+ scope="FIL" qualifier="CLA" created_at="2008-11-16 13:58:00.00" version="[null]" path="1009.1010."
+ status="U" islast="false" depth="2" />
+</dataset>
\ No newline at end of file