public Measure getMeasure(Resource resource, Metric metric) {
Bucket bucket = buckets.get(resource);
if (bucket != null) {
- Measure measure = bucket.getMeasures(MeasuresFilters.metric(metric));
- if (measure != null) {
- return persistence.reloadMeasure(measure);
- }
+ return bucket.getMeasures(MeasuresFilters.metric(metric));
}
return null;
}
private EventPersister eventPersister;
public DefaultPersistenceManager(ResourcePersister resourcePersister, SourcePersister sourcePersister,
- MeasurePersister measurePersister, DependencyPersister dependencyPersister,
- LinkPersister linkPersister, EventPersister eventPersister) {
+ MeasurePersister measurePersister, DependencyPersister dependencyPersister,
+ LinkPersister linkPersister, EventPersister eventPersister) {
this.resourcePersister = resourcePersister;
this.sourcePersister = sourcePersister;
this.measurePersister = measurePersister;
}
}
- public Measure reloadMeasure(Measure measure) {
- return measurePersister.reloadMeasure(measure);
- }
-
public void saveDependency(Project project, Dependency dependency, Dependency parentDependency) {
if (ResourceUtils.isPersistable(dependency.getFrom()) && ResourceUtils.isPersistable(dependency.getTo())) {
dependencyPersister.saveDependency(project, dependency, parentDependency);
private final MyBatis mybatis;
private final ResourcePersister resourcePersister;
private final RuleFinder ruleFinder;
- private final MemoryOptimizer memoryOptimizer;
private final SetMultimap<Resource, Measure> unsavedMeasuresByResource = LinkedHashMultimap.create();
private boolean delayedMode = false;
- public MeasurePersister(MyBatis mybatis, ResourcePersister resourcePersister, RuleFinder ruleFinder, MemoryOptimizer memoryOptimizer) {
+ public MeasurePersister(MyBatis mybatis, ResourcePersister resourcePersister, RuleFinder ruleFinder) {
this.mybatis = mybatis;
this.resourcePersister = resourcePersister;
this.ruleFinder = ruleFinder;
- this.memoryOptimizer = memoryOptimizer;
}
public void setDelayedMode(boolean delayedMode) {
this.delayedMode = delayedMode;
}
- public Measure reloadMeasure(Measure measure) {
- return memoryOptimizer.reloadMeasure(measure);
- }
-
public void dump() {
LoggerFactory.getLogger(getClass()).debug("{} measures to dump", unsavedMeasuresByResource.size());
unsavedMeasuresByResource.put(resource, measure);
return;
}
- MeasureModel model;
try {
- model = insertOrUpdate(resource, measure);
+ insertOrUpdate(resource, measure);
} catch (Exception e) {
// SONAR-4066
throw new SonarException(String.format("Unable to save measure for metric [%s] on component [%s]", measure.getMetricKey(), resource.getKey()), e);
}
- if (model != null) {
- memoryOptimizer.evictDataMeasure(measure, model);
- }
}
private MeasureModel insertOrUpdate(Resource resource, Measure measure) {
for (MeasureModelAndDetails value : values) {
try {
mapper.insert(value.getMeasureModel());
- if (value.getMeasureModel().getMeasureData() != null) {
- mapper.insertData(value.getMeasureModel().getMeasureData());
- }
} catch (Exception e) {
// SONAR-4066
throw new SonarException(String.format("Unable to save measure for metric [%s] on component [%s]", value.getMetricKey(), value.getResourceKey()), e);
MeasureMapper mapper = session.getMapper(MeasureMapper.class);
mapper.insert(value);
- if (value.getMeasureData() != null) {
- mapper.insertData(value.getMeasureData());
- }
session.commit();
} finally {
MeasureMapper mapper = session.getMapper(MeasureMapper.class);
mapper.update(value);
- mapper.deleteData(value);
- if (value.getMeasureData() != null) {
- mapper.insertData(value.getMeasureData());
- }
session.commit();
} finally {
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.index;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.batch.events.DecoratorExecutionHandler;
-import org.sonar.api.batch.events.DecoratorsPhaseHandler;
-import org.sonar.api.batch.events.SensorExecutionHandler;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.database.model.MeasureData;
-import org.sonar.api.database.model.MeasureModel;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.PersistenceMode;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * @since 2.7
- */
-public class MemoryOptimizer implements SensorExecutionHandler, DecoratorExecutionHandler, DecoratorsPhaseHandler {
-
- private static final Logger LOG = LoggerFactory.getLogger(MemoryOptimizer.class);
-
- private List<Measure> loadedMeasures = Lists.newArrayList();
- private Map<Long, Integer> dataIdByMeasureId = Maps.newHashMap();
- private DatabaseSession session;
-
- public MemoryOptimizer(DatabaseSession session) {
- this.session = session;
- }
-
- /**
- * Remove data of a database measure from memory.
- */
- public void evictDataMeasure(Measure measure, MeasureModel model) {
- if (PersistenceMode.DATABASE.equals(measure.getPersistenceMode())) {
- MeasureData data = model.getMeasureData();
- if (data != null && data.getId() != null) {
- measure.unsetData();
- dataIdByMeasureId.put(measure.getId(), data.getId());
- }
- }
- }
-
- public Measure reloadMeasure(Measure measure) {
- if (measure.getId() != null && dataIdByMeasureId.containsKey(measure.getId()) && !measure.hasData()) {
- Integer dataId = dataIdByMeasureId.get(measure.getId());
- MeasureData data = session.getSingleResult(MeasureData.class, "id", dataId);
- if (data == null) {
- LOG.error("The MEASURE_DATA row with id {} is lost", dataId);
-
- } else {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Reload the data measure: {}, id={}", measure.getMetricKey(), measure.getId());
- }
- measure.setData(data.getText());
- loadedMeasures.add(measure);
- }
- }
- return measure;
- }
-
- public void flushMemory() {
- if (LOG.isDebugEnabled() && !loadedMeasures.isEmpty()) {
- LOG.debug("Flush {} data measures from memory: ", loadedMeasures.size());
- }
- for (Measure measure : loadedMeasures) {
- measure.unsetData();
- }
- loadedMeasures.clear();
- }
-
- boolean isTracked(Long measureId) {
- return dataIdByMeasureId.get(measureId) != null;
- }
-
- public void onSensorExecution(SensorExecutionEvent event) {
- if (event.isEnd()) {
- flushMemory();
- session.commit();
- }
- }
-
- public void onDecoratorExecution(DecoratorExecutionEvent event) {
- if (event.isEnd()) {
- flushMemory();
- }
- }
-
- public void onDecoratorsPhase(DecoratorsPhaseEvent event) {
- if (event.isEnd()) {
- session.commit();
- }
- }
-
-}
void saveMeasure(Resource resource, Measure measure);
- Measure reloadMeasure(Measure measure);
-
void saveDependency(Project project, Dependency dependency, Dependency parentDependency);
void saveLink(Project project, ProjectLink link);
import com.google.common.annotations.VisibleForTesting;
import org.sonar.api.BatchComponent;
-import org.sonar.api.BatchExtension;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.InstantiationStrategy;
import org.sonar.api.batch.bootstrap.ProjectBootstrapper;
import org.sonar.batch.DefaultResourceCreationLock;
import org.sonar.batch.ProjectConfigurator;
import org.sonar.batch.ProjectTree;
-import org.sonar.batch.bootstrap.*;
+import org.sonar.batch.bootstrap.BootstrapSettings;
+import org.sonar.batch.bootstrap.ExtensionInstaller;
+import org.sonar.batch.bootstrap.ExtensionMatcher;
+import org.sonar.batch.bootstrap.ExtensionUtils;
+import org.sonar.batch.bootstrap.MetricProvider;
import org.sonar.batch.components.PeriodsDefinition;
import org.sonar.batch.debt.DebtModelProvider;
import org.sonar.batch.debt.IssueChangelogDebtCalculator;
-import org.sonar.batch.index.*;
-import org.sonar.batch.issue.*;
+import org.sonar.batch.index.Caches;
+import org.sonar.batch.index.ComponentDataCache;
+import org.sonar.batch.index.ComponentDataPersister;
+import org.sonar.batch.index.DefaultIndex;
+import org.sonar.batch.index.DefaultPersistenceManager;
+import org.sonar.batch.index.DefaultResourcePersister;
+import org.sonar.batch.index.DependencyPersister;
+import org.sonar.batch.index.EventPersister;
+import org.sonar.batch.index.LinkPersister;
+import org.sonar.batch.index.MeasurePersister;
+import org.sonar.batch.index.ResourceCache;
+import org.sonar.batch.index.ResourceKeyMigration;
+import org.sonar.batch.index.SnapshotCache;
+import org.sonar.batch.index.SourcePersister;
+import org.sonar.batch.issue.DefaultProjectIssues;
+import org.sonar.batch.issue.DeprecatedViolations;
+import org.sonar.batch.issue.IssueCache;
+import org.sonar.batch.issue.IssuePersister;
+import org.sonar.batch.issue.ScanIssueStorage;
import org.sonar.batch.phases.GraphPersister;
import org.sonar.batch.profiling.PhasesSumUpTimeProfiler;
import org.sonar.batch.rule.RulesProvider;
EventPersister.class,
LinkPersister.class,
MeasurePersister.class,
- MemoryOptimizer.class,
DefaultResourcePersister.class,
SourcePersister.class,
DefaultNotificationManager.class,
import org.junit.Before;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.mockito.ArgumentCaptor;
-import org.sonar.api.database.model.MeasureModel;
import org.sonar.api.database.model.Snapshot;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.core.persistence.AbstractDaoTestCase;
import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class MeasurePersisterTest extends AbstractDaoTestCase {
MeasurePersister measurePersister;
RuleFinder ruleFinder = mock(RuleFinder.class);
ResourcePersister resourcePersister = mock(ResourcePersister.class);
- MemoryOptimizer memoryOptimizer = mock(MemoryOptimizer.class);
Project project = new Project("foo");
Directory aDirectory = new Directory("org/foo");
File aFile = new File("org/foo/Bar.java");
when(resourcePersister.getSnapshot(project)).thenReturn(projectSnapshot);
when(resourcePersister.getSnapshot(aDirectory)).thenReturn(packageSnapshot);
- measurePersister = new MeasurePersister(getMyBatis(), resourcePersister, ruleFinder, memoryOptimizer);
+ measurePersister = new MeasurePersister(getMyBatis(), resourcePersister, ruleFinder);
}
@Test
measurePersister.saveMeasure(project, measure);
checkTables("shouldInsertMeasure", "project_measures");
- verify(memoryOptimizer).evictDataMeasure(eq(measure), any(MeasureModel.class));
assertThat(measure.getId()).isNotNull();
}
measurePersister.saveMeasure(project, measure);
}
- @Test
- public void should_reload_measure() {
- Measure measure = new Measure(ncloc());
-
- measurePersister.reloadMeasure(measure);
-
- verify(memoryOptimizer).reloadMeasure(measure);
- }
-
@Test
public void should_insert_rule_measure() {
setupData("empty");
Measure withLargeData = new Measure(ncloc()).setData(LONG);
measurePersister.saveMeasure(project, withLargeData);
- checkTables("shouldInsertMeasureWithLargeData", "project_measures", "measure_data");
+ checkTables("shouldInsertMeasureWithLargeData", "project_measures");
- ArgumentCaptor<MeasureModel> validMeasureModel = ArgumentCaptor.forClass(MeasureModel.class);
- verify(memoryOptimizer).evictDataMeasure(eq(withLargeData), validMeasureModel.capture());
- assertThat(validMeasureModel.getValue().getMeasureData().getId()).isNotNull();
assertThat(withLargeData.getId()).isNotNull();
}
measurePersister.saveMeasure(aFile, new Measure(coverage()).setValue(100.0));
- assertEmptyTables("project_measures", "measure_data");
+ assertEmptyTables("project_measures");
}
@Test
measurePersister.saveMeasure(aFile, new Measure("ncloc").setPersistenceMode(PersistenceMode.MEMORY));
- assertEmptyTables("project_measures", "measure_data");
+ assertEmptyTables("project_measures");
}
@Test
measurePersister.saveMeasure(project, new Measure(coverage()).setData(SHORT).setId(2L));
measurePersister.saveMeasure(aDirectory, new Measure(coverage()).setData(LONG).setId(3L));
- checkTables("shouldUpdateMeasure", "project_measures", "measure_data");
+ checkTables("shouldUpdateMeasure", "project_measures");
}
@Test
assertEmptyTables("project_measures");
measurePersister.dump();
- checkTables("shouldDelaySaving", "project_measures", "measure_data");
+ checkTables("shouldDelaySaving", "project_measures");
}
@Test
measurePersister.setDelayedMode(true);
measurePersister.saveMeasure(aFile, new Measure(coverage()).setValue(100.0));
- assertEmptyTables("project_measures", "measure_data");
+ assertEmptyTables("project_measures");
measurePersister.dump();
- assertEmptyTables("project_measures", "measure_data");
+ assertEmptyTables("project_measures");
}
@Test
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.index;
-
-import org.junit.Test;
-import org.sonar.api.database.model.MeasureData;
-import org.sonar.api.database.model.MeasureModel;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.PersistenceMode;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import static org.hamcrest.Matchers.greaterThan;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.core.IsNull.nullValue;
-import static org.junit.Assert.assertThat;
-
-public class MemoryOptimizerTest extends AbstractDbUnitTestCase {
-
- @Test
- public void shouldEvictDatabaseOnlyMeasure() {
- MemoryOptimizer optimizer = new MemoryOptimizer(getSession());
- Measure measure = new Measure(CoreMetrics.CONDITIONS_BY_LINE)
- .setData("10=23")
- .setPersistenceMode(PersistenceMode.DATABASE)
- .setId(12345L);
- MeasureModel model = newPersistedModel();
-
- optimizer.evictDataMeasure(measure, model);
-
- assertThat(optimizer.isTracked(12345L),is(true));
- assertThat(measure.getData(), nullValue());// data has been removed from memory
- }
-
- @Test
- public void shouldNotEvictStandardMeasure() {
- MemoryOptimizer optimizer = new MemoryOptimizer(getSession());
- Measure measure = new Measure(CoreMetrics.PROFILE)
- .setData("Sonar way")
- .setId(12345L);
- MeasureModel model = newPersistedModel();
-
- optimizer.evictDataMeasure(measure, model);
-
- assertThat(optimizer.isTracked(12345L),is(false));
- assertThat(measure.getData(), is("Sonar way"));
- }
-
- @Test
- public void shouldReloadEvictedMeasure() {
- setupData("shouldReloadEvictedMeasure");
- MemoryOptimizer optimizer = new MemoryOptimizer(getSession());
- Measure measure = new Measure(CoreMetrics.CONDITIONS_BY_LINE)
- .setData("initial")
- .setPersistenceMode(PersistenceMode.DATABASE)
- .setId(12345L);
-
- optimizer.evictDataMeasure(measure, newPersistedModel());
- assertThat(measure.getData(), nullValue());
-
- optimizer.reloadMeasure(measure);
-
- assertThat(measure.getData().length(), greaterThan(5));
-
- optimizer.flushMemory();
- assertThat(measure.getData(), nullValue());
- }
-
- private MeasureModel newPersistedModel() {
- MeasureModel model = new MeasureModel();
- model.setId(12345L);
- MeasureData measureData = new MeasureData();
- measureData.setId(500);
- model.setMeasureData(measureData);
- return model;
- }
-}
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]"/>
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
+ measure_data="[null]"/>
</dataset>
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]"/>
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
+ measure_data="[null]"/>
<project_measures id="2" VALUE="300.0" METRIC_ID="1" SNAPSHOT_ID="3002" 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]"/>
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
+ measure_data="[null]"/>
</dataset>
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]"/>
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
+ measure_data="[null]"/>
<project_measures id="2" VALUE="50.0" METRIC_ID="1" SNAPSHOT_ID="3002" 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="3002" data="MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OQ=="/>
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
+ measure_data="MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OQ=="/>
</dataset>
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]"/>
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
+ measure_data="[null]"/>
</dataset>
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="1" snapshot_id="3001" data="MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OQ=="/>
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
+ measure_data="MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OQ=="/>
</dataset>
RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
alert_status="[null]" description="[null]" rule_priority="2" 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]"/>
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
+ measure_data="[null]"/>
</dataset>
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]"/>
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
+ measure_data="[null]"/>
<project_measures id="2" VALUE="[null]" METRIC_ID="2" 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]"/>
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
+ measure_data="[null]"/>
<project_measures id="3" VALUE="[null]" METRIC_ID="2" SNAPSHOT_ID="3002" 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="3" snapshot_id="3002" data="MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OQ=="/>
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
+ measure_data="MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OQ=="/>
</dataset>
+++ /dev/null
-<dataset>
-
-
- <measure_data id="2" measure_id="2" snapshot_id="2" data="[null]"/>
- <measure_data id="500" measure_id="12345" snapshot_id="1" data="value from database"/>
-
-
-</dataset>
\ No newline at end of file
private Integer id;
- private Long measureId;
-
private Integer snapshotId;
private byte[] data;
return this;
}
- public Long getMeasureId() {
- return measureId;
- }
-
- public MeasureDataDto setMeasureId(Long measureId) {
- this.measureId = measureId;
- return this;
- }
-
public Integer getSnapshotId() {
return snapshotId;
}
*/
public class DatabaseVersion implements BatchComponent, ServerComponent {
- public static final int LAST_VERSION = 526;
+ public static final int LAST_VERSION = 530;
public static enum Status {
UP_TO_DATE, REQUIRES_UPGRADE, REQUIRES_DOWNGRADE, FRESH_INSTALL
"issue_filter_favourites",
"loaded_templates",
"manual_measures",
- "measure_data",
"measure_filters",
"measure_filter_favourites",
"metrics",
session.commit();
profiler.stop();
- profiler.start("deleteSnapshotMeasureData (measure_data)");
- for (List<Long> partSnapshotIds : snapshotIdsPartition) {
- purgeMapper.deleteSnapshotMeasureData(partSnapshotIds);
- }
- session.commit();
- profiler.stop();
-
profiler.start("deleteSnapshotMeasures (project_measures)");
for (List<Long> partSnapshotIds : snapshotIdsPartition) {
purgeMapper.deleteSnapshotMeasures(partSnapshotIds);
profiler.start("deleteSnapshotDependencies (dependencies)");
for (List<Long> partSnapshotIds : snapshotIdsPartition) {
// SONAR-4586
- // On MsSQL, the maximum number of parameters allowed in a query is 2000, so we have to execute 3 queries instead of one with 3 or inside
+ // On MsSQL, the maximum number of parameters allowed in a query is 2000, so we have to execute 3 queries instead of one with 3 or
+ // inside
purgeMapper.deleteSnapshotDependenciesFromSnapshotId(partSnapshotIds);
purgeMapper.deleteSnapshotDependenciesToSnapshotId(partSnapshotIds);
purgeMapper.deleteSnapshotDependenciesProjectSnapshotId(partSnapshotIds);
void deleteSnapshotMeasures(@Param("snapshotIds") List<Long> snapshotIds);
- void deleteSnapshotMeasureData(@Param("snapshotIds") List<Long> snapshotIds);
-
void deleteSnapshotSource(@Param("snapshotIds") List<Long> snapshotIds);
void deleteSnapshotGraphs(@Param("snapshotIds") List<Long> snapshotIds);
<class>org.sonar.api.database.model.User</class>
<class>org.sonar.api.database.model.Snapshot</class>
<class>org.sonar.api.database.model.MeasureModel</class>
- <class>org.sonar.api.database.model.MeasureData</class>
<class>org.sonar.api.design.DependencyDto</class>
<class>org.sonar.api.measures.Metric</class>
<class>org.sonar.api.database.model.ResourceModel</class>
<mapper namespace="org.sonar.core.measure.db.MeasureDataMapper">
<sql id="measureDataColumns">
- m.id,
- m.measure_id as measureId,
- m.snapshot_id as snapshotId,
- m.data as data
+ pm.id,
+ pm.snapshot_id as snapshotId,
+ pm.measure_data as data
</sql>
<select id="findByComponentKeyAndMetricKey" parameterType="map" resultType="MeasureData">
SELECT
<include refid="measureDataColumns"/>
- FROM measure_data m
- INNER JOIN project_measures pm ON pm.id=m.measure_id
+ FROM project_measures pm
INNER JOIN snapshots s ON s.id=pm.snapshot_id AND s.islast=${_true}
INNER JOIN projects p ON p.id=s.project_id AND p.enabled=${_true}
INNER JOIN metrics metric ON metric.id=pm.metric_id
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('524');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('525');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('526');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('530');
INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '2011-09-26 22:27:48.0', '2011-09-26 22:27:48.0', null, null);
ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2;
"RESOURCE_ID" INTEGER
);
-CREATE TABLE "MEASURE_DATA" (
- "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
- "MEASURE_ID" BIGINT,
- "SNAPSHOT_ID" INTEGER,
- "DATA" BINARY(167772150)
-);
-
CREATE TABLE "GROUPS" (
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
"NAME" VARCHAR(255),
"VARIATION_VALUE_2" DOUBLE,
"VARIATION_VALUE_3" DOUBLE,
"VARIATION_VALUE_4" DOUBLE,
- "VARIATION_VALUE_5" DOUBLE
+ "VARIATION_VALUE_5" DOUBLE,
+ "MEASURE_DATA" BINARY(167772150)
);
CREATE TABLE "SNAPSHOT_SOURCES" (
CREATE INDEX "ACTIVE_RULE_PARAM_CHANGES_CID" ON "ACTIVE_RULE_PARAM_CHANGES" ("ACTIVE_RULE_CHANGE_ID");
-CREATE INDEX "M_DATA_SID" ON "MEASURE_DATA" ("SNAPSHOT_ID");
-
-CREATE INDEX "MEASURE_DATA_MEASURE_ID" ON "MEASURE_DATA" ("MEASURE_ID");
-
CREATE INDEX "EVENTS_SNAPSHOT_ID" ON "EVENTS" ("SNAPSHOT_ID");
CREATE INDEX "EVENTS_RESOURCE_ID" ON "EVENTS" ("RESOURCE_ID");
</foreach>
</delete>
- <delete id="deleteSnapshotMeasureData" parameterType="map">
- delete from measure_data where snapshot_id in
- <foreach collection="snapshotIds" open="(" close=")" item="snapshotId" separator=",">
- #{snapshotId}
- </foreach>
- </delete>
-
<delete id="deleteSnapshotSource" parameterType="map">
delete from snapshot_sources where snapshot_id in
<foreach collection="snapshotIds" open="(" close=")" item="snapshotId" separator=",">
setupData("shared");
MeasureDataDto result = dao.findByComponentKeyAndMetricKey("org.sonar.core.measure.db.MeasureData", "authors_by_line");
- assertThat(result.getId()).isEqualTo(30);
- assertThat(result.getMeasureId()).isEqualTo(20);
+ assertThat(result.getId()).isEqualTo(20);
assertThat(result.getSnapshotId()).isEqualTo(5);
assertThat(result.getText()).isNotNull();
assertThat(result.getData()).isNotNull();
- // FIXME failing because data is returned in wrong format
-// assertThat(result.getText()).isEqualTo("test");
+ assertThat(result.getText()).isEqualTo("0123456789012345678901234567890123456789");
}
@Test
setupData("find_by_component_key_and_metric_key_without_text");
MeasureDataDto result = dao.findByComponentKeyAndMetricKey("org.sonar.core.measure.db.MeasureData", "authors_by_line");
- assertThat(result.getId()).isEqualTo(30);
- assertThat(result.getMeasureId()).isEqualTo(20);
+ assertThat(result.getId()).isEqualTo(20);
assertThat(result.getSnapshotId()).isEqualTo(5);
assertThat(result.getText()).isNull();
assertThat(result.getData()).isNull();
MyBatis.closeQuietly(session);
}
checkTables("shouldDeleteSnapshot",
- "snapshots", "project_measures", "measure_data", "snapshot_sources", "duplications_index", "events", "dependencies", "snapshot_data");
+ "snapshots", "project_measures", "snapshot_sources", "duplications_index", "events", "dependencies", "snapshot_data");
}
/**
MyBatis.closeQuietly(session);
}
checkTables("shouldPurgeSnapshot",
- "snapshots", "project_measures", "measure_data", "snapshot_sources", "duplications_index", "events", "dependencies", "snapshot_data");
+ "snapshots", "project_measures", "snapshot_sources", "duplications_index", "events", "dependencies", "snapshot_data");
}
@Test
// The goal of this test is only to check that the query do no fail, not to check result
}
- private List<Long> getHugeNumberOfIds(){
+ private List<Long> getHugeNumberOfIds() {
List<Long> hugeNbOfSnapshotIds = newArrayList();
- for (long i=0; i<4500; i++) {
+ for (long i = 0; i < 4500; i++) {
hugeNbOfSnapshotIds.add(i);
}
return hugeNbOfSnapshotIds;
<projects id="1" kee="org.sonar.core.measure.db.MeasureData" enabled="[true]"/>
<snapshots id="5" project_id="1" islast="[true]" />
- <project_measures id="20" snapshot_id="5" metric_id="10"/>
- <measure_data id="30" measure_id="20" snapshot_id="5" data="[null]"/>
+ <project_measures id="20" snapshot_id="5" metric_id="10" measure_data="[null]"/>
</dataset>
<projects id="1" kee="org.sonar.core.measure.db.MeasureData" enabled="[true]"/>
<snapshots id="5" project_id="1" islast="[true]" />
- <project_measures id="20" snapshot_id="5" metric_id="10"/>
- <measure_data id="30" measure_id="20" snapshot_id="5" data="test"/>
+ <project_measures id="20" snapshot_id="5" metric_id="10" measure_data="MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OQ=="/>
</dataset>
RULE_ID="1"
person_id="[null]"
text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
- alert_status="[null]" description="[null]"/>
- <measure_data id="1" measure_id="1" snapshot_id="1" data="[null]"/>
+ alert_status="[null]" description="[null]" measure_data="[null]"/>
<dependencies id="1" from_resource_id="1" from_snapshot_id="1" to_resource_id="30" to_snapshot_id="30"
parent_dependency_id="[null]" project_snapshot_id="1"
dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="LIB"/>
RULE_ID="1"
person_id="[null]"
text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
- alert_status="[null]" description="[null]"/>
- <measure_data id="1" measure_id="1" snapshot_id="1" data="[null]"/>
+ alert_status="[null]" description="[null]" measure_data="[null]"/>
<dependencies id="1" from_resource_id="1" from_snapshot_id="1" to_resource_id="30" to_snapshot_id="30"
parent_dependency_id="[null]" project_snapshot_id="1"
dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="LIB"/>
RULE_ID="1"
person_id="[null]"
text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
- alert_status="[null]" description="[null]"/>
- <measure_data id="2" measure_id="2" snapshot_id="5" data="[null]"/>
+ alert_status="[null]" description="[null]" measure_data="[null]"/>
<dependencies id="2" from_resource_id="10" from_snapshot_id="10" to_resource_id="5" to_snapshot_id="5"
parent_dependency_id="[null]" project_snapshot_id="5"
dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="LIB"/>
rules_category_id="[null]"
person_id="[null]"
text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]"
- description="[null]"/>
+ description="[null]" measure_data="[null]"/>
<!-- delete measure on rule -->
<!--<project_measures ID="2" project_id="1" SNAPSHOT_ID="1" RULE_ID="33" characteristic_id="[null]" METRIC_ID="1"
rules_category_id="[null]"
person_id="[null]"
text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]"
- description="[null]"/>-->
+ description="[null]" measure_data="[null]"/>-->
<!-- do not delete measure on characteristic -->
<project_measures id="3" project_id="1" snapshot_id="1" rule_id="[null]" characteristic_id="1" metric_id="1"
rules_category_id="[null]"
person_id="[null]"
text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]"
- description="[null]"/>
+ description="[null]" measure_data="[null]"/>
<!-- do not delete measure on characteristic -->
<project_measures id="4" project_id="1" snapshot_id="1" rule_id="[null]" characteristic_id="2" metric_id="1"
rules_category_id="[null]"
person_id="[null]"
text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]"
- description="[null]"/>
+ description="[null]" measure_data="[null]"/>
<!-- delete measure on metrics that are flagged with delete_historical_data=true -->
<!--<project_measures ID="6" project_id="1" SNAPSHOT_ID="1" RULE_ID="[null]" characteristic_id="[null]" METRIC_ID="2"
rules_category_id="[null]"
person_id="[null]"
text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]"
- description="[null]"/>-->
+ description="[null]" measure_data="[null]"/>-->
<!-- delete measure on developers -->
<!--<project_measures id="7" project_id="1" snapshot_id="1" rule_id="[null]" characteristic_id="[null]" metric_id="2"
variation_value_5="[null]" rule_priority="[null]" alert_text="[null]" value="10.0"
rules_category_id="[null]"
text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]"
- description="[null]"/>-->
+ description="[null]" measure_data="[null]"/>-->
</dataset>
rules_category_id="[null]"
person_id="[null]"
text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]"
- description="[null]"/>
+ description="[null]" measure_data="[null]"/>
<!-- delete measure on rule -->
<project_measures id="2" project_id="1" snapshot_id="1" rule_id="33" characteristic_id="[null]" metric_id="1"
rules_category_id="[null]"
person_id="[null]"
text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]"
- description="[null]"/>
+ description="[null]" measure_data="[null]"/>
<!-- do not delete measure on root characteristic -->
<project_measures id="3" project_id="1" snapshot_id="1" rule_id="[null]" characteristic_id="1" metric_id="1"
rules_category_id="[null]"
person_id="[null]"
text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]"
- description="[null]"/>
+ description="[null]" measure_data="[null]"/>
<!-- do not delete measure on characteristic -->
<project_measures id="4" project_id="1" snapshot_id="1" rule_id="[null]" characteristic_id="2" metric_id="1"
rules_category_id="[null]"
person_id="[null]"
text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]"
- description="[null]"/>
+ description="[null]" measure_data="[null]"/>
<!-- delete measure on metrics that are flagged with delete_historical_data=true -->
<project_measures id="6" project_id="1" snapshot_id="1" rule_id="[null]" characteristic_id="[null]" metric_id="2"
rules_category_id="[null]"
person_id="[null]"
text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]"
- description="[null]"/>
+ description="[null]" measure_data="[null]"/>
<!-- delete measure on developers -->
<project_measures id="7" project_id="1" snapshot_id="1" rule_id="[null]" characteristic_id="[null]" metric_id="2"
variation_value_5="[null]" rule_priority="[null]" alert_text="[null]" value="10.0"
rules_category_id="[null]"
text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]"
- description="[null]"/>
+ description="[null]" measure_data="[null]"/>
</dataset>
url="[null]" variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]"
variation_value_5="[null]" rule_priority="[null]" alert_text="[null]" VALUE="10.0" METRIC_ID="1" rules_category_id="[null]"
person_id="[null]"
- text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]" description="[null]"/>
-
- <measure_data id="1" measure_id="1" snapshot_id="1" data="[null]"/>
+ text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]" description="[null]" measure_data="[null]"/>
<!--<dependencies id="1" from_resource_id="1" from_snapshot_id="1" to_resource_id="2" to_snapshot_id="2"-->
<!--parent_dependency_id="[null]" project_snapshot_id="[null]"-->
url="[null]" variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]"
variation_value_5="[null]" rule_priority="[null]" alert_text="[null]" VALUE="10.0" METRIC_ID="1" rules_category_id="[null]"
person_id="[null]"
- text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]" description="[null]"/>
-
- <measure_data id="2" measure_id="2" snapshot_id="2" data="[null]"/>
+ text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]" description="[null]" measure_data="[null]"/>
<dependencies id="3" from_resource_id="33" from_snapshot_id="33" to_resource_id="44" to_snapshot_id="44"
parent_dependency_id="[null]" project_snapshot_id="[null]"
url="[null]" variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]"
variation_value_5="[null]" rule_priority="[null]" alert_text="[null]" VALUE="10.0" METRIC_ID="1" rules_category_id="[null]"
person_id="[null]"
- text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]" description="[null]"/>
-
- <measure_data id="1" measure_id="1" snapshot_id="1" data="[null]"/>
+ text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]" description="[null]" measure_data="[null]"/>
<dependencies id="1" from_resource_id="1" from_snapshot_id="1" to_resource_id="2" to_snapshot_id="2"
parent_dependency_id="[null]" project_snapshot_id="[null]"
url="[null]" variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]"
variation_value_5="[null]" rule_priority="[null]" alert_text="[null]" VALUE="10.0" METRIC_ID="1" rules_category_id="[null]"
person_id="[null]"
- text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]" description="[null]"/>
-
- <measure_data id="2" measure_id="2" snapshot_id="2" data="[null]"/>
+ text_value="[null]" tendency="[null]" measure_date="[null]" alert_status="[null]" description="[null]" measure_data="[null]"/>
<dependencies id="3" from_resource_id="33" from_snapshot_id="33" to_resource_id="44" to_snapshot_id="44"
parent_dependency_id="[null]" project_snapshot_id="[null]"
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.database.model;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Throwables;
-import org.apache.commons.lang.builder.ToStringBuilder;
-import org.apache.commons.lang.builder.ToStringStyle;
-import org.sonar.api.database.BaseIdentifiable;
-
-import javax.persistence.*;
-import java.io.UnsupportedEncodingException;
-
-@Entity
-@Table(name = "measure_data")
-public class MeasureData extends BaseIdentifiable {
-
- @OneToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "measure_id")
- private MeasureModel measure;
-
- @Column(name = "snapshot_id", updatable = true, nullable = true)
- private Integer snapshotId;
-
- @Column(name = "data", updatable = true, nullable = true, length = 167772150)
- private byte[] data;
-
- public MeasureData(MeasureModel measure) {
- this.measure = measure;
- }
-
- public MeasureData(MeasureModel measure, byte[] data) {
- this.measure = measure;
- this.data = data;
- }
-
- public MeasureData(MeasureModel measure, String dataString) {
- this.measure = measure;
- this.data = dataString.getBytes();
- }
-
- public MeasureData() {
- }
-
- public MeasureModel getMeasure() {
- return measure;
- }
-
- public void setMeasure(MeasureModel measure) {
- this.measure = measure;
- }
-
- public byte[] getData() {
- return data;
- }
-
- public String getText() {
- if (data != null) {
- try {
- return new String(data, Charsets.UTF_8.name());
- } catch (UnsupportedEncodingException e) {
- // how is it possible to not support UTF-8 ?
- Throwables.propagate(e);
- }
- }
- return null;
- }
-
- public void setData(byte[] data) {
- this.data = data;
- }
-
- public Integer getSnapshotId() {
- return snapshotId;
- }
-
- public void setSnapshotId(Integer snapshotId) {
- this.snapshotId = snapshotId;
- }
-
- @Override
- public String toString() {
- return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
- .append("snapshotId", snapshotId)
- .append("mesasure", measure)
- .append("data", data)
- .toString();
- }
-}
-
public interface MeasureMapper {
void insert(MeasureModel measure);
- void insertData(MeasureData data);
-
- void deleteData(MeasureModel data);
-
void update(MeasureModel measure);
}
*/
package org.sonar.api.database.model;
+import com.google.common.base.Charsets;
+import com.google.common.base.Throwables;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.sonar.api.database.DatabaseSession;
import org.sonar.api.measures.Metric;
import org.sonar.api.rules.RulePriority;
-import javax.persistence.*;
-
-import java.util.ArrayList;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import java.io.UnsupportedEncodingException;
import java.util.Date;
-import java.util.List;
/**
* This class is the Hibernate model to store a measure in the DB
*/
@Deprecated
@Column(name = "rules_category_id", nullable = true)
- private Integer rulesCategoryId;//NOSONAR this field is kept for backward-compatiblity of API
+ private Integer rulesCategoryId;// NOSONAR this field is kept for backward-compatiblity of API
@Column(name = "rule_priority", updatable = false, nullable = true)
@Enumerated(EnumType.ORDINAL)
@Column(name = "url", updatable = true, nullable = true, length = 2000)
private String url;
- @OneToMany(mappedBy = "measure", fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
- private List<MeasureData> measureData = new ArrayList<MeasureData>();
-
@Column(name = "characteristic_id", nullable = true)
private Integer characteristicId;
@Column(name = "person_id", updatable = true, nullable = true)
private Integer personId;
+ @Column(name = "measure_data", updatable = true, nullable = true, length = 167772150)
+ private byte[] data;
+
public Long getId() {
return id;
}
if (this.textValue != null) {
return this.textValue;
}
- if (metric.isDataType() && !measureData.isEmpty()) {
- return measureData.get(0).getText();
+ if (metric.isDataType() && data != null) {
+ try {
+ return new String(data, Charsets.UTF_8.name());
+ } catch (UnsupportedEncodingException e) {
+ // how is it possible to not support UTF-8 ?
+ Throwables.propagate(e);
+ }
}
return null;
}
public final void setData(String data) {
if (data == null) {
this.textValue = null;
- measureData.clear();
+ this.data = null;
} else {
if (data.length() > TEXT_VALUE_LENGTH) {
- measureData.clear();
- measureData.add(new MeasureData(this, data));
-
+ this.textValue = null;
+ this.data = data.getBytes(Charsets.UTF_8);
} else {
this.textValue = data;
+ this.data = null;
}
}
}
- /**
- * Use getData() instead
- */
- public MeasureData getMeasureData() {
- if (!measureData.isEmpty()) {
- return measureData.get(0);
- }
- return null;
- }
-
- /**
- * Use setData() instead
- */
- //@Deprecated
- public void setMeasureData(MeasureData data) {
- measureData.clear();
- if (data != null) {
- this.measureData.add(data);
- }
- }
-
/**
* @return the text of the alert
*/
* @return the current object
*/
public MeasureModel save(DatabaseSession session) {
- MeasureData data = getMeasureData();
- setMeasureData(null);
session.save(this);
-
- if (data != null) {
- data.setMeasure(session.getEntity(MeasureModel.class, getId()));
- data.setSnapshotId(snapshotId);
- session.save(data);
- setMeasureData(data);
- }
return this;
}
INSERT INTO project_measures (
value, metric_id, snapshot_id, rule_id, text_value, tendency, measure_date,
project_id, alert_status, alert_text, url, description, rule_priority, characteristic_id, variation_value_1,
- variation_value_2, variation_value_3, variation_value_4, variation_value_5, person_id)
+ variation_value_2, variation_value_3, variation_value_4, variation_value_5, person_id, measure_data)
VALUES (
#{value}, #{metricId}, #{snapshotId}, #{ruleId}, #{textValue}, #{tendency},
#{measureDate}, #{projectId}, #{alertStatus}, #{alertText},
#{url}, #{description}, #{rulePriority.ordinal}, #{characteristicId}, #{variationValue1},
- #{variationValue2}, #{variationValue3}, #{variationValue4}, #{variationValue5}, #{personId}
+ #{variationValue2}, #{variationValue3}, #{variationValue4}, #{variationValue5}, #{personId}, #{data}
)
</insert>
- <insert id="insertData" parameterType="MeasureData" keyColumn="id" useGeneratedKeys="true" keyProperty="id">
- INSERT INTO measure_data (measure_id, snapshot_id, data)
- VALUES (#{measure.id}, #{measure.snapshotId}, #{data})
- </insert>
-
- <update id="deleteData" parameterType="MeasureModel">
- DELETE FROM measure_data WHERE measure_id=#{id} AND snapshot_id=#{snapshotId}
- </update>
-
<update id="update" parameterType="MeasureModel">
UPDATE project_measures
SET
variation_value_3 = #{variationValue3},
variation_value_4 = #{variationValue4},
variation_value_5 = #{variationValue5},
- person_id = #{personId}
+ person_id = #{personId},
+ measure_data = #{data}
WHERE id = #{id}
</update>
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.database.model;
-
-import java.io.UnsupportedEncodingException;
-
-import com.google.common.base.Charsets;
-import org.junit.Test;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class MeasureDataTest {
- @Test
- public void text_is_utf8() throws UnsupportedEncodingException {
- String s = "accents éà and special characters ç€";
-
- MeasureData data = new MeasureData();
- data.setData(s.getBytes(Charsets.UTF_8.name()));
-
- assertThat(data.getText()).isEqualTo(s);
- }
-}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.database.model;
+
+import org.junit.Test;
+import org.sonar.api.measures.CoreMetrics;
+
+import java.io.UnsupportedEncodingException;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class MeasureModelTest {
+ @Test
+ public void text_is_utf8() throws UnsupportedEncodingException {
+ String s = "accents éà and special characters ç€";
+
+ MeasureModel measure = new MeasureModel();
+ measure.setData(s);
+
+ assertThat(measure.getData(CoreMetrics.DUPLICATIONS_DATA)).isEqualTo(s);
+ }
+}
# create duplication groups
@duplication_groups = []
- if duplications_data && duplications_data.measure_data && duplications_data.measure_data.data
- dups = Document.new duplications_data.measure_data.data.to_s
+ if duplications_data && duplications_data.data
+ dups = Document.new duplications_data.data.to_s
if XPath.match(dups, "//g").size > 0
parse_duplications(dups, @duplication_groups)
else
+++ /dev/null
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 3 of the License, or (at your option) any later version.
-#
-# SonarQube is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-class MeasureData < ActiveRecord::Base
- set_table_name :measure_data
- belongs_to :measure, :class_name => 'ProjectMeasure', :foreign_key => 'measure_id'
-
-end
\ No newline at end of file
belongs_to :project
belongs_to :characteristic
belongs_to :person, :class_name => 'Project', :foreign_key => 'person_id'
- has_one :measure_data, :class_name => 'MeasureData', :foreign_key => 'measure_id'
def metric
@metric ||=
def data
if metric.data?
- text_value || (measure_data && measure_data.data)
+ text_value || measure_data
else
text_value
end
end
def self.add_measures_column(colname)
- unless ProjectMeasure.column_names.include?(name)
+ unless ProjectMeasure.column_names.include?(colname)
add_column(:project_measures, colname, :decimal, :null => true, :precision => 30, :scale => 20)
end
end
--- /dev/null
+#
+# SonarQube, open source software quality management tool.
+# Copyright (C) 2008-2014 SonarSource
+# mailto:contact AT sonarsource DOT com
+#
+# SonarQube is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 3 of the License, or (at your option) any later version.
+#
+# SonarQube is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+#
+# SonarQube 4.4
+# SONAR-5249
+#
+class MergeMeasureDataIntoProjectMeasure < ActiveRecord::Migration
+
+ class ProjectMeasure < ActiveRecord::Base
+ end
+
+ def self.up
+ unless ProjectMeasure.column_names.include?('data')
+ add_column :project_measures, 'measure_data', :binary, :null => true
+ end
+ ProjectMeasure.reset_column_information
+ execute_ddl('move measure data', 'UPDATE project_measures m SET m.measure_data = (SELECT md.data FROM measure_data md WHERE md.measure_id = m.id)')
+ drop_table(:measure_data)
+ end
+
+ def self.execute_ddl(message, ddl)
+ begin
+ say_with_time(message) do
+ ProjectMeasure.connection.execute(ddl)
+ end
+ rescue
+ # already executed
+ end
+ end
+
+end