aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-batch
diff options
context:
space:
mode:
authorDavid Gageot <david@gageot.net>2012-07-09 16:00:49 +0200
committerDavid Gageot <david@gageot.net>2012-07-10 08:50:59 +0200
commit9a1dfc90225636f980821a4c4be971035f0e6e05 (patch)
treef27949099ecbfb35d0a3322ebebc9c48ddf4ad9b /sonar-batch
parent4bc518ebc8b51e8ee64d4bb3d86136a5b7d12043 (diff)
downloadsonarqube-9a1dfc90225636f980821a4c4be971035f0e6e05.tar.gz
sonarqube-9a1dfc90225636f980821a4c4be971035f0e6e05.zip
SONAR-3437 Use MyBatis in batch mode
Diffstat (limited to 'sonar-batch')
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/index/MeasurePersister.java108
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/index/MeasurePersisterTest.java11
-rw-r--r--sonar-batch/src/test/resources/org/sonar/batch/index/MeasurePersisterTest/shouldInsertMeasureWithLargeData-result.xml18
3 files changed, 110 insertions, 27 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/MeasurePersister.java b/sonar-batch/src/main/java/org/sonar/batch/index/MeasurePersister.java
index c270e2fd071..38b8e7ff3a3 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/index/MeasurePersister.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/index/MeasurePersister.java
@@ -19,14 +19,20 @@
*/
package org.sonar.batch.index;
-import org.sonar.api.database.model.MeasureDto;
+import javax.annotation.Nullable;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Lists;
import com.google.common.collect.SetMultimap;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.ibatis.session.SqlSession;
import org.slf4j.LoggerFactory;
+import org.sonar.api.database.model.MeasureDataDto;
+import org.sonar.api.database.model.MeasureDto;
import org.sonar.api.database.model.MeasureModel;
import org.sonar.api.database.model.MeasureModelMapper;
import org.sonar.api.database.model.Snapshot;
@@ -41,8 +47,13 @@ import org.sonar.api.utils.SonarException;
import org.sonar.core.persistence.MyBatis;
import java.util.Collection;
+import java.util.List;
import java.util.Map;
+import static com.google.common.collect.Iterables.filter;
+
+import static com.google.common.base.Predicates.not;
+
public final class MeasurePersister {
private final MyBatis mybatis;
private final ResourcePersister resourcePersister;
@@ -62,25 +73,38 @@ public final class MeasurePersister {
this.delayedMode = delayedMode;
}
+ public Measure reloadMeasure(Measure measure) {
+ return memoryOptimizer.reloadMeasure(measure);
+ }
+
+ public void dump() {
+ LoggerFactory.getLogger(getClass()).debug("{} measures to dump", unsavedMeasuresByResource.size());
+
+ List<MeasureDto> measuresToSave = getMeasuresToSave();
+ insert(filter(measuresToSave, HAS_LARGE_DATA));
+ batchInsert(filter(measuresToSave, not(HAS_LARGE_DATA)));
+ }
+
public void saveMeasure(Resource resource, Measure measure) {
if (shouldSaveLater(measure)) {
unsavedMeasuresByResource.put(resource, measure);
return;
}
- MeasureModel model = null;
- if (measure.getId() != null) {
- model = update(measure);
- } else if (shouldPersistMeasure(resource, measure)) {
- model = insert(measure, resourcePersister.getSnapshotOrFail(resource));
- }
+ MeasureModel model = insertOrUpdate(resource, measure);
if (model != null) {
memoryOptimizer.evictDataMeasure(measure, model);
}
}
- public Measure reloadMeasure(Measure measure) {
- return memoryOptimizer.reloadMeasure(measure);
+ private MeasureModel insertOrUpdate(Resource resource, Measure measure) {
+ if (measure.getId() != null) {
+ return update(measure);
+ }
+ if (shouldPersistMeasure(resource, measure)) {
+ return insert(measure, resourcePersister.getSnapshotOrFail(resource));
+ }
+ return null;
}
private boolean shouldSaveLater(Measure measure) {
@@ -111,29 +135,22 @@ public final class MeasurePersister {
&& (measure.getVariation5() == null || NumberUtils.compare(measure.getVariation5().doubleValue(), 0.0) == 0);
}
- public void dump() {
- LoggerFactory.getLogger(getClass()).debug("{} measures to dump", unsavedMeasuresByResource.size());
-
- SqlSession session = mybatis.openSession();
- try {
- MeasureModelMapper mapper = session.getMapper(MeasureModelMapper.class);
+ private List<MeasureDto> getMeasuresToSave() {
+ List<MeasureDto> batch = Lists.newArrayList();
- Map<Resource, Collection<Measure>> map = unsavedMeasuresByResource.asMap();
- for (Map.Entry<Resource, Collection<Measure>> entry : map.entrySet()) {
- Resource resource = entry.getKey();
- Snapshot snapshot = resourcePersister.getSnapshot(entry.getKey());
- for (Measure measure : entry.getValue()) {
- if (shouldPersistMeasure(resource, measure)) {
- mapper.insert(new MeasureDto(model(measure).setSnapshotId(snapshot.getId())));
- }
+ Map<Resource, Collection<Measure>> map = unsavedMeasuresByResource.asMap();
+ for (Map.Entry<Resource, Collection<Measure>> entry : map.entrySet()) {
+ Resource resource = entry.getKey();
+ Snapshot snapshot = resourcePersister.getSnapshot(entry.getKey());
+ for (Measure measure : entry.getValue()) {
+ if (shouldPersistMeasure(resource, measure)) {
+ batch.add(new MeasureDto(model(measure).setSnapshotId(snapshot.getId())));
}
}
- session.commit();
- } finally {
- MyBatis.closeQuietly(session);
}
unsavedMeasuresByResource.clear();
+ return batch;
}
private MeasureModel model(Measure measure) {
@@ -171,13 +188,44 @@ public final class MeasurePersister {
return model;
}
+ private void batchInsert(Iterable<MeasureDto> values) {
+ SqlSession session = mybatis.openBatchSession();
+ try {
+ MeasureModelMapper mapper = session.getMapper(MeasureModelMapper.class);
+ for (MeasureDto value : values) {
+ mapper.insert(value);
+ }
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ private void insert(Iterable<MeasureDto> values) {
+ SqlSession session = mybatis.openSession();
+ try {
+ MeasureModelMapper mapper = session.getMapper(MeasureModelMapper.class);
+ for (MeasureDto value : values) {
+ mapper.insert(value);
+ mapper.insertData(new MeasureDataDto(value.getId(), value.getSnapshotId(), value.getMeasureData().getData()));
+ }
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
private MeasureModel insert(Measure measure, Snapshot snapshot) {
MeasureModel model = model(measure).setSnapshotId(snapshot.getId());
SqlSession session = mybatis.openSession();
try {
MeasureModelMapper mapper = session.getMapper(MeasureModelMapper.class);
- mapper.insert(new MeasureDto(model));
+ MeasureDto value = new MeasureDto(model);
+ mapper.insert(value);
+ if (value.getMeasureData() != null) {
+ mapper.insertData(new MeasureDataDto(value.getId(), value.getSnapshotId(), value.getMeasureData().getData()));
+ }
session.commit();
} finally {
MyBatis.closeQuietly(session);
@@ -201,4 +249,10 @@ public final class MeasurePersister {
return model;
}
+
+ private static final Predicate<MeasureDto> HAS_LARGE_DATA = new Predicate<MeasureDto>() {
+ public boolean apply(@Nullable MeasureDto measure) {
+ return (null != measure) && (measure.getMeasureData() != null);
+ }
+ };
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/MeasurePersisterTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/MeasurePersisterTest.java
index 3bb6707129a..f1ba1fb750a 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/index/MeasurePersisterTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/index/MeasurePersisterTest.java
@@ -19,6 +19,7 @@
*/
package org.sonar.batch.index;
+import org.apache.commons.lang.StringUtils;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.database.model.MeasureModel;
@@ -94,6 +95,16 @@ public class MeasurePersisterTest extends AbstractDaoTestCase {
}
@Test
+ public void shouldInsertMeasureWithTextData() {
+ setupData("empty");
+
+ measurePersister.saveMeasure(project, new Measure(ncloc()).setData("SHORT"));
+ measurePersister.saveMeasure(project, new Measure(ncloc()).setData(StringUtils.repeat("0123456789", 10)));
+
+ checkTables("shouldInsertMeasureWithLargeData", "project_measures", "measure_data");
+ }
+
+ @Test
public void shouldUpdateMeasure() {
setupData("data");
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/index/MeasurePersisterTest/shouldInsertMeasureWithLargeData-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/index/MeasurePersisterTest/shouldInsertMeasureWithLargeData-result.xml
new file mode 100644
index 00000000000..c90db3d3f14
--- /dev/null
+++ b/sonar-batch/src/test/resources/org/sonar/batch/index/MeasurePersisterTest/shouldInsertMeasureWithLargeData-result.xml
@@ -0,0 +1,18 @@
+<dataset>
+
+ <project_measures id="1" VALUE="[null]" METRIC_ID="1" SNAPSHOT_ID="3001" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+ RULE_ID="[null]" text_value="SHORT" tendency="[null]" measure_date="[null]" project_id="[null]"
+ alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
+ person_id="[null]"
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"/>
+
+ <project_measures id="2" VALUE="[null]" METRIC_ID="1" SNAPSHOT_ID="3001" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+ RULE_ID="[null]" text_value="[null]"
+ tendency="[null]" measure_date="[null]" project_id="[null]"
+ alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
+ person_id="[null]"
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"/>
+
+ <measure_data id="1" measure_id="2" snapshot_id="3001" data="MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OQ=="/>
+
+</dataset>