public MeasureDto toMeasureDto(Measure measure, Metric metric, Component component) {
MeasureDto out = new MeasureDto();
out.setMetricId(metric.getId());
- out.setComponentId(dbIdsRepository.getComponentId(component));
+ out.setComponentUuid(component.getUuid());
out.setSnapshotId(dbIdsRepository.getSnapshotId(component));
if (measure.hasVariations()) {
setVariations(out, measure.getVariations());
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
-import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.measure.MeasureDto;
-import org.sonar.db.rule.RuleDto;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.Measure.StringValue;
import org.sonar.server.computation.batch.BatchReportReader;
private final Metric metric2 = mock(Metric.class);
private static final long LAST_SNAPSHOT_ID = 123;
private static final long OTHER_SNAPSHOT_ID = 369;
- private static final long COMPONENT_ID = 567;
+ private static final String COMPONENT_UUID = "UUID1";
private static final Measure SOME_MEASURE = Measure.newMeasureBuilder().create("some value");
private static final String SOME_DATA = "some data";
- private static final RuleDto SOME_RULE = RuleDto.createFor(RuleKey.of("A", "1")).setId(963);
private ReportMetricValidator reportMetricValidator = mock(ReportMetricValidator.class);
@Test
public void getBaseMeasure_returns_Measure_if_measure_of_last_snapshot_only_in_DB() {
dbTester.prepareDbUnit(getClass(), "shared.xml");
- dbClient.measureDao().insert(dbSession, createMeasureDto(METRIC_ID_1, LAST_SNAPSHOT_ID));
- dbClient.measureDao().insert(dbSession, createMeasureDto(METRIC_ID_2, OTHER_SNAPSHOT_ID));
+ dbClient.measureDao().insert(dbSession, createMeasureDto(METRIC_ID_1, FILE_COMPONENT.getUuid(), LAST_SNAPSHOT_ID));
+ dbClient.measureDao().insert(dbSession, createMeasureDto(METRIC_ID_2, FILE_COMPONENT.getUuid(), OTHER_SNAPSHOT_ID));
dbSession.commit();
// metric 1 is associated to snapshot with "last=true"
assertThat(rawMeasures.get(METRIC_KEY_2)).containsOnly(Measure.newMeasureBuilder().create("some value"));
}
- private static MeasureDto createMeasureDto(int metricId, long snapshotId) {
+ private static MeasureDto createMeasureDto(int metricId, String componentUuid, long snapshotId) {
return new MeasureDto()
- .setComponentId(COMPONENT_ID)
+ .setComponentUuid(componentUuid)
.setSnapshotId(snapshotId)
.setData(SOME_DATA)
.setMetricId(metricId);
public void toMeasureDto_set_componentId_and_snapshotId_from_method_arguments(Measure measure, Metric metric) {
MeasureDto measureDto = underTest.toMeasureDto(measure, metric, SOME_COMPONENT);
- assertThat(measureDto.getComponentId()).isEqualTo(SOME_COMPONENT_ID);
+ assertThat(measureDto.getComponentUuid()).isEqualTo(SOME_COMPONENT.getUuid());
assertThat(measureDto.getSnapshotId()).isEqualTo(SOME_SNAPSHOT_ID);
}
import org.junit.Test;
import org.sonar.api.measures.Metric;
import org.sonar.api.utils.System2;
-import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
}
private void setupReportComponents() {
- Component project = ReportComponent.builder(PROJECT, ROOT_REF)
+ Component project = ReportComponent.builder(PROJECT, ROOT_REF).setUuid("root-uuid")
.addChildren(
- ReportComponent.builder(MODULE, INTERMEDIATE_1_REF)
+ ReportComponent.builder(MODULE, INTERMEDIATE_1_REF).setUuid("intermediate1-uuid")
.addChildren(
- ReportComponent.builder(DIRECTORY, INTERMEDIATE_2_REF)
+ ReportComponent.builder(DIRECTORY, INTERMEDIATE_2_REF).setUuid("intermediate2-uuid")
.addChildren(
- ReportComponent.builder(FILE, LEAF_REF)
+ ReportComponent.builder(FILE, LEAF_REF).setUuid("leaf-uuid")
.build())
.build())
.build())
}
private void setupViewsComponents() {
- Component view = ViewsComponent.builder(VIEW, ROOT_REF)
+ Component view = ViewsComponent.builder(VIEW, ROOT_REF).setUuid("root-uuid")
.addChildren(
- ViewsComponent.builder(SUBVIEW, INTERMEDIATE_1_REF)
+ ViewsComponent.builder(SUBVIEW, INTERMEDIATE_1_REF).setUuid("intermediate1-uuid")
.addChildren(
- ViewsComponent.builder(SUBVIEW, INTERMEDIATE_2_REF)
+ ViewsComponent.builder(SUBVIEW, INTERMEDIATE_2_REF).setUuid("intermediate2-uuid")
.addChildren(
- ViewsComponent.builder(PROJECT_VIEW, LEAF_REF)
+ ViewsComponent.builder(PROJECT_VIEW, LEAF_REF).setUuid("leaf-uuid")
.build())
.build())
.build())
}
private void setupDbIds() {
- rootDto = addComponent("root-key");
- intermediate1Dto = addComponent("intermediate1-key");
- intermediate2Dto = addComponent("intermediate2-key");
- leafDto = addComponent("leaf-key");
+ rootDto = addComponent("root-key", "root-uuid");
+ intermediate1Dto = addComponent("intermediate1-key", "intermediate1-uuid");
+ intermediate2Dto = addComponent("intermediate2-key", "intermediate2-uuid");
+ leafDto = addComponent("leaf-key", "leaf-uuid");
setDbIds(ROOT_REF, rootDto.getId(), ROOT_SNAPSHOT_ID);
setDbIds(INTERMEDIATE_1_REF, intermediate1Dto.getId(), INTERMEDIATE_1_SNAPSHOT_ID);
Map<String, Object> dto = dtos.get(0);
assertThat(dto.get("snapshotId")).isEqualTo(ROOT_SNAPSHOT_ID);
- assertThat(dto.get("componentId")).isEqualTo(rootDto.getId());
+ assertThat(dto.get("componentUuid")).isEqualTo(rootDto.uuid());
assertThat(dto.get("metricId")).isEqualTo((long) stringMetricId);
assertThat(dto.get("value")).isNull();
assertThat(dto.get("textValue")).isEqualTo("measure-data");
dto = dtos.get(1);
assertThat(dto.get("snapshotId")).isEqualTo(INTERMEDIATE_1_SNAPSHOT_ID);
- assertThat(dto.get("componentId")).isEqualTo(intermediate1Dto.getId());
+ assertThat(dto.get("componentUuid")).isEqualTo(intermediate1Dto.uuid());
assertThat(dto.get("metricId")).isEqualTo((long) intMetricId);
assertValue(dto, 12d);
assertThat(dto.get("textValue")).isNull();
dto = dtos.get(2);
assertThat(dto.get("snapshotId")).isEqualTo(INTERMEDIATE_2_SNAPSHOT_ID);
- assertThat(dto.get("componentId")).isEqualTo(intermediate2Dto.getId());
+ assertThat(dto.get("componentUuid")).isEqualTo(intermediate2Dto.uuid());
assertThat(dto.get("metricId")).isEqualTo((long) longMetricId);
assertValue(dto, 9635d);
assertThat(dto.get("textValue")).isNull();
dto = dtos.get(3);
assertThat(dto.get("snapshotId")).isEqualTo(LEAF_SNAPSHOT_ID);
- assertThat(dto.get("componentId")).isEqualTo(leafDto.getId());
+ assertThat(dto.get("componentUuid")).isEqualTo(leafDto.uuid());
assertThat(dto.get("metricId")).isEqualTo((long) doubleMetricId);
assertValue(dto, 123.1d);
assertThat(dto.get("textValue")).isNull();
Map<String, Object> dto = dtos.get(0);
assertThat(dto.get("snapshotId")).isEqualTo(ROOT_SNAPSHOT_ID);
- assertThat(dto.get("componentId")).isEqualTo(rootDto.getId());
+ assertThat(dto.get("componentUuid")).isEqualTo(rootDto.uuid());
assertThat(dto.get("textValue")).isEqualTo("0=1;2=10");
}
Map<String, Object> dto = dtos.get(0);
assertThat(dto.get("snapshotId")).isEqualTo(ROOT_SNAPSHOT_ID);
- assertThat(dto.get("componentId")).isEqualTo(rootDto.getId());
+ assertThat(dto.get("componentUuid")).isEqualTo(rootDto.uuid());
assertThat(dto.get("textValue")).isEqualTo("0=1;2=10");
}
Map<String, Object> dto = dtos.get(0);
assertThat(dto.get("snapshotId")).isEqualTo(ROOT_SNAPSHOT_ID);
- assertThat(dto.get("componentId")).isEqualTo(rootDto.getId());
+ assertThat(dto.get("componentUuid")).isEqualTo(rootDto.uuid());
assertThat(dto.get("textValue")).isEqualTo("0=1;2=10");
}
assertThat(dto.get("developerId")).isEqualTo(10L);
}
- private ComponentDto addComponent(String key) {
- ComponentDto componentDto = new ComponentDto().setKey(key).setUuid(Uuids.create());
+ private ComponentDto addComponent(String key, String uuid) {
+ ComponentDto componentDto = new ComponentDto().setKey(key).setUuid(uuid);
dbClient.componentDao().insert(dbTester.getSession(), componentDto);
return componentDto;
}
private List<Map<String, Object>> selectSnapshots() {
return dbTester
.select(
- "SELECT snapshot_id as \"snapshotId\", project_id as \"componentId\", metric_id as \"metricId\", person_id as \"developerId\", "
- +
- "value as \"value\", text_value as \"textValue\", " +
- "variation_value_1 as \"variation_value_1\", " +
- "variation_value_2 as \"variation_value_2\", " +
- "variation_value_3 as \"variation_value_3\", " +
- "variation_value_4 as \"variation_value_4\", " +
- "variation_value_5 as \"variation_value_5\"" +
- "FROM project_measures " +
- "ORDER by snapshot_id asc");
+ "SELECT snapshot_id as \"snapshotId\", component_uuid as \"componentUuid\", metric_id as \"metricId\", person_id as \"developerId\", "
+ +
+ "value as \"value\", text_value as \"textValue\", " +
+ "variation_value_1 as \"variation_value_1\", " +
+ "variation_value_2 as \"variation_value_2\", " +
+ "variation_value_3 as \"variation_value_3\", " +
+ "variation_value_4 as \"variation_value_4\", " +
+ "variation_value_5 as \"variation_value_5\"" +
+ "FROM project_measures " +
+ "ORDER by snapshot_id asc");
}
@Override
public void do_nothing_when_no_raw_measure() {
SnapshotDto period1ProjectSnapshot = newSnapshotForProject(PROJECT_DTO);
dbClient.snapshotDao().insert(session, period1ProjectSnapshot);
- dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.getId(), period1ProjectSnapshot.getId(), 60d));
+ dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.uuid(), period1ProjectSnapshot.getId(), 60d));
session.commit();
periodsHolder.setPeriods(newPeriod(1, period1ProjectSnapshot));
// Project
SnapshotDto period1ProjectSnapshot = newSnapshotForProject(PROJECT_DTO);
dbClient.snapshotDao().insert(session, period1ProjectSnapshot);
- dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.getId(), period1ProjectSnapshot.getId(), 60d));
+ dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.uuid(), period1ProjectSnapshot.getId(), 60d));
// Directory
ComponentDto directoryDto = ComponentTesting.newDirectory(PROJECT_DTO, "dir");
dbClient.componentDao().insert(session, directoryDto);
SnapshotDto period1DirectorySnapshot = createForComponent(directoryDto, period1ProjectSnapshot);
dbClient.snapshotDao().insert(session, period1DirectorySnapshot);
- dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), directoryDto.getId(), period1DirectorySnapshot.getId(), 10d));
+ dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), directoryDto.uuid(), period1DirectorySnapshot.getId(), 10d));
session.commit();
periodsHolder.setPeriods(newPeriod(1, period1ProjectSnapshot));
// Project
SnapshotDto period1ProjectSnapshot = newSnapshotForProject(PROJECT_DTO);
dbClient.snapshotDao().insert(session, period1ProjectSnapshot);
- dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.getId(), period1ProjectSnapshot.getId(), 60d));
+ dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.uuid(), period1ProjectSnapshot.getId(), 60d));
// Directory
ComponentDto directoryDto = ComponentTesting.newDirectory(PROJECT_DTO, "dir");
dbClient.componentDao().insert(session, directoryDto);
SnapshotDto period1DirectorySnapshot = createForComponent(directoryDto, period1ProjectSnapshot);
dbClient.snapshotDao().insert(session, period1DirectorySnapshot);
- dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), directoryDto.getId(), period1DirectorySnapshot.getId(), 10d));
+ dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), directoryDto.uuid(), period1DirectorySnapshot.getId(), 10d));
session.commit();
periodsHolder.setPeriods(newPeriod(1, period1ProjectSnapshot));
SnapshotDto currentProjectSnapshot = newSnapshotForProject(PROJECT_DTO).setCreatedAt(2000_000_000L);
dbClient.snapshotDao().insert(session, past1ProjectSnapshot);
dbClient.snapshotDao().insert(session, currentProjectSnapshot);
- dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.getId(), past1ProjectSnapshot.getId(), 60d));
- dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.getId(), currentProjectSnapshot.getId(), 60d));
+ dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.uuid(), past1ProjectSnapshot.getId(), 60d));
+ dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.uuid(), currentProjectSnapshot.getId(), 60d));
session.commit();
periodsHolder.setPeriods(newPeriod(1, past1ProjectSnapshot));
dbClient.snapshotDao().insert(session, period1ProjectSnapshot, period2ProjectSnapshot, period3ProjectSnapshot, period4ProjectSnapshot, period5ProjectSnapshot);
dbClient.measureDao().insert(session,
- newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.getId(), period1ProjectSnapshot.getId(), 0d),
- newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.getId(), period2ProjectSnapshot.getId(), 20d),
- newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.getId(), period3ProjectSnapshot.getId(), 40d),
- newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.getId(), period4ProjectSnapshot.getId(), 80d),
- newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.getId(), period5ProjectSnapshot.getId(), 100d));
+ newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.uuid(), period1ProjectSnapshot.getId(), 0d),
+ newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.uuid(), period2ProjectSnapshot.getId(), 20d),
+ newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.uuid(), period3ProjectSnapshot.getId(), 40d),
+ newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.uuid(), period4ProjectSnapshot.getId(), 80d),
+ newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.uuid(), period5ProjectSnapshot.getId(), 100d));
session.commit();
periodsHolder.setPeriods(newPeriod(1, period1ProjectSnapshot),
SnapshotDto period1ProjectSnapshot = newSnapshotForProject(PROJECT_DTO);
dbClient.snapshotDao().insert(session, period1ProjectSnapshot);
dbClient.measureDao().insert(session,
- newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.getId(), period1ProjectSnapshot.getId(), 60d),
- newMeasureDto(DEBT_METRIC.getId(), PROJECT_DTO.getId(), period1ProjectSnapshot.getId(), 10d),
- newMeasureDto(FILE_COMPLEXITY_METRIC.getId(), PROJECT_DTO.getId(), period1ProjectSnapshot.getId(), 2d),
- newMeasureDto(BUILD_BREAKER_METRIC.getId(), PROJECT_DTO.getId(), period1ProjectSnapshot.getId(), 1d));
+ newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.uuid(), period1ProjectSnapshot.getId(), 60d),
+ newMeasureDto(DEBT_METRIC.getId(), PROJECT_DTO.uuid(), period1ProjectSnapshot.getId(), 10d),
+ newMeasureDto(FILE_COMPLEXITY_METRIC.getId(), PROJECT_DTO.uuid(), period1ProjectSnapshot.getId(), 2d),
+ newMeasureDto(BUILD_BREAKER_METRIC.getId(), PROJECT_DTO.uuid(), period1ProjectSnapshot.getId(), 1d));
session.commit();
periodsHolder.setPeriods(newPeriod(1, period1ProjectSnapshot));
SnapshotDto period1ProjectSnapshot = newSnapshotForProject(PROJECT_DTO);
dbClient.snapshotDao().insert(session, period1ProjectSnapshot);
dbClient.measureDao().insert(session,
- newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.getId(), period1ProjectSnapshot.getId(), 60d));
+ newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.uuid(), period1ProjectSnapshot.getId(), 60d));
session.commit();
periodsHolder.setPeriods(newPeriod(1, period1ProjectSnapshot));
public void does_not_update_existing_variations() throws Exception {
SnapshotDto period1ProjectSnapshot = newSnapshotForProject(PROJECT_DTO);
dbClient.snapshotDao().insert(session, period1ProjectSnapshot);
- dbClient.measureDao().insert(session, newMeasureDto(NEW_DEBT.getId(), PROJECT_DTO.getId(), period1ProjectSnapshot.getId(), 60d));
+ dbClient.measureDao().insert(session, newMeasureDto(NEW_DEBT.getId(), PROJECT_DTO.uuid(), period1ProjectSnapshot.getId(), 60d));
session.commit();
periodsHolder.setPeriods(newPeriod(1, period1ProjectSnapshot));
treeRootHolder.setRoot(PROJECT);
assertThat(measureRepository.getRawMeasure(PROJECT, NEW_DEBT).get().getVariations().getVariation1()).isEqualTo(10d);
}
- private static MeasureDto newMeasureDto(int metricId, long projectId, long snapshotId, double value) {
- return new MeasureDto().setMetricId(metricId).setComponentId(projectId).setSnapshotId(snapshotId).setValue(value);
+ private static MeasureDto newMeasureDto(int metricId, String componentUuid, long snapshotId, double value) {
+ return new MeasureDto().setMetricId(metricId).setComponentUuid(componentUuid).setSnapshotId(snapshotId).setValue(value);
}
private static Period newPeriod(int index, SnapshotDto snapshotDto) {
public void do_nothing_when_no_raw_measure() {
SnapshotDto period1ViewSnapshot = newSnapshotForView(VIEW_DTO);
dbClient.snapshotDao().insert(session, period1ViewSnapshot);
- dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.getId(), period1ViewSnapshot.getId(), 60d));
+ dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.uuid(), period1ViewSnapshot.getId(), 60d));
session.commit();
periodsHolder.setPeriods(newPeriod(1, period1ViewSnapshot));
// View
SnapshotDto period1ViewSnapshot = newSnapshotForView(VIEW_DTO);
dbClient.snapshotDao().insert(session, period1ViewSnapshot);
- dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.getId(), period1ViewSnapshot.getId(), 60d));
+ dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.uuid(), period1ViewSnapshot.getId(), 60d));
// SubView
ComponentDto subviewDto = ComponentTesting.newSubView(VIEW_DTO, "dir", "key");
dbClient.componentDao().insert(session, subviewDto);
SnapshotDto period1SubviewSnapshot = createForComponent(subviewDto, period1ViewSnapshot);
dbClient.snapshotDao().insert(session, period1SubviewSnapshot);
- dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), subviewDto.getId(), period1SubviewSnapshot.getId(), 10d));
+ dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), subviewDto.uuid(), period1SubviewSnapshot.getId(), 10d));
session.commit();
periodsHolder.setPeriods(newPeriod(1, period1ViewSnapshot));
dbClient.snapshotDao().insert(session, period1ViewSnapshot, period2ViewSnapshot, period3ViewSnapshot, period4ViewSnapshot, period5ViewSnapshot);
dbClient.measureDao().insert(session,
- newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.getId(), period1ViewSnapshot.getId(), 0d),
- newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.getId(), period2ViewSnapshot.getId(), 20d),
- newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.getId(), period3ViewSnapshot.getId(), 40d),
- newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.getId(), period4ViewSnapshot.getId(), 80d),
- newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.getId(), period5ViewSnapshot.getId(), 100d));
+ newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.uuid(), period1ViewSnapshot.getId(), 0d),
+ newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.uuid(), period2ViewSnapshot.getId(), 20d),
+ newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.uuid(), period3ViewSnapshot.getId(), 40d),
+ newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.uuid(), period4ViewSnapshot.getId(), 80d),
+ newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.uuid(), period5ViewSnapshot.getId(), 100d));
session.commit();
periodsHolder.setPeriods(newPeriod(1, period1ViewSnapshot),
SnapshotDto period1ViewSnapshot = newSnapshotForProject(VIEW_DTO);
dbClient.snapshotDao().insert(session, period1ViewSnapshot);
dbClient.measureDao().insert(session,
- newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.getId(), period1ViewSnapshot.getId(), 60d),
- newMeasureDto(DEBT_METRIC.getId(), VIEW_DTO.getId(), period1ViewSnapshot.getId(), 10d),
- newMeasureDto(FILE_COMPLEXITY_METRIC.getId(), VIEW_DTO.getId(), period1ViewSnapshot.getId(), 2d),
- newMeasureDto(BUILD_BREAKER_METRIC.getId(), VIEW_DTO.getId(), period1ViewSnapshot.getId(), 1d)
+ newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.uuid(), period1ViewSnapshot.getId(), 60d),
+ newMeasureDto(DEBT_METRIC.getId(), VIEW_DTO.uuid(), period1ViewSnapshot.getId(), 10d),
+ newMeasureDto(FILE_COMPLEXITY_METRIC.getId(), VIEW_DTO.uuid(), period1ViewSnapshot.getId(), 2d),
+ newMeasureDto(BUILD_BREAKER_METRIC.getId(), VIEW_DTO.uuid(), period1ViewSnapshot.getId(), 1d)
);
session.commit();
assertThat(measureRepository.getRawMeasure(VIEW, BUILD_BREAKER_METRIC).get().getVariations().getVariation1()).isEqualTo(-1d);
}
- private static MeasureDto newMeasureDto(int metricId, long projectId, long snapshotId, double value) {
- return new MeasureDto().setMetricId(metricId).setComponentId(projectId).setSnapshotId(snapshotId).setValue(value);
+ private static MeasureDto newMeasureDto(int metricId, String componentUuid, long snapshotId, double value) {
+ return new MeasureDto().setMetricId(metricId).setComponentUuid(componentUuid).setSnapshotId(snapshotId).setValue(value);
}
private static Period newPeriod(int index, SnapshotDto snapshotDto) {
<dataset>
- <projects id="567" uuid="uuid_567" kee="file cpt key" enabled="[true]"/>
- <snapshots id="123" component_uuid="uuid_567" root_component_uuid="uuid_567" islast="[true]"/>
- <snapshots id="369" component_uuid="uuid_567" root_component_uuid="uuid_567" islast="[false]"/>
+ <projects id="567" uuid="uuid_1" kee="file cpt key" enabled="[true]"/>
+ <snapshots id="123" component_uuid="uuid_1" root_component_uuid="uuid_1" islast="[true]"/>
+ <snapshots id="369" component_uuid="uuid_1" root_component_uuid="uuid_1" islast="[false]"/>
<metrics id="1" name="metric 1" />
<metrics id="2" name="metric 2" />
</dataset>
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]" variation_value_5="400"
alert_text="[null]"
- text_value="[null]" project_id="[null]"
- alert_status="[null]" description="[null]"/>
+ text_value="[null]"
+ component_uuid="ABCD"
+ alert_status="[null]"
+ description="[null]"/>
<!-- details of the measure by person -->
<project_measures id="1002" metric_id="1" value="300" snapshot_id="101" person_id="30000"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]" variation_value_5="400"
alert_text="[null]"
- text_value="[null]" project_id="[null]"
- alert_status="[null]" description="[null]"/>
+ text_value="[null]"
+ component_uuid="ABCD"
+ alert_status="[null]"
+ description="[null]"/>
<project_measures id="1003" metric_id="1" value="200" snapshot_id="101" person_id="40000"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]" variation_value_5="400"
alert_text="[null]"
- text_value="[null]" project_id="[null]"
- alert_status="[null]" description="[null]"/>
+ text_value="[null]"
+ component_uuid="ABCD"
+ alert_status="[null]"
+ description="[null]"/>
</dataset>
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]" variation_value_5="400"
alert_text="[null]"
- text_value="[null]" project_id="[null]"
- alert_status="[null]" description="[null]" person_id="[null]"/>
+ text_value="[null]"
+ component_uuid="ABCD"
+ alert_status="[null]" description="[null]"
+ person_id="[null]"/>
<!-- details of the measure by model characteristic -->
<!--project_measures id="1002" metric_id="1" value="300" snapshot_id="101" characteristic_id="30000"
url="[null]" variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]" variation_value_5="400"
rule_priority="[null]" alert_text="[null]" RULES_CATEGORY_ID="[null]"
- text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
+ RULE_ID="[null]" text_value="[null]"
+ component_uuid="ABCD"
alert_status="[null]" description="[null]" person_id="[null]"/>-->
<!--project_measures id="1003" metric_id="1" value="200" snapshot_id="101" characteristic_id="40000"
url="[null]" variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]" variation_value_5="400"
- rule_priority="[null]" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+ alert_text="[null]" RULES_CATEGORY_ID="[null]"
+ RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" component_uuid="ABCD"
+ alert_status="[null]" description="[null]" person_id="[null]"/>
text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
alert_status="[null]" description="[null]" person_id="[null]"/>-->
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]" variation_value_5="400"
alert_text="[null]"
- text_value="[null]" project_id="[null]"
+ text_value="[null]" component_uuid="ABCD"
alert_status="[null]" description="[null]"/>
<project_measures id="1002" metric_id="1" value="510" snapshot_id="102"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]" variation_value_5="[null]"
alert_text="[null]"
- text_value="[null]" project_id="[null]"
- alert_status="[null]" description="[null]"/>
+ text_value="[null]"
+ alert_status="[null]" description="[null]"
+ component_uuid="BCDE" />
<project_measures id="1003" metric_id="1" value="500" snapshot_id="103"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]" variation_value_5="[null]"
alert_text="[null]"
- text_value="[null]" project_id="[null]"
- alert_status="[null]" description="[null]"/>
+ text_value="[null]"
+ alert_status="[null]" description="[null]"
+ component_uuid="CDEF" />
<project_measures id="1004" metric_id="1" value="10" snapshot_id="104"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]" variation_value_5="[null]"
alert_text="[null]"
- text_value="[null]" project_id="[null]"
- alert_status="[null]" description="[null]"/>
+ text_value="[null]"
+ alert_status="[null]" description="[null]"
+ component_uuid="DEFG"/>
<!-- profile of java project -->
<project_measures id="1005" metric_id="2" value="[null]" snapshot_id="101"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]" variation_value_5="[null]"
alert_text="[null]"
- text_value="Sonar way" project_id="[null]"
+ text_value="Sonar way"
+ component_uuid="ABCD"
alert_status="[null]" description="[null]"/>
<!-- coverage of java project -->
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]" variation_value_5="[null]"
alert_text="[null]"
- text_value="Sonar way" project_id="[null]"
+ text_value="Sonar way"
+ component_uuid="ABCD"
alert_status="[null]" description="[null]"/>
<!-- php project -->
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]" variation_value_5="4900"
alert_text="[null]"
- text_value="[null]" project_id="[null]"
+ text_value="[null]"
+ component_uuid="EFGH"
alert_status="[null]" description="[null]"/>
<project_measures id="1011" metric_id="2" value="[null]" snapshot_id="110"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]" variation_value_5="[null]"
alert_text="[null]"
- text_value="php way" project_id="[null]"
+ text_value="php way"
+ component_uuid="EFGH"
alert_status="[null]" description="[null]"/>
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]" variation_value_5="400"
alert_text="[null]"
- text_value="WARN" project_id="[null]"
+ text_value="WARN"
+ component_uuid="ABCD"
alert_status="[null]" description="[null]"/>
<!-- php project -->
url="[null]" variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]" variation_value_5="[null]"
alert_text="[null]"
- text_value="OK" project_id="[null]"
+ text_value="OK"
+ component_uuid="BCDE"
alert_status="[null]" description="[null]"/>
<!-- js project -->
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]" variation_value_5="[null]"
alert_text="[null]"
- text_value="ERROR" project_id="[null]"
+ text_value="ERROR"
+ component_uuid="CDEF"
alert_status="[null]" description="[null]"/>
DAY = 1000 * 60 * 60 * 24
belongs_to :snapshot
- belongs_to :project
+ belongs_to :project, :class_name => 'Project', :foreign_key => 'component_uuid', :primary_key => 'uuid'
belongs_to :person, :class_name => 'Project', :foreign_key => 'person_id'
def metric
--- /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 6.0
+#
+class AddComponentUuidToMeasures < ActiveRecord::Migration
+
+ def self.up
+ execute_java_migration('org.sonar.db.version.v60.AddComponentUuidColumnToMeasures')
+ 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 6.0
+#
+class PopulateComponentUuidOfMeasures < ActiveRecord::Migration
+
+ def self.up
+ execute_java_migration('org.sonar.db.version.v60.PopulateComponentUuidOfMeasures')
+ 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 6.0
+#
+class DeleteOrphanMeasuresWithoutComponent < ActiveRecord::Migration
+
+ def self.up
+ execute_java_migration('org.sonar.db.version.v60.DeleteOrphanMeasuresWithoutComponent')
+ 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 6.0
+#
+class MakeComponentUuidNotNullOnMeasures < ActiveRecord::Migration
+
+ def self.up
+ execute_java_migration('org.sonar.db.version.v60.MakeComponentUuidNotNullOnMeasures')
+ 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 6.0
+#
+class DropProjectIdColumnFromMeasures < ActiveRecord::Migration
+
+ def self.up
+ execute_java_migration('org.sonar.db.version.v60.DropProjectIdColumnFromMeasures')
+ end
+end
private String alertStatus;
private String alertText;
private String description;
-
- private Long componentId;
+ private String componentUuid;
private Long snapshotId;
private Integer metricId;
private Long developerId;
return this;
}
+ public String getComponentUuid() {
+ return componentUuid;
+ }
+
+ public MeasureDto setComponentUuid(String s) {
+ this.componentUuid = s;
+ return this;
+ }
+
@CheckForNull
public String getData() {
if (dataValue != null) {
return this;
}
- public Long getComponentId() {
- return componentId;
- }
-
- public MeasureDto setComponentId(Long componentId) {
- this.componentId = componentId;
- return this;
- }
-
public Integer getMetricId() {
return metricId;
}
.add("alertStatus", alertStatus)
.add("alertText", alertText)
.add("description", description)
- .add("componentId", componentId)
+ .add("componentUuid", componentUuid)
.add("snapshotId", snapshotId)
.add("metricId", metricId)
.add("developerId", developerId)
public class DatabaseVersion {
- public static final int LAST_VERSION = 1_213;
+ public static final int LAST_VERSION = 1_218;
/**
* The minimum supported version which can be upgraded. Lower
import org.sonar.db.version.v55.FeedRulesTypes;
import org.sonar.db.version.v56.FixLengthOfIssuesMessageOnOracle;
import org.sonar.db.version.v56.FixTypeOfRuleTypeOnMysql;
+import org.sonar.db.version.v60.AddComponentUuidColumnToMeasures;
import org.sonar.db.version.v60.AddUuidColumnsToResourceIndex;
import org.sonar.db.version.v60.AddUuidColumnsToSnapshots;
import org.sonar.db.version.v60.CleanOrphanRowsInResourceIndex;
import org.sonar.db.version.v60.CleanOrphanRowsInSnapshots;
+import org.sonar.db.version.v60.DeleteOrphanMeasuresWithoutComponent;
import org.sonar.db.version.v60.DropIdColumnsFromResourceIndex;
import org.sonar.db.version.v60.DropUnusedMeasuresColumns;
import org.sonar.db.version.v60.DropIdColumnsFromSnapshots;
+import org.sonar.db.version.v60.DropProjectIdColumnFromMeasures;
+import org.sonar.db.version.v60.MakeComponentUuidNotNullOnMeasures;
import org.sonar.db.version.v60.MakeUuidColumnsNotNullOnResourceIndex;
import org.sonar.db.version.v60.MakeUuidColumnsNotNullOnSnapshots;
+import org.sonar.db.version.v60.PopulateComponentUuidOfMeasures;
import org.sonar.db.version.v60.PopulateUuidColumnsOfResourceIndex;
import org.sonar.db.version.v60.PopulateUuidColumnsOfSnapshots;
PopulateUuidColumnsOfSnapshots.class,
CleanOrphanRowsInSnapshots.class,
MakeUuidColumnsNotNullOnSnapshots.class,
- DropIdColumnsFromSnapshots.class);
+ DropIdColumnsFromSnapshots.class,
+ AddComponentUuidColumnToMeasures.class,
+ PopulateComponentUuidOfMeasures.class,
+ DeleteOrphanMeasuresWithoutComponent.class,
+ MakeComponentUuidNotNullOnMeasures.class,
+ DropProjectIdColumnFromMeasures.class);
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.version.v60;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.db.version.DdlChange;
+
+import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public class AddComponentUuidColumnToMeasures extends DdlChange {
+
+ private static final String TABLE_MEASURES = "project_measures";
+
+ public AddComponentUuidColumnToMeasures(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(new AddColumnsBuilder(getDatabase().getDialect(), TABLE_MEASURES)
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("component_uuid").setLimit(UUID_VARCHAR_SIZE).setIsNullable(true).build())
+ .build());
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.version.v60;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.version.BaseDataChange;
+import org.sonar.db.version.MassUpdate;
+
+public class DeleteOrphanMeasuresWithoutComponent extends BaseDataChange {
+
+ public DeleteOrphanMeasuresWithoutComponent(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ MassUpdate massUpdate = context.prepareMassUpdate();
+ massUpdate.select("SELECT id from project_measures where component_uuid is null");
+ massUpdate.update("DELETE from project_measures WHERE id=?");
+ massUpdate.rowPluralName("measures");
+ massUpdate.execute((row, update) -> {
+ update.setLong(1, row.getLong(1));
+ return true;
+ });
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.version.v60;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.version.DdlChange;
+import org.sonar.db.version.DropColumnsBuilder;
+
+public class DropProjectIdColumnFromMeasures extends DdlChange {
+
+ private static final String TABLE_MEASURES = "project_measures";
+
+ public DropProjectIdColumnFromMeasures(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(
+ new DropColumnsBuilder(getDatabase().getDialect(), TABLE_MEASURES, "project_id").build());
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.version.v60;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.version.AlterColumnsBuilder;
+import org.sonar.db.version.DdlChange;
+
+import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public class MakeComponentUuidNotNullOnMeasures extends DdlChange {
+
+ private static final String TABLE_MEASURES = "project_measures";
+
+ public MakeComponentUuidNotNullOnMeasures(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(new AlterColumnsBuilder(getDatabase().getDialect(), TABLE_MEASURES)
+ .updateColumn(newVarcharColumnDefBuilder().setColumnName("component_uuid").setLimit(UUID_VARCHAR_SIZE).setIsNullable(false).build())
+ .build());
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.version.v60;
+
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+import org.sonar.db.Database;
+import org.sonar.db.version.BaseDataChange;
+import org.sonar.db.version.MassUpdate;
+import org.sonar.db.version.Select;
+import org.sonar.db.version.SqlStatement;
+
+public class PopulateComponentUuidOfMeasures extends BaseDataChange {
+
+ public PopulateComponentUuidOfMeasures(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ Map<Long, String> componentUuidById = buildComponentUuidMap(context);
+ if (componentUuidById.isEmpty()) {
+ return;
+ }
+
+ populateUuidColumns(context, componentUuidById);
+ }
+
+ private Map<Long, String> buildComponentUuidMap(Context context) throws SQLException {
+ Map<Long, String> componentUuidById = new HashMap<>();
+ context.prepareSelect("select distinct p.id, p.uuid from projects p" +
+ " join project_measures pm on pm.project_id = p.id and pm.component_uuid is null")
+ .scroll(row -> componentUuidById.put(row.getLong(1), row.getString(2)));
+ return componentUuidById;
+ }
+
+ private void populateUuidColumns(Context context, Map<Long, String> componentUuidById) throws SQLException {
+ MassUpdate massUpdate = context.prepareMassUpdate();
+ massUpdate.select("SELECT pm.id, pm.project_id from project_measures pm where pm.component_uuid is null");
+ massUpdate.update("UPDATE project_measures SET component_uuid=? WHERE id=?");
+ massUpdate.rowPluralName("measures");
+ massUpdate.execute((row, update) -> this.handle(componentUuidById, row, update));
+ }
+
+ public boolean handle(Map<Long, String> componentUuidById, Select.Row row, SqlStatement update) throws SQLException {
+ long id = row.getLong(1);
+ long componentId = row.getLong(2);
+
+ String componentUuid = componentUuidById.get(componentId);
+
+ if (componentUuid == null) {
+ return false;
+ }
+
+ update.setString(1, componentUuid);
+ update.setLong(2, id);
+
+ return true;
+ }
+
+}
pm.id,
pm.metric_id as metricId,
pm.person_id as developerId,
+ pm.component_uuid as componentUuid,
pm.snapshot_id as snapshotId,
pm.value as value,
pm.text_value as textValue,
<include refid="extendedMeasureColumns"/>
FROM project_measures pm
INNER JOIN snapshots s ON s.id=pm.snapshot_id AND s.islast=${_true}
- INNER JOIN projects p ON p.uuid=s.component_uuid AND p.enabled=${_true}
+ INNER JOIN projects p ON p.uuid=pm.component_uuid AND p.enabled=${_true}
INNER JOIN metrics metric ON metric.id=pm.metric_id
<where>
AND p.kee = #{componentKey}
<include refid="extendedMeasureColumns"/>
FROM project_measures pm
INNER JOIN snapshots s ON s.id=pm.snapshot_id AND s.islast=${_true}
- INNER JOIN projects p ON p.uuid=s.component_uuid AND p.enabled=${_true}
+ INNER JOIN projects p ON p.uuid=pm.component_uuid AND p.enabled=${_true}
INNER JOIN metrics metric ON metric.id=pm.metric_id
<where>
AND p.kee = #{componentKey}
INNER JOIN snapshots s ON s.id=pm.snapshot_id AND s.islast=${_true}
INNER JOIN metrics metric ON metric.id=pm.metric_id
INNER JOIN projects p ON p.uuid=s.component_uuid AND p.enabled=${_true}
- <where>
- AND p.kee = #{componentKey}
+ WHERE
+ p.kee = #{componentKey}
AND metric.name = #{metricKey}
AND pm.person_id IS NULL
- </where>
</select>
<select id="selectByComponentUuidAndProjectSnapshotIdAndStatusAndMetricIds" parameterType="map"
FROM project_measures pm
INNER JOIN snapshots s ON s.id=pm.snapshot_id AND s.status=#{status}
INNER JOIN projects p ON p.uuid=s.component_uuid AND p.enabled=${_true}
- <where>
- AND p.uuid = #{componentUuid}
+ WHERE
+ <!-- do not filter on pm.component_uuid in order to benefit from index on p.uuid -->
+ p.uuid=#{componentUuid}
AND (s.root_snapshot_id=#{rootSnapshotId} OR s.id=#{rootSnapshotId})
AND
<foreach item="metricId" index="index" collection="metricIds" open="(" separator=" or " close=")">
pm.metric_id=#{metricId}
</foreach>
AND pm.person_id IS NULL
- </where>
</select>
<insert id="insert" parameterType="Measure" useGeneratedKeys="false">
INSERT INTO project_measures (
- value, metric_id, snapshot_id, text_value, project_id, alert_status, alert_text, description,
+ value, metric_id, component_uuid, snapshot_id, text_value, alert_status, alert_text, description,
person_id, variation_value_1, variation_value_2, variation_value_3, variation_value_4,
variation_value_5, measure_data)
VALUES (
- #{value, jdbcType=DOUBLE}, #{metricId, jdbcType=INTEGER}, #{snapshotId, jdbcType=INTEGER},
+ #{value, jdbcType=DOUBLE}, #{metricId, jdbcType=INTEGER}, #{componentUuid, jdbcType=VARCHAR},
+ #{snapshotId, jdbcType=INTEGER},
#{textValue, jdbcType=VARCHAR},
- #{componentId, jdbcType=INTEGER}, #{alertStatus, jdbcType=VARCHAR}, #{alertText, jdbcType=VARCHAR},
+ #{alertStatus, jdbcType=VARCHAR}, #{alertText, jdbcType=VARCHAR},
#{description, jdbcType=VARCHAR},
#{developerId, jdbcType=INTEGER}, #{variation1, jdbcType=DOUBLE}, #{variation2, jdbcType=DOUBLE},
#{variation3, jdbcType=DOUBLE},
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1211');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1212');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1213');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1214');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1215');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1216');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1217');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1218');
INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, EXTERNAL_IDENTITY, EXTERNAL_IDENTITY_PROVIDER, USER_LOCAL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'admin', 'sonarqube', true, 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '1418215735482', '1418215735482', null, null);
ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2;
"ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
"VALUE" DOUBLE,
"METRIC_ID" INTEGER NOT NULL,
+ "COMPONENT_UUID" VARCHAR(50) NOT NULL,
"SNAPSHOT_ID" INTEGER,
"TEXT_VALUE" VARCHAR(4000),
- "PROJECT_ID" INTEGER,
"ALERT_STATUS" VARCHAR(5),
"ALERT_TEXT" VARCHAR(4000),
"DESCRIPTION" VARCHAR(4000),
ComponentDto projectDto = insertProject("aa");
SnapshotDto snapshotDto = insertSnapshot(projectDto, true);
- insertMeasure(snapshotDto, DEVELOPER_ID, NCLOC_METRIC_ID, 12d);
+ insertMeasure(projectDto, snapshotDto, DEVELOPER_ID, NCLOC_METRIC_ID, 12d);
List<MeasureDto> measureDtos = underTest.selectProjectMeasuresByDeveloperForMetrics(dbSession, DEVELOPER_ID, ImmutableList.of(NCLOC_METRIC_ID));
assertThat(measureDtos).hasSize(1);
assertThat(measureDto.getId()).isNotNull();
assertThat(measureDto.getMetricId()).isEqualTo(NCLOC_METRIC_ID);
assertThat(measureDto.getSnapshotId()).isEqualTo(snapshotDto.getId());
- assertThat(measureDto.getComponentId()).isEqualTo(projectDto.getId());
+ assertThat(measureDto.getComponentUuid()).isEqualTo(projectDto.uuid());
assertThat(measureDto.getDeveloperId()).isEqualTo(DEVELOPER_ID);
assertThat(underTest.selectProjectMeasuresByDeveloperForMetrics(dbSession, otherDeveloperId, ImmutableList.of(NCLOC_METRIC_ID))).isEmpty();
ComponentDto projectDto = insertProject("aa");
SnapshotDto nonLastSnapshotDto = insertSnapshot(projectDto, false);
- insertMeasure(nonLastSnapshotDto, DEVELOPER_ID, NCLOC_METRIC_ID, 12d);
+ insertMeasure(projectDto, nonLastSnapshotDto, DEVELOPER_ID, NCLOC_METRIC_ID, 12d);
SnapshotDto lastSnapshotDto = insertSnapshot(projectDto, true);
- insertMeasure(lastSnapshotDto, otherDeveloperId, NCLOC_METRIC_ID, 15d);
+ insertMeasure(projectDto, lastSnapshotDto, otherDeveloperId, NCLOC_METRIC_ID, 15d);
assertThat(underTest.selectProjectMeasuresByDeveloperForMetrics(dbSession, DEVELOPER_ID, ImmutableList.of(NCLOC_METRIC_ID))).hasSize(0);
MeasureDto measureDto = measureDtos.iterator().next();
assertThat(measureDto.getMetricId()).isEqualTo(NCLOC_METRIC_ID);
assertThat(measureDto.getSnapshotId()).isEqualTo(lastSnapshotDto.getId());
- assertThat(measureDto.getComponentId()).isEqualTo(projectDto.getId());
+ assertThat(measureDto.getComponentUuid()).isEqualTo(projectDto.uuid());
assertThat(measureDto.getDeveloperId()).isEqualTo(otherDeveloperId);
assertThat(measureDto.getValue()).isEqualTo(15d);
}
ComponentDto projectDto = insertProject("aa");
insertSnapshot(projectDto, true);
ComponentDto moduleDto = insertComponent(ComponentTesting.newModuleDto(projectDto));
- insertMeasure(insertSnapshot(moduleDto, true), DEVELOPER_ID, NCLOC_METRIC_ID, 15d);
+ insertMeasure(moduleDto, insertSnapshot(moduleDto, true), DEVELOPER_ID, NCLOC_METRIC_ID, 15d);
ComponentDto dirDto = insertComponent(ComponentTesting.newDirectory(moduleDto, "toto"));
- insertMeasure(insertSnapshot(dirDto, true), DEVELOPER_ID, NCLOC_METRIC_ID, 25d);
+ insertMeasure(dirDto, insertSnapshot(dirDto, true), DEVELOPER_ID, NCLOC_METRIC_ID, 25d);
ComponentDto fileDto = insertComponent(ComponentTesting.newFileDto(moduleDto, "tutu"));
- insertMeasure(insertSnapshot(fileDto, true), DEVELOPER_ID, NCLOC_METRIC_ID, 35d);
+ insertMeasure(fileDto, insertSnapshot(fileDto, true), DEVELOPER_ID, NCLOC_METRIC_ID, 35d);
assertThat(underTest.selectProjectMeasuresByDeveloperForMetrics(dbSession, DEVELOPER_ID, ImmutableList.of(NCLOC_METRIC_ID))).isEmpty();
}
return snapshotDto;
}
- private MeasureDto insertMeasure(SnapshotDto snapshotDto, Long developerId, int metricId, double value) {
- MeasureDto measureDto = new MeasureDto().setMetricId(metricId).setValue(value).setSnapshotId(snapshotDto.getId()).setDeveloperId(developerId);
+ private MeasureDto insertMeasure(ComponentDto componentDto, SnapshotDto snapshotDto, Long developerId, int metricId, double value) {
+ MeasureDto measureDto = new MeasureDto()
+ .setMetricId(metricId)
+ .setValue(value)
+ .setComponentUuid(componentDto.uuid())
+ .setSnapshotId(snapshotDto.getId())
+ .setDeveloperId(developerId);
dbClient.measureDao().insert(dbSession, measureDto);
dbSession.commit();
return measureDto;
.setSnapshotId(2L)
.setMetricId(3)
.setDeveloperId(23L)
- .setRuleId(5)
- .setComponentId(6L)
+ .setComponentUuid("FILE1")
.setValue(2.0d)
.setData("measure-value")
.setVariation(1, 1.0d)
underTest.insert(dbSession, new MeasureDto()
.setSnapshotId(2L)
.setMetricId(3)
- .setComponentId(6L)
+ .setComponentUuid("COMPONENT_1")
.setValue(2.0d),
new MeasureDto()
.setSnapshotId(3L)
.setMetricId(4)
- .setComponentId(6L)
+ .setComponentUuid("COMPONENT_2")
.setValue(4.0d));
dbSession.commit();
*/
package org.sonar.db.measure;
+import org.apache.commons.lang.RandomStringUtils;
+import org.sonar.core.util.Uuids;
import org.sonar.db.metric.MetricDto;
-import static org.apache.commons.lang.math.RandomUtils.nextInt;
-
public class MeasureTesting {
private MeasureTesting() {
// static methods only
return new MeasureDto()
.setMetricId(metricDto.getId())
.setMetricKey(metricDto.getKey())
- .setComponentId((long) nextInt())
+ .setComponentUuid(RandomStringUtils.randomAlphanumeric(Uuids.MAX_LENGTH))
.setSnapshotId(snapshotId);
}
}
public void verify_count_of_added_MigrationStep_types() {
ComponentContainer container = new ComponentContainer();
new MigrationStepModule().configure(container);
- assertThat(container.size()).isEqualTo(76);
+ assertThat(container.size()).isEqualTo(81);
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.version.v60;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+
+import static java.lang.String.valueOf;
+
+public class AddComponentUuidColumnToMeasuresTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, AddComponentUuidColumnToMeasuresTest.class, "project_measures_5.6.sql");
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private AddComponentUuidColumnToMeasures underTest = new AddComponentUuidColumnToMeasures(db.database());
+
+ @Test
+ public void migration_adds_column_to_empty_table() throws SQLException {
+ underTest.execute();
+
+ verifyAddedColumns();
+ }
+
+ @Test
+ public void migration_adds_column_to_populated_table() throws SQLException {
+ for (int i = 0; i < 9; i++) {
+ db.executeInsert(
+ "project_measures",
+ "METRIC_ID", valueOf(i),
+ "VALUE", valueOf(i),
+ "SNAPSHOT_ID", valueOf(i));
+ }
+ db.commit();
+
+ underTest.execute();
+
+ verifyAddedColumns();
+ }
+
+ @Test
+ public void migration_is_not_reentrant() throws SQLException {
+ underTest.execute();
+
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Fail to execute ");
+ underTest.execute();
+ }
+
+ private void verifyAddedColumns() {
+ db.assertColumnDefinition("project_measures", "component_uuid", Types.VARCHAR, 50, true);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.version.v60;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+
+import static java.lang.String.valueOf;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class DeleteOrphanMeasuresWithoutComponentTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, DeleteOrphanMeasuresWithoutComponentTest.class,
+ "in_progress_project_measures.sql");
+
+ private DeleteOrphanMeasuresWithoutComponent underTest = new DeleteOrphanMeasuresWithoutComponent(db.database());
+
+ @Test
+ public void migration_has_no_effects_on_empty_table() throws SQLException {
+ underTest.execute();
+
+ assertThat(db.countRowsOfTable("project_measures")).isEqualTo(0);
+ }
+
+ @Test
+ public void migration_deletes_any_row_with_a_null_component_uuid() throws SQLException {
+ insertMeasure(1, true);
+ insertMeasure(2, false);
+ insertMeasure(3, false);
+ insertMeasure(4, true);
+ db.commit();
+
+ underTest.execute();
+
+ assertThat(idsOfRowsInMeasures()).containsOnly(1L, 4L);
+ }
+
+ @Test
+ public void migration_is_reentrant() throws SQLException {
+ insertMeasure(1, true);
+ insertMeasure(2, false);
+
+ underTest.execute();
+
+ assertThat(idsOfRowsInMeasures()).containsOnly(1L);
+
+ underTest.execute();
+
+ assertThat(idsOfRowsInMeasures()).containsOnly(1L);
+ }
+
+ private List<Long> idsOfRowsInMeasures() {
+ return db.select("select ID from project_measures").stream().map(map -> (Long) map.get("ID")).collect(Collectors.toList());
+ }
+
+ private void insertMeasure(long id, boolean hasComponentUuid) {
+ db.executeInsert(
+ "project_measures",
+ "ID", valueOf(id),
+ "METRIC_ID", valueOf(id + 10),
+ "SNAPSHOT_ID", valueOf(id + 100),
+ "VALUE", valueOf(id + 1000));
+
+ if (hasComponentUuid) {
+ db.executeUpdateSql("update project_measures set COMPONENT_UUID=? where id=?", "uuid_" + id, valueOf(id));
+ }
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.version.v60;
+
+import java.sql.SQLException;
+import org.junit.Test;
+import org.sonar.db.Database;
+import org.sonar.db.dialect.PostgreSql;
+import org.sonar.db.version.DdlChange;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class DropProjectIdColumnFromMeasuresTest {
+ private Database database = mock(Database.class);
+
+ private DropProjectIdColumnFromMeasures underTest = new DropProjectIdColumnFromMeasures(database);
+
+ @Test
+ public void verify_generated_sql_on_postgresql() throws SQLException {
+ when(database.getDialect()).thenReturn(new PostgreSql());
+
+ DdlChange.Context context = mock(DdlChange.Context.class);
+ underTest.execute(context);
+
+ verify(context).execute("ALTER TABLE project_measures DROP COLUMN project_id");
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.version.v60;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+
+import static java.lang.String.valueOf;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class MakeComponentUuidNotNullOnMeasuresTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, MakeComponentUuidNotNullOnMeasuresTest.class,
+ "in_progress_project_measures.sql");
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private MakeComponentUuidNotNullOnMeasures underTest = new MakeComponentUuidNotNullOnMeasures(db.database());
+
+ @Test
+ public void migration_sets_uuid_columns_not_nullable_on_empty_table() throws SQLException {
+ underTest.execute();
+
+ verifyColumnDefinitions();
+ }
+
+ @Test
+ public void migration_sets_uuid_columns_not_nullable_on_populated_table() throws SQLException {
+ insertMeasure(1L, true);
+ insertMeasure(2L, true);
+
+ underTest.execute();
+
+ verifyColumnDefinitions();
+ assertThat(idsOfRowsInMeasures()).containsOnly(1L, 2L);
+ }
+
+ @Test
+ public void migration_fails_if_some_uuid_columns_are_null() throws SQLException {
+ insertMeasure(1L, false);
+
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Fail to execute");
+
+ underTest.execute();
+ }
+
+ private void verifyColumnDefinitions() {
+ db.assertColumnDefinition("project_measures", "component_uuid", Types.VARCHAR, 50, false);
+ }
+
+ private List<Long> idsOfRowsInMeasures() {
+ return db.select("select ID from project_measures").stream().map(map -> (Long) map.get("ID")).collect(Collectors.toList());
+ }
+
+ private void insertMeasure(long id, boolean hasComponentUuid) {
+ db.executeInsert(
+ "project_measures",
+ "ID", valueOf(id),
+ "METRIC_ID", valueOf(id + 10),
+ "SNAPSHOT_ID", valueOf(id + 100),
+ "VALUE", valueOf(id + 1000));
+
+ if (hasComponentUuid) {
+ db.executeUpdateSql("update project_measures set COMPONENT_UUID=? where id=?", "uuid_" + id, valueOf(id));
+ }
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.version.v60;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Nullable;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+
+import static java.lang.String.valueOf;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class PopulateComponentUuidOfMeasuresTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, PopulateComponentUuidOfMeasuresTest.class,
+ "in_progress_measures_with_projects.sql");
+
+ private PopulateComponentUuidOfMeasures underTest = new PopulateComponentUuidOfMeasures(db.database());
+
+ @Test
+ public void migration_has_no_effect_on_empty_tables() throws SQLException {
+ underTest.execute();
+
+ assertThat(db.countRowsOfTable("project_measures")).isEqualTo(0);
+ assertThat(db.countRowsOfTable("projects")).isEqualTo(0);
+ }
+
+ @Test
+ public void migration_updates_component_uuid_with_values_from_table_projects_when_they_exist() throws SQLException {
+ String uuid1 = insertComponent(40);
+ String uuid2 = insertComponent(50);
+ String uuid3 = insertComponent(60);
+ String uuid4 = insertComponent(70);
+
+ insertMeasure(1, 40);
+ insertMeasure(2, 60);
+ insertMeasure(3, 90); // 90 does not exist
+ insertMeasure(4, 100); // 100 does not exist
+ db.commit();
+
+ underTest.execute();
+
+ verifyMeasure(1, 40, uuid1);
+ verifyMeasure(2, 60, uuid3);
+ verifyMeasure(3, 90, null);
+ verifyMeasure(4, 100, null);
+ }
+
+ @Test
+ public void migration_is_reentrant() throws SQLException {
+ String uuid1 = insertComponent(40);
+ String uuid2 = insertComponent(50);
+ insertMeasure(1, 40);
+
+ underTest.execute();
+ verifyMeasure(1, 40, uuid1);
+
+ underTest.execute();
+ verifyMeasure(1, 40, uuid1);
+
+ }
+
+ private void verifyMeasure(long id, long componentId, @Nullable String componentUuid) {
+ List<Map<String, Object>> rows = db.select("select PROJECT_ID, COMPONENT_UUID from project_measures where ID=" + id);
+ assertThat(rows).hasSize(1);
+ Map<String, Object> row = rows.get(0);
+ assertThat(row.get("PROJECT_ID")).isEqualTo(componentId);
+ assertThat(row.get("COMPONENT_UUID")).isEqualTo(componentUuid);
+ }
+
+ private String insertComponent(long id) {
+ String uuid = "uuid_" + id;
+ db.executeInsert(
+ "projects",
+ "ID", valueOf(id),
+ "UUID", uuid);
+ return uuid;
+ }
+
+ private void insertMeasure(long id, long componentId) {
+ db.executeInsert(
+ "project_measures",
+ "ID", valueOf(id),
+ "METRIC_ID", valueOf(id + 10),
+ "SNAPSHOT_ID", valueOf(id + 100),
+ "VALUE", valueOf(id + 1000),
+ "PROJECT_ID", valueOf(componentId));
+
+ }
+}
id="1"
snapshot_id="2"
metric_id="3"
- project_id="6"
+ component_uuid="FILE1"
person_id="23"
value="2.0"
text_value="measure-value"
<!-- project measures -->
- <project_measures id="1" VALUE="60" METRIC_ID="1" SNAPSHOT_ID="1000" person_id="[null]"/>
+ <project_measures id="1" VALUE="60" METRIC_ID="1" SNAPSHOT_ID="1000" person_id="[null]" component_uuid="ABCD"/>
- <project_measures id="2" VALUE="80" METRIC_ID="2" SNAPSHOT_ID="1000" person_id="[null]"/>
+ <project_measures id="2" VALUE="80" METRIC_ID="2" SNAPSHOT_ID="1000" person_id="[null]" component_uuid="ABCD"/>
<!-- package measures -->
- <project_measures id="3" VALUE="20" METRIC_ID="1" SNAPSHOT_ID="1001" person_id="[null]"/>
+ <project_measures id="3" VALUE="20" METRIC_ID="1" SNAPSHOT_ID="1001" person_id="[null]" component_uuid="BCDE"/>
- <project_measures id="4" VALUE="70" METRIC_ID="2" SNAPSHOT_ID="1001" person_id="[null]"/>
+ <project_measures id="4" VALUE="70" METRIC_ID="2" SNAPSHOT_ID="1001" person_id="[null]" component_uuid="BCDE"/>
<!-- file measures -->
- <project_measures id="5" VALUE="5" METRIC_ID="1" SNAPSHOT_ID="1002" person_id="[null]"/>
+ <project_measures id="5" VALUE="5" METRIC_ID="1" SNAPSHOT_ID="1002" person_id="[null]" component_uuid="CDEF"/>
- <project_measures id="6" VALUE="60" METRIC_ID="2" SNAPSHOT_ID="1002" person_id="[null]"/>
+ <project_measures id="6" VALUE="60" METRIC_ID="2" SNAPSHOT_ID="1002" person_id="[null]" component_uuid="CDEF"/>
</dataset>
status="P" islast="[false]" depth="0"/>
<!-- project measures -->
- <project_measures id="1" VALUE="60" METRIC_ID="1" SNAPSHOT_ID="1000" person_id="[null]"/>
+ <project_measures id="1" VALUE="60" METRIC_ID="1" SNAPSHOT_ID="1000" person_id="[null]" component_uuid="ABCD"/>
- <project_measures id="2" VALUE="20" METRIC_ID="1" SNAPSHOT_ID="1000" person_id="20"/>
+ <project_measures id="2" VALUE="20" METRIC_ID="1" SNAPSHOT_ID="1000" person_id="20" component_uuid="ABCD"/>
- <project_measures id="3" VALUE="40" METRIC_ID="1" SNAPSHOT_ID="1000" person_id="21"/>
+ <project_measures id="3" VALUE="40" METRIC_ID="1" SNAPSHOT_ID="1000" person_id="21" component_uuid="ABCD"/>
</dataset>
<metrics id="11" name="coverage_line_hits_data"/>
<metrics id="12" name="ncloc"/>
- <projects id="1" kee="org.struts:struts-core:src/org/struts/RequestContext.java" enabled="[true]" uuid="ABCD"/>
+ <projects id="1" kee="org.struts:struts-core:src/org/struts/RequestContext.java" enabled="[true]" uuid="FILE1"/>
<snapshots id="5" component_uuid="ABCD" root_component_uuid="ABCD" islast="[true]" />
<project_measures id="20" snapshot_id="5" metric_id="10" value="[null]" text_value="0123456789012345678901234567890123456789" measure_data="[null]"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
- alert_status="[null]" alert_text="[null]" />
+ alert_status="[null]" alert_text="[null]" component_uuid="FILE1"/>
<project_measures id="21" snapshot_id="5" metric_id="11" value="[null]" text_value="36=1;37=1;38=1;39=1;43=1;48=1;53=1" measure_data="[null]"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
- alert_status="[null]" alert_text="[null]" />
+ alert_status="[null]" alert_text="[null]" component_uuid="FILE1"/>
<project_measures id="22" snapshot_id="5" metric_id="12" value="10" text_value="[null]" measure_data="[null]"
variation_value_1="1" variation_value_2="2" variation_value_3="3" variation_value_4="4" variation_value_5="-5"
- alert_status="OK" alert_text="Green"/>
+ alert_status="OK" alert_text="Green" component_uuid="FILE1"/>
</dataset>
<snapshots id="5" component_uuid="ABCD" root_component_uuid="ABCD" islast="[true]" />
- <project_measures id="20" snapshot_id="5" metric_id="10" value="[null]" text_value="0123456789012345678901234567890123456789" measure_data="[null]"
+ <project_measures id="20"
+ component_uuid="ABCD"
+ snapshot_id="5"
+ metric_id="10" value="[null]" text_value="0123456789012345678901234567890123456789" measure_data="[null]"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
alert_status="[null]" alert_text="[null]" />
- <project_measures id="21" snapshot_id="5" metric_id="11" value="[null]" text_value="36=1;37=1;38=1;39=1;43=1;48=1;53=1" measure_data="[null]"
+ <project_measures id="21"
+ component_uuid="ABCD"
+ snapshot_id="5"
+ metric_id="11" value="[null]" text_value="36=1;37=1;38=1;39=1;43=1;48=1;53=1" measure_data="[null]"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
alert_status="[null]" alert_text="[null]" />
- <project_measures id="22" snapshot_id="5" metric_id="12" value="10" text_value="[null]" measure_data="[null]"
+ <project_measures id="22"
+ component_uuid="ABCD"
+ snapshot_id="5"
+ metric_id="12" value="10" text_value="[null]" measure_data="[null]"
variation_value_1="1" variation_value_2="2" variation_value_3="3" variation_value_4="4" variation_value_5="-5"
alert_status="OK" alert_text="Green"/>
<project_measures id="20" snapshot_id="5" metric_id="10" value="[null]" text_value="0123456789012345678901234567890123456789" measure_data="[null]"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
alert_status="[null]" alert_text="[null]"
- person_id="[null]"/>
+ person_id="[null]" component_uuid="1"/>
<project_measures id="21" snapshot_id="5" metric_id="11" value="[null]" text_value="36=1;37=1;38=1;39=1;43=1;48=1;53=1" measure_data="[null]"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
alert_status="[null]" alert_text="[null]"
- person_id="[null]"/>
+ person_id="[null]" component_uuid="1"/>
<project_measures id="22" snapshot_id="5" metric_id="12" value="10" text_value="[null]" measure_data="[null]"
variation_value_1="1" variation_value_2="2" variation_value_3="3" variation_value_4="4" variation_value_5="-5"
alert_status="OK" alert_text="Green"
- person_id="[null]"/>
+ person_id="[null]" component_uuid="1"/>
<!--measures for developer 333-->
<project_measures id="30" snapshot_id="5" metric_id="10" value="[null]" text_value="0123456789012345678901234567890123456789" measure_data="[null]"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
alert_status="[null]" alert_text="[null]"
- person_id="333"/>
+ person_id="333" component_uuid="1"/>
<project_measures id="31" snapshot_id="5" metric_id="11" value="[null]" text_value="36=1;37=1;38=1;39=1;43=1;48=1;53=1" measure_data="[null]"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"
alert_status="[null]" alert_text="[null]"
- person_id="333"/>
+ person_id="333" component_uuid="1"/>
<project_measures id="32" snapshot_id="5" metric_id="12" value="10" text_value="[null]" measure_data="[null]"
variation_value_1="1" variation_value_2="2" variation_value_3="3" variation_value_4="4" variation_value_5="-5"
alert_status="OK" alert_text="Green"
- person_id="333"/>
+ person_id="333" component_uuid="1"/>
</dataset>
variation_value_5="[null]"
alert_text="[null]" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1"
person_id="[null]"
- text_value="[null]" project_id="[null]"
+ text_value="[null]"
+ component_uuid="1"
alert_status="[null]" description="[null]" measure_data="[null]"/>
<events id="1" name="Version 1.0" component_uuid="1" snapshot_id="1" category="VERSION" description="[null]"
event_date="1228222680000" created_at="1228222680000" event_data="[null]"/>
variation_value_5="[null]"
alert_text="[null]" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1"
person_id="[null]"
- text_value="[null]" project_id="[null]"
+ text_value="[null]"
+ component_uuid="1"
alert_status="[null]" description="[null]" measure_data="[null]"/>
<events id="1" name="Version 1.0" component_uuid="1" snapshot_id="1" category="VERSION" description="[null]"
event_date="1228222680000" created_at="1228222680000" event_data="[null]"/>
variation_value_5="[null]"
alert_text="[null]" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="5"
person_id="[null]"
- text_value="[null]" project_id="[null]"
+ text_value="[null]"
+ component_uuid="5"
alert_status="[null]" description="[null]" measure_data="[null]"/>
<events id="2" name="Version 1.0" component_uuid="5" snapshot_id="5" category="VERSION" description="[null]"
event_date="1228222680000" created_at="1228222680000" event_data="[null]"/>
build_date="1228222680000" version="[null]" path="[null]"/>
<!-- do not delete standard measure -->
- <project_measures id="1" project_id="1" snapshot_id="1" metric_id="1"
+ <project_measures id="1"
+ snapshot_id="1"
+ metric_id="1"
+ component_uuid="1"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]"
variation_value_5="[null]" alert_text="[null]" value="10.0"
build_date="1228222680000" version="[null]" path="[null]"/>
<!-- do not delete standard measure -->
- <project_measures id="1" project_id="1" snapshot_id="1" metric_id="1"
+ <project_measures id="1"
+ component_uuid="1"
+ snapshot_id="1" metric_id="1"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]"
variation_value_5="[null]" alert_text="[null]" value="10.0"
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" metric_id="2"
+ <project_measures id="6"
+ component_uuid="1"
+ snapshot_id="1" metric_id="2"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]"
variation_value_5="[null]" alert_text="[null]" value="10.0"
description="[null]" measure_data="[null]"/>
<!-- delete measure on developers -->
- <project_measures id="7" project_id="1" snapshot_id="1" metric_id="2"
+ <project_measures id="7"
+ component_uuid="1"
+ snapshot_id="1" metric_id="2"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
person_id="123456"
variation_value_4="[null]"
<!--created_at="2008-12-02 13:58:00.00"-->
<!--checksum="[null]" person_id="[null]"/>-->
- <project_measures ID="1" project_id="1" SNAPSHOT_ID="1"
+ <project_measures ID="1"
+ component_uuid="1"
+ SNAPSHOT_ID="1"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]"
variation_value_5="[null]" alert_text="[null]" VALUE="10.0" METRIC_ID="1"
build_date="1228222680000" version="[null]" path="[null]"/>
- <project_measures ID="2" project_id="2" SNAPSHOT_ID="2"
+ <project_measures ID="2"
+ component_uuid="2"
+ SNAPSHOT_ID="2"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]"
variation_value_5="[null]" alert_text="[null]" VALUE="10.0" METRIC_ID="1"
depth="[null]" scope="PRJ" qualifier="TRK" created_at="1228222680000"
build_date="1228222680000" version="[null]" path="[null]"/>
- <project_measures ID="1" project_id="1" SNAPSHOT_ID="1"
+ <project_measures ID="1"
+ component_uuid="1"
+ SNAPSHOT_ID="1"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]" variation_value_5="[null]" alert_text="[null]"
VALUE="10.0" METRIC_ID="1" person_id="[null]" text_value="[null]"
depth="[null]" scope="PRJ" qualifier="TRK" created_at="1228222680000"
build_date="1228222680000" version="[null]" path="[null]"/>
- <project_measures ID="2" project_id="2" SNAPSHOT_ID="2" characteristic_id="[null]"
+ <project_measures ID="2"
+ component_uuid="2"
+ SNAPSHOT_ID="2" characteristic_id="[null]"
variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
variation_value_4="[null]"
variation_value_5="[null]" alert_text="[null]" VALUE="10.0" METRIC_ID="1"
--- /dev/null
+CREATE TABLE "PROJECT_MEASURES" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "VALUE" DOUBLE,
+ "METRIC_ID" INTEGER NOT NULL,
+ "SNAPSHOT_ID" INTEGER,
+ "RULE_ID" INTEGER,
+ "RULES_CATEGORY_ID" INTEGER,
+ "TEXT_VALUE" VARCHAR(4000),
+ "TENDENCY" INTEGER,
+ "MEASURE_DATE" TIMESTAMP,
+ "PROJECT_ID" INTEGER,
+ "ALERT_STATUS" VARCHAR(5),
+ "ALERT_TEXT" VARCHAR(4000),
+ "URL" VARCHAR(2000),
+ "DESCRIPTION" VARCHAR(4000),
+ "RULE_PRIORITY" INTEGER,
+ "CHARACTERISTIC_ID" INTEGER,
+ "PERSON_ID" INTEGER,
+ "VARIATION_VALUE_1" DOUBLE,
+ "VARIATION_VALUE_2" DOUBLE,
+ "VARIATION_VALUE_3" DOUBLE,
+ "VARIATION_VALUE_4" DOUBLE,
+ "VARIATION_VALUE_5" DOUBLE,
+ "MEASURE_DATA" BINARY(167772150)
+);
+
+CREATE INDEX "MEASURES_SID_METRIC" ON "PROJECT_MEASURES" ("SNAPSHOT_ID", "METRIC_ID");
+
+CREATE INDEX "MEASURES_PERSON" ON "PROJECT_MEASURES" ("PERSON_ID");
--- /dev/null
+CREATE TABLE "PROJECT_MEASURES" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "VALUE" DOUBLE,
+ "METRIC_ID" INTEGER NOT NULL,
+ "SNAPSHOT_ID" INTEGER,
+ "RULE_ID" INTEGER,
+ "RULES_CATEGORY_ID" INTEGER,
+ "TEXT_VALUE" VARCHAR(4000),
+ "TENDENCY" INTEGER,
+ "MEASURE_DATE" TIMESTAMP,
+ "PROJECT_ID" INTEGER,
+ "ALERT_STATUS" VARCHAR(5),
+ "ALERT_TEXT" VARCHAR(4000),
+ "URL" VARCHAR(2000),
+ "DESCRIPTION" VARCHAR(4000),
+ "RULE_PRIORITY" INTEGER,
+ "CHARACTERISTIC_ID" INTEGER,
+ "PERSON_ID" INTEGER,
+ "VARIATION_VALUE_1" DOUBLE,
+ "VARIATION_VALUE_2" DOUBLE,
+ "VARIATION_VALUE_3" DOUBLE,
+ "VARIATION_VALUE_4" DOUBLE,
+ "VARIATION_VALUE_5" DOUBLE,
+ "MEASURE_DATA" BINARY(167772150),
+
+ // new column, introduced in migration 1214
+ "COMPONENT_UUID" VARCHAR(50)
+);
+
+CREATE INDEX "MEASURES_SID_METRIC" ON "PROJECT_MEASURES" ("SNAPSHOT_ID", "METRIC_ID");
+
+CREATE INDEX "MEASURES_PERSON" ON "PROJECT_MEASURES" ("PERSON_ID");
--- /dev/null
+CREATE TABLE "PROJECT_MEASURES" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "VALUE" DOUBLE,
+ "METRIC_ID" INTEGER NOT NULL,
+ "SNAPSHOT_ID" INTEGER,
+ "RULE_ID" INTEGER,
+ "RULES_CATEGORY_ID" INTEGER,
+ "TEXT_VALUE" VARCHAR(4000),
+ "TENDENCY" INTEGER,
+ "MEASURE_DATE" TIMESTAMP,
+ "PROJECT_ID" INTEGER,
+ "ALERT_STATUS" VARCHAR(5),
+ "ALERT_TEXT" VARCHAR(4000),
+ "URL" VARCHAR(2000),
+ "DESCRIPTION" VARCHAR(4000),
+ "RULE_PRIORITY" INTEGER,
+ "CHARACTERISTIC_ID" INTEGER,
+ "PERSON_ID" INTEGER,
+ "VARIATION_VALUE_1" DOUBLE,
+ "VARIATION_VALUE_2" DOUBLE,
+ "VARIATION_VALUE_3" DOUBLE,
+ "VARIATION_VALUE_4" DOUBLE,
+ "VARIATION_VALUE_5" DOUBLE,
+ "MEASURE_DATA" BINARY(167772150),
+
+ // new column, introduced in migration 1214
+ "COMPONENT_UUID" VARCHAR(50)
+);
+
+CREATE INDEX "MEASURES_SID_METRIC" ON "PROJECT_MEASURES" ("SNAPSHOT_ID", "METRIC_ID");
+
+CREATE INDEX "MEASURES_PERSON" ON "PROJECT_MEASURES" ("PERSON_ID");
--- /dev/null
+CREATE TABLE "PROJECT_MEASURES" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "VALUE" DOUBLE,
+ "METRIC_ID" INTEGER NOT NULL,
+ "SNAPSHOT_ID" INTEGER,
+ "RULE_ID" INTEGER,
+ "RULES_CATEGORY_ID" INTEGER,
+ "TEXT_VALUE" VARCHAR(4000),
+ "TENDENCY" INTEGER,
+ "MEASURE_DATE" TIMESTAMP,
+ "PROJECT_ID" INTEGER,
+ "ALERT_STATUS" VARCHAR(5),
+ "ALERT_TEXT" VARCHAR(4000),
+ "URL" VARCHAR(2000),
+ "DESCRIPTION" VARCHAR(4000),
+ "RULE_PRIORITY" INTEGER,
+ "CHARACTERISTIC_ID" INTEGER,
+ "PERSON_ID" INTEGER,
+ "VARIATION_VALUE_1" DOUBLE,
+ "VARIATION_VALUE_2" DOUBLE,
+ "VARIATION_VALUE_3" DOUBLE,
+ "VARIATION_VALUE_4" DOUBLE,
+ "VARIATION_VALUE_5" DOUBLE,
+ "MEASURE_DATA" BINARY(167772150),
+
+ // new column, introduced in migration 1214
+ "COMPONENT_UUID" VARCHAR(50)
+);
+
+CREATE INDEX "MEASURES_SID_METRIC" ON "PROJECT_MEASURES" ("SNAPSHOT_ID", "METRIC_ID");
+
+CREATE INDEX "MEASURES_PERSON" ON "PROJECT_MEASURES" ("PERSON_ID");
+
+CREATE TABLE "PROJECTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(400),
+ "ROOT_ID" INTEGER,
+ "UUID" VARCHAR(50),
+ "PROJECT_UUID" VARCHAR(50),
+ "MODULE_UUID" VARCHAR(50),
+ "MODULE_UUID_PATH" VARCHAR(4000),
+ "NAME" VARCHAR(2000),
+ "DESCRIPTION" VARCHAR(2000),
+ "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE,
+ "SCOPE" VARCHAR(3),
+ "QUALIFIER" VARCHAR(10),
+ "DEPRECATED_KEE" VARCHAR(400),
+ "PATH" VARCHAR(2000),
+ "LANGUAGE" VARCHAR(20),
+ "COPY_RESOURCE_ID" INTEGER,
+ "LONG_NAME" VARCHAR(2000),
+ "PERSON_ID" INTEGER,
+ "CREATED_AT" TIMESTAMP,
+ "AUTHORIZATION_UPDATED_AT" BIGINT
+);