]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5249 Merge measure_data and project_measure tables
authorJulien HENRY <julien.henry@sonarsource.com>
Tue, 29 Apr 2014 08:45:35 +0000 (10:45 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Tue, 29 Apr 2014 08:46:21 +0000 (10:46 +0200)
46 files changed:
sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
sonar-batch/src/main/java/org/sonar/batch/index/DefaultPersistenceManager.java
sonar-batch/src/main/java/org/sonar/batch/index/MeasurePersister.java
sonar-batch/src/main/java/org/sonar/batch/index/MemoryOptimizer.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/index/PersistenceManager.java
sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
sonar-batch/src/test/java/org/sonar/batch/index/MeasurePersisterTest.java
sonar-batch/src/test/java/org/sonar/batch/index/MemoryOptimizerTest.java [deleted file]
sonar-batch/src/test/resources/org/sonar/batch/index/MeasurePersisterTest/shouldAddDelayedMeasureSeveralTimes-result.xml
sonar-batch/src/test/resources/org/sonar/batch/index/MeasurePersisterTest/shouldAlwaysPersistNonFileMeasures-result.xml
sonar-batch/src/test/resources/org/sonar/batch/index/MeasurePersisterTest/shouldDelaySaving-result.xml
sonar-batch/src/test/resources/org/sonar/batch/index/MeasurePersisterTest/shouldInsertMeasure-result.xml
sonar-batch/src/test/resources/org/sonar/batch/index/MeasurePersisterTest/shouldInsertMeasureWithLargeData-result.xml
sonar-batch/src/test/resources/org/sonar/batch/index/MeasurePersisterTest/shouldInsertRuleMeasure-result.xml
sonar-batch/src/test/resources/org/sonar/batch/index/MeasurePersisterTest/shouldUpdateMeasure-result.xml
sonar-batch/src/test/resources/org/sonar/batch/index/MemoryOptimizerTest/shouldReloadEvictedMeasure.xml [deleted file]
sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDataDto.java
sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java
sonar-core/src/main/java/org/sonar/core/purge/PurgeCommands.java
sonar-core/src/main/java/org/sonar/core/purge/PurgeMapper.java
sonar-core/src/main/resources/META-INF/persistence.xml
sonar-core/src/main/resources/org/sonar/core/measure/db/MeasureDataMapper.xml
sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql
sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl
sonar-core/src/main/resources/org/sonar/core/purge/PurgeMapper.xml
sonar-core/src/test/java/org/sonar/core/measure/db/MeasureDataDaoTest.java
sonar-core/src/test/java/org/sonar/core/purge/PurgeCommandsTest.java
sonar-core/src/test/resources/org/sonar/core/measure/db/MeasureDataDaoTest/find_by_component_key_and_metric_key_without_text.xml
sonar-core/src/test/resources/org/sonar/core/measure/db/MeasureDataDaoTest/shared.xml
sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteSnapshot-result.xml
sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteSnapshot.xml
sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteWastedMeasuresWhenPurgingSnapshot-result.xml
sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteWastedMeasuresWhenPurgingSnapshot.xml
sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldPurgeSnapshot-result.xml
sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldPurgeSnapshot.xml
sonar-plugin-api/src/main/java/org/sonar/api/database/model/MeasureData.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/database/model/MeasureMapper.java
sonar-plugin-api/src/main/java/org/sonar/api/database/model/MeasureModel.java
sonar-plugin-api/src/main/resources/org/sonar/api/database/model/MeasureMapper.xml
sonar-plugin-api/src/test/java/org/sonar/api/database/model/MeasureDataTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/database/model/MeasureModelTest.java [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb
sonar-server/src/main/webapp/WEB-INF/app/models/measure_data.rb [deleted file]
sonar-server/src/main/webapp/WEB-INF/app/models/project_measure.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/163_add_variation_columns.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/530_merge_measure_data_into_project_measures.rb [new file with mode: 0644]

index 9624513e288a71e0d23d4eeb968e5cb9e458fd36..d5e42948fc5f51b937dcbf33229c2840ac65a425 100644 (file)
@@ -176,10 +176,7 @@ public class DefaultIndex extends SonarIndex {
   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;
   }
index 14da97381cff207c3e47eb17f3dda2427bab5a82..9dd3460e0ff286c7e825fbed0c89ef82918b9d57 100644 (file)
@@ -40,8 +40,8 @@ public final class DefaultPersistenceManager implements PersistenceManager {
   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;
@@ -88,10 +88,6 @@ public final class DefaultPersistenceManager implements PersistenceManager {
     }
   }
 
-  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);
index 8e61a931bd0da86145e2aab288c86ba77a8c7fab..2e1c8995bac8b0479ffae74412cc527f7674df05 100644 (file)
@@ -47,25 +47,19 @@ public final class MeasurePersister {
   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());
 
@@ -81,16 +75,12 @@ public final class MeasurePersister {
       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) {
@@ -192,9 +182,6 @@ public final class MeasurePersister {
       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);
@@ -216,9 +203,6 @@ public final class MeasurePersister {
       MeasureMapper mapper = session.getMapper(MeasureMapper.class);
 
       mapper.insert(value);
-      if (value.getMeasureData() != null) {
-        mapper.insertData(value.getMeasureData());
-      }
 
       session.commit();
     } finally {
@@ -238,10 +222,6 @@ public final class MeasurePersister {
       MeasureMapper mapper = session.getMapper(MeasureMapper.class);
 
       mapper.update(value);
-      mapper.deleteData(value);
-      if (value.getMeasureData() != null) {
-        mapper.insertData(value.getMeasureData());
-      }
 
       session.commit();
     } finally {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/MemoryOptimizer.java b/sonar-batch/src/main/java/org/sonar/batch/index/MemoryOptimizer.java
deleted file mode 100644 (file)
index 9daa941..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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();
-    }
-  }
-
-}
index d42e1a9f2e18d71086e9f821d85719e46ffc3814..dec88e49d15314afe5ee1fb7ab656da67a693a46 100644 (file)
@@ -46,8 +46,6 @@ public interface PersistenceManager {
 
   void saveMeasure(Resource resource, Measure measure);
 
-  Measure reloadMeasure(Measure measure);
-
   void saveDependency(Project project, Dependency dependency, Dependency parentDependency);
 
   void saveLink(Project project, ProjectLink link);
index e4eacf6aa8d2aebc440b10e1e1432767beaddfca..59e68e6078cc1c086212b40beb9208375e5303a5 100644 (file)
@@ -21,7 +21,6 @@ package org.sonar.batch.scan;
 
 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;
@@ -36,12 +35,33 @@ import org.sonar.batch.DefaultFileLinesContextFactory;
 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;
@@ -112,7 +132,6 @@ public class ProjectScanContainer extends ComponentContainer {
       EventPersister.class,
       LinkPersister.class,
       MeasurePersister.class,
-      MemoryOptimizer.class,
       DefaultResourcePersister.class,
       SourcePersister.class,
       DefaultNotificationManager.class,
index fc3a69628d28a6cb26a0bb2985096d9f05e462fa..0b3363527da66c0f5e81dc1e1106b436e7447e68 100644 (file)
@@ -23,8 +23,6 @@ import org.apache.commons.lang.StringUtils;
 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;
@@ -41,10 +39,7 @@ import org.sonar.api.utils.SonarException;
 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 {
@@ -64,7 +59,6 @@ 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");
@@ -78,7 +72,7 @@ public class MeasurePersisterTest extends AbstractDaoTestCase {
     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
@@ -89,7 +83,6 @@ public class MeasurePersisterTest extends AbstractDaoTestCase {
     measurePersister.saveMeasure(project, measure);
 
     checkTables("shouldInsertMeasure", "project_measures");
-    verify(memoryOptimizer).evictDataMeasure(eq(measure), any(MeasureModel.class));
     assertThat(measure.getId()).isNotNull();
   }
 
@@ -105,15 +98,6 @@ public class MeasurePersisterTest extends AbstractDaoTestCase {
     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");
@@ -135,11 +119,8 @@ public class MeasurePersisterTest extends AbstractDaoTestCase {
     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();
   }
 
@@ -149,7 +130,7 @@ public class MeasurePersisterTest extends AbstractDaoTestCase {
 
     measurePersister.saveMeasure(aFile, new Measure(coverage()).setValue(100.0));
 
-    assertEmptyTables("project_measures", "measure_data");
+    assertEmptyTables("project_measures");
   }
 
   @Test
@@ -158,7 +139,7 @@ public class MeasurePersisterTest extends AbstractDaoTestCase {
 
     measurePersister.saveMeasure(aFile, new Measure("ncloc").setPersistenceMode(PersistenceMode.MEMORY));
 
-    assertEmptyTables("project_measures", "measure_data");
+    assertEmptyTables("project_measures");
   }
 
   @Test
@@ -179,7 +160,7 @@ public class MeasurePersisterTest extends AbstractDaoTestCase {
     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
@@ -207,7 +188,7 @@ public class MeasurePersisterTest extends AbstractDaoTestCase {
     assertEmptyTables("project_measures");
 
     measurePersister.dump();
-    checkTables("shouldDelaySaving", "project_measures", "measure_data");
+    checkTables("shouldDelaySaving", "project_measures");
   }
 
   @Test
@@ -242,11 +223,11 @@ public class MeasurePersisterTest extends AbstractDaoTestCase {
     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
diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/MemoryOptimizerTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/MemoryOptimizerTest.java
deleted file mode 100644 (file)
index 468654d..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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;
-  }
-}
index a9d69262af3bfb0f8ce8b36fb37d9d5caca05b19..416ec0a604b26606d0ead749e82f27da0a9a1f6a 100644 (file)
@@ -4,6 +4,7 @@
                     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>
index cc956fb7770e2344b184d72fc7492174ef271189..cd064d6d9f1c889fbd9a00b404f0d714d820f745 100644 (file)
@@ -4,11 +4,13 @@
                     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>
index 97b4eb2090a511b4c722407748b710f8323f7a19..28f2942aec1604f19ef1a48d3da876fe1227b6d0 100644 (file)
@@ -5,14 +5,14 @@
                     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>
index f7475f591e862161e0d9ed17a9f86507255c830e..a19db3a8c05e5a22d57f2bc655b6e257cd237cf8 100644 (file)
@@ -4,6 +4,7 @@
                     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>
index 77b6b6049a889d00a38bcdc24ba6cd0991726043..7aec2e88e4eacd0641591162887434d3ef11d3e9 100644 (file)
@@ -5,8 +5,7 @@
                     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>
index 5472c06aaea0d5d285cb31cff41051b226d8384d..89acf2b2223e5d22ab0d9c1ef5ade268389c8e2c 100644 (file)
@@ -4,6 +4,7 @@
                     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>
index 22201f588e4d54f29ff50828dde5ef0f62a5e34a..07f08fb086c22419e5c8ba1e94c7372a0e14fa40 100644 (file)
@@ -4,20 +4,21 @@
                     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>
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/index/MemoryOptimizerTest/shouldReloadEvictedMeasure.xml b/sonar-batch/src/test/resources/org/sonar/batch/index/MemoryOptimizerTest/shouldReloadEvictedMeasure.xml
deleted file mode 100644 (file)
index 5f40b82..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<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
index 474aee60f7a5ee7bd1a7959366e07b21af237e65..c2003a9796eeaf937faac45f3ca22dc0acdd5de0 100644 (file)
@@ -28,8 +28,6 @@ public class MeasureDataDto {
 
   private Integer id;
 
-  private Long measureId;
-
   private Integer snapshotId;
 
   private byte[] data;
@@ -43,15 +41,6 @@ public class MeasureDataDto {
     return this;
   }
 
-  public Long getMeasureId() {
-    return measureId;
-  }
-
-  public MeasureDataDto setMeasureId(Long measureId) {
-    this.measureId = measureId;
-    return this;
-  }
-
   public Integer getSnapshotId() {
     return snapshotId;
   }
index d815836f613ffe3d5f47324288debf0061bd10e2..41ca1b31a1e49579c38f7b964245fbcf06c95d21 100644 (file)
@@ -33,7 +33,7 @@ import java.util.List;
  */
 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
@@ -67,7 +67,6 @@ public class DatabaseVersion implements BatchComponent, ServerComponent {
     "issue_filter_favourites",
     "loaded_templates",
     "manual_measures",
-    "measure_data",
     "measure_filters",
     "measure_filter_favourites",
     "metrics",
index 765f8e2a7bfd60d3c451a6e5c45b1bcb60a5d812..3a4e0ac18e691f30aa4e0a0f58eb8d9435983e85 100644 (file)
@@ -173,13 +173,6 @@ class PurgeCommands {
     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);
@@ -276,7 +269,8 @@ class PurgeCommands {
     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);
index ff7d36d2d042d44e08f3e77bdfc98056553af928..684c8d6500ea85615fab4149535fd057847de1e2 100644 (file)
@@ -48,8 +48,6 @@ public interface PurgeMapper {
 
   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);
index 034e3dffd100c2ce9484b322e34aaa580645d147..4caafcf45ede87c199265cbb55ed2e4ef4828fa0 100644 (file)
@@ -12,7 +12,6 @@
     <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>
index 2ee23a30df0110e357050833ec2ee280b37e17cf..b908ad21cd14369ef65c4386134795561e0ccadb 100644 (file)
@@ -4,17 +4,15 @@
 <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
index 0c06c24b650d79511c3978afdaccda26859e8467..968d26bed9726fdd74546404e4e8a1c73925f72a 100644 (file)
@@ -225,6 +225,7 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('523');
 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;
index 78504f74af38b366edd70d23cf9c2bbadf6cca3d..4b1234367c9247add70379c8b9297fc1d09a61c3 100644 (file)
@@ -72,13 +72,6 @@ CREATE TABLE "WIDGETS" (
   "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),
@@ -277,7 +270,8 @@ CREATE TABLE "PROJECT_MEASURES" (
   "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" (
@@ -612,10 +606,6 @@ CREATE UNIQUE INDEX "METRICS_UNIQUE_NAME" ON "METRICS" ("NAME");
 
 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");
index cd4dc492f891169a66ab1cd4933b2ae1d1b106d1..6b204d180a3d4355ff710bf4547448feeec643af 100644 (file)
     </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=",">
index d83e09ad37b50070b3909273511ada83ebf1b65c..507facc96db5a8420614984921b2b0854a07e058 100644 (file)
@@ -40,14 +40,12 @@ public class MeasureDataDaoTest extends AbstractDaoTestCase {
     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
@@ -55,8 +53,7 @@ public class MeasureDataDaoTest extends AbstractDaoTestCase {
     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();
index 7d57347f425995a2058222cadbac0c49930d2f0f..8bf3763296686c989252d89ccc792a0eb939fd30 100644 (file)
@@ -53,7 +53,7 @@ public class PurgeCommandsTest extends AbstractDaoTestCase {
       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");
   }
 
   /**
@@ -84,7 +84,7 @@ public class PurgeCommandsTest extends AbstractDaoTestCase {
       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
@@ -140,9 +140,9 @@ public class PurgeCommandsTest extends AbstractDaoTestCase {
     // 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;
index 0d9b98c4fcd54ac05395637bb6e7a126fd5bd17e..a4092fddc22132505f49f6018a8b7683b94f62a1 100644 (file)
@@ -4,7 +4,6 @@
   <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>
index 7fd1781b05ba8d6eab6fbf80b4448a55aaab5e54..57fb0e395d12969d0506d3eeccde6b70cce2219c 100644 (file)
@@ -4,7 +4,6 @@
   <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>
index 028d67e409d161a21afb7e330e4da862d5f4ecb8..dbbab34b4f9c493602317d30c2760d19a6c8d66b 100644 (file)
@@ -22,8 +22,7 @@
                     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"/>
index 69ee6858e9b0ebe833e2b65a40744f3e4c8d858b..bfdbc9c5f63664339489597d8ffbdfc0c3730455 100644 (file)
@@ -20,8 +20,7 @@
                     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"/>
@@ -51,8 +50,7 @@
                     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"/>
index 81249826cc2d4aaa0cf06ae00e7cc60585a143f0..1234157d512a7b98fd45668a7fb0c914316deb83 100644 (file)
@@ -33,7 +33,7 @@
                     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"
@@ -43,7 +43,7 @@
                     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"
@@ -53,7 +53,7 @@
                     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"
@@ -63,7 +63,7 @@
                     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"
@@ -73,7 +73,7 @@
                     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"
@@ -83,5 +83,5 @@
                       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>
index 83204ee61d6f9c1925ffd5f7500f9703e323369d..cb1197cc1eba98a92e066fe38335e7687053ed72 100644 (file)
@@ -33,7 +33,7 @@
                     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"
@@ -43,7 +43,7 @@
                     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"
@@ -53,7 +53,7 @@
                     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"
@@ -63,7 +63,7 @@
                     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"
@@ -73,7 +73,7 @@
                     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"
@@ -83,5 +83,5 @@
                     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>
index 382e60aa51882c63c712d89728a974f4b3f46a83..54257ab7f5df480e1d6505ef260ae66ff80df9bd 100644 (file)
@@ -29,9 +29,7 @@ Note that measures, events and reviews are not deleted.
                     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]"-->
@@ -65,9 +63,7 @@ Note that measures, events and reviews are not deleted.
                     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]"
index 065d64d23cc34ddb8cd00bfab64840864861c27d..4a2123e1412baa97ff802697a2b04811dd20b0db 100644 (file)
@@ -16,9 +16,7 @@
                     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]"
@@ -54,9 +52,7 @@
                       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]"
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/database/model/MeasureData.java b/sonar-plugin-api/src/main/java/org/sonar/api/database/model/MeasureData.java
deleted file mode 100644 (file)
index b0275b6..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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();
-  }
-}
-
index b55da95413e586321b64619251fe98e2e69b0226..42b7afc9b70a21c8cdb973c699d2b8f20b3452da 100644 (file)
@@ -22,9 +22,5 @@ package org.sonar.api.database.model;
 public interface MeasureMapper {
   void insert(MeasureModel measure);
 
-  void insertData(MeasureData data);
-
-  void deleteData(MeasureModel data);
-
   void update(MeasureModel measure);
 }
index f2a00deccfb58e5bea3a42ddb7be8bee4a85323b..95aa6b4f6bf47cd97c24a9d0c9447ddff24decc7 100644 (file)
  */
 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
@@ -78,7 +87,7 @@ public class MeasureModel implements Cloneable {
    */
   @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)
@@ -108,15 +117,15 @@ public class MeasureModel implements Cloneable {
   @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;
   }
@@ -357,8 +366,13 @@ public class MeasureModel implements Cloneable {
     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;
   }
@@ -369,40 +383,19 @@ public class MeasureModel implements Cloneable {
   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
    */
@@ -482,16 +475,7 @@ public class MeasureModel implements Cloneable {
    * @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;
   }
 
index a3f83181d7511d2721baceb095f1137c1bb86c1f..6cb43d9509b4f844f73f77d0798c3ff2fb9e11d0 100644 (file)
@@ -7,24 +7,15 @@
     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
@@ -44,7 +35,8 @@
       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>
 
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/database/model/MeasureDataTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/database/model/MeasureDataTest.java
deleted file mode 100644 (file)
index 37f8319..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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);
-  }
-}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/database/model/MeasureModelTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/database/model/MeasureModelTest.java
new file mode 100644 (file)
index 0000000..5205e96
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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);
+  }
+}
index 5a3ce9def0e501dd2f0a81df288241391a9cc920..bc8837bac8a6747861babf914eff124e49546c30 100644 (file)
@@ -224,8 +224,8 @@ class ResourceController < ApplicationController
 
     # 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
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/measure_data.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/measure_data.rb
deleted file mode 100644 (file)
index dc8d232..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# 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
index 9dae53b99e8ee2ceacf7f5653ee4b83f07ce73de..98af92f13215288e3ed172e505a707afb66a2798 100644 (file)
@@ -30,7 +30,6 @@ class ProjectMeasure < ActiveRecord::Base
   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 ||=
@@ -50,7 +49,7 @@ class ProjectMeasure < ActiveRecord::Base
 
   def data
     if metric.data?
-      text_value || (measure_data && measure_data.data)
+      text_value || measure_data
     else
       text_value
     end
index 496da8ed5846d8dc77dd41f1920537f176e3ef7b..50c24435a78ad6d27eca1cdd3cf523731dcd9573 100644 (file)
@@ -204,7 +204,7 @@ class AddVariationColumns < ActiveRecord::Migration
   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
diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/530_merge_measure_data_into_project_measures.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/530_merge_measure_data_into_project_measures.rb
new file mode 100644 (file)
index 0000000..b63f392
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# 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