]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5392 Fix issue on Oracle
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 12 Jun 2014 08:03:11 +0000 (10:03 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 12 Jun 2014 08:03:11 +0000 (10:03 +0200)
sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java
sonar-core/src/main/java/org/sonar/core/technicaldebt/db/CharacteristicMapper.java
sonar-core/src/main/java/org/sonar/core/technicaldebt/db/RequirementMigrationDto.java [new file with mode: 0644]
sonar-core/src/main/resources/org/sonar/core/technicaldebt/db/CharacteristicMapper.xml
sonar-server/src/main/java/org/sonar/server/startup/CopyRequirementsFromCharacteristicsToRules.java

index faef9bd177bae3d0b28b3ff3eb0717a319f5edb1..dc840a99b509233c5c76d632dd67b033574ddeb2 100644 (file)
@@ -24,11 +24,7 @@ import com.google.common.io.Closeables;
 import org.apache.ibatis.builder.xml.XMLMapperBuilder;
 import org.apache.ibatis.logging.LogFactory;
 import org.apache.ibatis.mapping.Environment;
-import org.apache.ibatis.session.Configuration;
-import org.apache.ibatis.session.ExecutorType;
-import org.apache.ibatis.session.SqlSession;
-import org.apache.ibatis.session.SqlSessionFactory;
-import org.apache.ibatis.session.SqlSessionFactoryBuilder;
+import org.apache.ibatis.session.*;
 import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
 import org.apache.ibatis.type.JdbcType;
 import org.slf4j.LoggerFactory;
@@ -39,14 +35,7 @@ import org.sonar.core.cluster.WorkQueue;
 import org.sonar.core.component.ComponentDto;
 import org.sonar.core.component.db.ComponentMapper;
 import org.sonar.core.config.Logback;
-import org.sonar.core.dashboard.ActiveDashboardDto;
-import org.sonar.core.dashboard.ActiveDashboardMapper;
-import org.sonar.core.dashboard.DashboardDto;
-import org.sonar.core.dashboard.DashboardMapper;
-import org.sonar.core.dashboard.WidgetDto;
-import org.sonar.core.dashboard.WidgetMapper;
-import org.sonar.core.dashboard.WidgetPropertyDto;
-import org.sonar.core.dashboard.WidgetPropertyMapper;
+import org.sonar.core.dashboard.*;
 import org.sonar.core.dependency.DependencyDto;
 import org.sonar.core.dependency.DependencyMapper;
 import org.sonar.core.dependency.ResourceSnapshotDto;
@@ -55,19 +44,7 @@ import org.sonar.core.duplication.DuplicationMapper;
 import org.sonar.core.duplication.DuplicationUnitDto;
 import org.sonar.core.graph.jdbc.GraphDto;
 import org.sonar.core.graph.jdbc.GraphDtoMapper;
-import org.sonar.core.issue.db.ActionPlanDto;
-import org.sonar.core.issue.db.ActionPlanMapper;
-import org.sonar.core.issue.db.ActionPlanStatsDto;
-import org.sonar.core.issue.db.ActionPlanStatsMapper;
-import org.sonar.core.issue.db.IssueChangeDto;
-import org.sonar.core.issue.db.IssueChangeMapper;
-import org.sonar.core.issue.db.IssueDto;
-import org.sonar.core.issue.db.IssueFilterDto;
-import org.sonar.core.issue.db.IssueFilterFavouriteDto;
-import org.sonar.core.issue.db.IssueFilterFavouriteMapper;
-import org.sonar.core.issue.db.IssueFilterMapper;
-import org.sonar.core.issue.db.IssueMapper;
-import org.sonar.core.issue.db.IssueStatsMapper;
+import org.sonar.core.issue.db.*;
 import org.sonar.core.log.db.LogDto;
 import org.sonar.core.log.db.LogMapper;
 import org.sonar.core.measure.db.MeasureDto;
@@ -76,33 +53,14 @@ import org.sonar.core.measure.db.MeasureFilterMapper;
 import org.sonar.core.measure.db.MeasureMapper;
 import org.sonar.core.notification.db.NotificationQueueDto;
 import org.sonar.core.notification.db.NotificationQueueMapper;
-import org.sonar.core.permission.GroupWithPermissionDto;
-import org.sonar.core.permission.PermissionTemplateDto;
-import org.sonar.core.permission.PermissionTemplateGroupDto;
-import org.sonar.core.permission.PermissionTemplateMapper;
-import org.sonar.core.permission.PermissionTemplateUserDto;
-import org.sonar.core.permission.UserWithPermissionDto;
+import org.sonar.core.permission.*;
 import org.sonar.core.properties.PropertiesMapper;
 import org.sonar.core.properties.PropertyDto;
 import org.sonar.core.purge.PurgeMapper;
 import org.sonar.core.purge.PurgeableSnapshotDto;
-import org.sonar.core.qualitygate.db.ProjectQgateAssociationDto;
-import org.sonar.core.qualitygate.db.ProjectQgateAssociationMapper;
-import org.sonar.core.qualitygate.db.QualityGateConditionDto;
-import org.sonar.core.qualitygate.db.QualityGateConditionMapper;
-import org.sonar.core.qualitygate.db.QualityGateDto;
-import org.sonar.core.qualitygate.db.QualityGateMapper;
-import org.sonar.core.qualityprofile.db.ActiveRuleDto;
-import org.sonar.core.qualityprofile.db.ActiveRuleMapper;
-import org.sonar.core.qualityprofile.db.ActiveRuleParamDto;
-import org.sonar.core.qualityprofile.db.QualityProfileDto;
-import org.sonar.core.qualityprofile.db.QualityProfileMapper;
-import org.sonar.core.resource.ResourceDto;
-import org.sonar.core.resource.ResourceIndexDto;
-import org.sonar.core.resource.ResourceIndexerMapper;
-import org.sonar.core.resource.ResourceKeyUpdaterMapper;
-import org.sonar.core.resource.ResourceMapper;
-import org.sonar.core.resource.SnapshotDto;
+import org.sonar.core.qualitygate.db.*;
+import org.sonar.core.qualityprofile.db.*;
+import org.sonar.core.resource.*;
 import org.sonar.core.rule.RuleDto;
 import org.sonar.core.rule.RuleMapper;
 import org.sonar.core.rule.RuleParamDto;
@@ -111,18 +69,10 @@ import org.sonar.core.source.db.SnapshotDataMapper;
 import org.sonar.core.source.db.SnapshotSourceMapper;
 import org.sonar.core.technicaldebt.db.CharacteristicDto;
 import org.sonar.core.technicaldebt.db.CharacteristicMapper;
+import org.sonar.core.technicaldebt.db.RequirementMigrationDto;
 import org.sonar.core.template.LoadedTemplateDto;
 import org.sonar.core.template.LoadedTemplateMapper;
-import org.sonar.core.user.AuthorDto;
-import org.sonar.core.user.AuthorMapper;
-import org.sonar.core.user.GroupDto;
-import org.sonar.core.user.GroupMembershipDto;
-import org.sonar.core.user.GroupMembershipMapper;
-import org.sonar.core.user.GroupRoleDto;
-import org.sonar.core.user.RoleMapper;
-import org.sonar.core.user.UserDto;
-import org.sonar.core.user.UserMapper;
-import org.sonar.core.user.UserRoleDto;
+import org.sonar.core.user.*;
 
 import java.io.InputStream;
 
@@ -201,6 +151,7 @@ public class MyBatis implements BatchComponent, ServerComponent {
     loadAlias(conf, "QualityProfile", QualityProfileDto.class);
     loadAlias(conf, "ActiveRule", ActiveRuleDto.class);
     loadAlias(conf, "ActiveRuleParam", ActiveRuleParamDto.class);
+    loadAlias(conf, "RequirementMigration", RequirementMigrationDto.class);
     loadAlias(conf, "Log", LogDto.class);
 
     // AuthorizationMapper has to be loaded before IssueMapper because this last one used it
index 123a216a32d0569034bf099605da33f161774a06..ea734f081f8034b0973a701790223f147947a5a5 100644 (file)
@@ -23,7 +23,6 @@ package org.sonar.core.technicaldebt.db;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
-import java.util.Map;
 
 public interface CharacteristicMapper {
 
@@ -51,5 +50,5 @@ public interface CharacteristicMapper {
 
   void deleteRequirementsFromCharacteristicsTable();
 
-  List<Map<String, Object>> selectDeprecatedRequirements();
+  List<RequirementMigrationDto> selectDeprecatedRequirements();
 }
diff --git a/sonar-core/src/main/java/org/sonar/core/technicaldebt/db/RequirementMigrationDto.java b/sonar-core/src/main/java/org/sonar/core/technicaldebt/db/RequirementMigrationDto.java
new file mode 100644 (file)
index 0000000..ac4cb02
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * 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.core.technicaldebt.db;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * Only used in {@link org.sonar.server.startup.CopyRequirementsFromCharacteristicsToRules}
+ */
+public class RequirementMigrationDto implements Serializable {
+
+  private Integer id;
+  private Integer parentId;
+  private Integer rootId;
+  private Integer ruleId;
+  private String functionKey;
+  private Double coefficientValue;
+  private String coefficientUnit;
+  private Double offsetValue;
+  private String offsetUnit;
+  private Date createdAt;
+  private Date updatedAt;
+  private boolean enabled;
+
+  public Integer getId() {
+    return id;
+  }
+
+  public RequirementMigrationDto setId(Integer id) {
+    this.id = id;
+    return this;
+  }
+
+  public Integer getParentId() {
+    return parentId;
+  }
+
+  public RequirementMigrationDto setParentId(Integer i) {
+    this.parentId = i;
+    return this;
+  }
+
+  public Integer getRootId() {
+    return rootId;
+  }
+
+  public RequirementMigrationDto setRootId(Integer rootId) {
+    this.rootId = rootId;
+    return this;
+  }
+
+  public Integer getRuleId() {
+    return ruleId;
+  }
+
+  public RequirementMigrationDto setRuleId(Integer ruleId) {
+    this.ruleId = ruleId;
+    return this;
+  }
+
+  public String getFunction() {
+    return functionKey;
+  }
+
+  public RequirementMigrationDto setFunction(String function) {
+    this.functionKey = function;
+    return this;
+  }
+
+  @CheckForNull
+  public Double getCoefficientValue() {
+    return coefficientValue;
+  }
+
+  public RequirementMigrationDto setCoefficientValue(@Nullable Double coefficientValue) {
+    this.coefficientValue = coefficientValue;
+    return this;
+  }
+
+  @CheckForNull
+  public String getCoefficientUnit() {
+    return coefficientUnit;
+  }
+
+  public RequirementMigrationDto setCoefficientUnit(@Nullable String coefficientUnit) {
+    this.coefficientUnit = coefficientUnit;
+    return this;
+  }
+
+  @CheckForNull
+  public Double getOffsetValue() {
+    return offsetValue;
+  }
+
+  public RequirementMigrationDto setOffsetValue(@Nullable Double offset) {
+    this.offsetValue = offset;
+    return this;
+  }
+
+  @CheckForNull
+  public String getOffsetUnit() {
+    return offsetUnit;
+  }
+
+  public RequirementMigrationDto setOffsetUnit(@Nullable String offsetUnit) {
+    this.offsetUnit = offsetUnit;
+    return this;
+  }
+
+  public Date getCreatedAt() {
+    return createdAt;
+  }
+
+  public RequirementMigrationDto setCreatedAt(Date createdAt) {
+    this.createdAt = createdAt;
+    return this;
+  }
+
+  @CheckForNull
+  public Date getUpdatedAt() {
+    return updatedAt;
+  }
+
+  public RequirementMigrationDto setUpdatedAt(@Nullable Date updatedAt) {
+    this.updatedAt = updatedAt;
+    return this;
+  }
+
+  public boolean isEnabled() {
+    return enabled;
+  }
+
+  public RequirementMigrationDto setEnabled(boolean enabled) {
+    this.enabled = enabled;
+    return this;
+  }
+
+}
index 5857ba78a8760ae3e790f7e5bd8dab7e4c2cb003..abce63863736527608d95d00d49a2348cd74ed8c 100644 (file)
     where id=#{id}
   </update>
 
-  <select id="selectDeprecatedRequirements" resultType="map">
+  <select id="selectDeprecatedRequirements" resultType="RequirementMigration">
     select id as "id",
     parent_id as "parentId",
     root_id as "rootId",
index 10ddce7b90f6141bf2848a24988edfe1ac0c3ec2..2cf02ae839e78d48c4f63aaaa588fdde4131d2bb 100644 (file)
@@ -36,6 +36,7 @@ import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.MyBatis;
 import org.sonar.core.rule.RuleDto;
 import org.sonar.core.technicaldebt.db.CharacteristicMapper;
+import org.sonar.core.technicaldebt.db.RequirementMigrationDto;
 import org.sonar.core.template.LoadedTemplateDto;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.rule.RegisterRules;
@@ -45,13 +46,14 @@ import javax.annotation.Nullable;
 
 import java.util.Collection;
 import java.util.List;
-import java.util.Map;
 
 /**
  * This script copy every requirements from characteristics table (every row where rule_id is not null) to the rules table.
  * <p/>
  * This script need to be executed after rules registration because default debt columns (characteristics, function, coefficient and offset) has to be populated
  * in order to be able to compare default values with overridden values.
+ * <p/>
+ * WARNING : When updating this class, please take time to test on ALL databases!
  *
  * @since 4.3 this component could be removed after 4 or 5 releases.
  */
@@ -90,22 +92,21 @@ public class CopyRequirementsFromCharacteristicsToRules implements ServerCompone
     DbSession dbSession = dbClient.openSession(true);
 
     try {
-      List<Map<String, Object>> requirementDtos = dbSession.getMapper(CharacteristicMapper.class).selectDeprecatedRequirements();
+      List<RequirementMigrationDto> requirementDtos = dbSession.getMapper(CharacteristicMapper.class).selectDeprecatedRequirements();
       if (requirementDtos.isEmpty()) {
         LOGGER.info("No requirement will be copied", requirementDtos);
 
       } else {
         int requirementCopied = 0;
 
-        final Multimap<Number, RequirementDto> requirementsByRuleId = ArrayListMultimap.create();
-        for (Map<String, Object> map : requirementDtos) {
-          RequirementDto requirementDto = new RequirementDto(map);
+        final Multimap<Integer, RequirementMigrationDto> requirementsByRuleId = ArrayListMultimap.create();
+        for (RequirementMigrationDto requirementDto : requirementDtos) {
           requirementsByRuleId.put(requirementDto.getRuleId(), requirementDto);
         }
 
         List<RuleDto> rules = dbClient.ruleDao().findAll(dbSession);
         for (RuleDto rule : rules) {
-          Collection<RequirementDto> requirementsForRule = requirementsByRuleId.get(rule.getId());
+          Collection<RequirementMigrationDto> requirementsForRule = requirementsByRuleId.get(rule.getId());
           if (!requirementsForRule.isEmpty()) {
             convert(rule, requirementsForRule, dbSession);
             requirementCopied++;
@@ -120,8 +121,8 @@ public class CopyRequirementsFromCharacteristicsToRules implements ServerCompone
     }
   }
 
-  private void convert(RuleDto rule, Collection<RequirementDto> requirementsForRule, DbSession session) {
-    RequirementDto enabledRequirement = enabledRequirement(requirementsForRule);
+  private void convert(RuleDto rule, Collection<RequirementMigrationDto> requirementsForRule, DbSession session) {
+    RequirementMigrationDto enabledRequirement = enabledRequirement(requirementsForRule);
 
     if (enabledRequirement == null && RuleStatus.REMOVED != rule.getStatus()) {
       // If no enabled requirement is found, it means that the requirement has been disabled for this rule
@@ -135,10 +136,10 @@ public class CopyRequirementsFromCharacteristicsToRules implements ServerCompone
     }
   }
 
-  private static RequirementDto enabledRequirement(Collection<RequirementDto> requirementsForRule) {
-    return Iterables.find(requirementsForRule, new Predicate<RequirementDto>() {
+  private static RequirementMigrationDto enabledRequirement(Collection<RequirementMigrationDto> requirementsForRule) {
+    return Iterables.find(requirementsForRule, new Predicate<RequirementMigrationDto>() {
       @Override
-      public boolean apply(@Nullable RequirementDto input) {
+      public boolean apply(@Nullable RequirementMigrationDto input) {
         return input != null && input.isEnabled();
       }
     }, null);
@@ -152,8 +153,8 @@ public class CopyRequirementsFromCharacteristicsToRules implements ServerCompone
     dbClient.ruleDao().update(session, rule);
   }
 
-  private void convertEnabledRequirement(RuleDto ruleRow, RequirementDto enabledRequirement, DbSession session) {
-    ruleRow.setSubCharacteristicId(enabledRequirement.getParentId() != null ? enabledRequirement.getParentId().intValue() : null);
+  private void convertEnabledRequirement(RuleDto ruleRow, RequirementMigrationDto enabledRequirement, DbSession session) {
+    ruleRow.setSubCharacteristicId(enabledRequirement.getParentId() != null ? enabledRequirement.getParentId() : null);
     ruleRow.setRemediationFunction(enabledRequirement.getFunction().toUpperCase());
     ruleRow.setRemediationCoefficient(convertDuration(enabledRequirement.getCoefficientValue(), enabledRequirement.getCoefficientUnit()));
     ruleRow.setRemediationOffset(convertDuration(enabledRequirement.getOffsetValue(), enabledRequirement.getOffsetUnit()));
@@ -185,10 +186,10 @@ public class CopyRequirementsFromCharacteristicsToRules implements ServerCompone
 
   @CheckForNull
   @VisibleForTesting
-  static String convertDuration(@Nullable Number oldValue, @Nullable String oldUnit) {
-    if (oldValue != null && oldValue.doubleValue() > 0) {
+  static String convertDuration(@Nullable Double oldValue, @Nullable String oldUnit) {
+    if (oldValue != null && oldValue > 0) {
       // As value is stored in double, we have to round it in order to have an integer (for instance, if it was 1.6, we'll use 2)
-      return Integer.toString((int) Math.round(oldValue.doubleValue())) + convertUnit(oldUnit);
+      return Integer.toString((int) Math.round(oldValue)) + convertUnit(oldUnit);
     }
     return null;
   }
@@ -219,65 +220,4 @@ public class CopyRequirementsFromCharacteristicsToRules implements ServerCompone
     }
   }
 
-  static class RequirementDto {
-
-    private final Map<String, Object> map;
-
-    RequirementDto(Map<String, Object> map) {
-      this.map = map;
-    }
-
-    /**
-     * Do not use Integer because Oracle returns BigDecimal
-     */
-    public Number getId() {
-      return (Number) map.get("id");
-    }
-
-    /**
-     * Do not use Integer because Oracle returns BigDecimal
-     */
-    public Number getParentId() {
-      return (Number) map.get("parentId");
-    }
-
-    /**
-     * Do not use Integer because Oracle returns BigDecimal
-     */
-    public Number getRuleId() {
-      return (Number) map.get("ruleId");
-    }
-
-    public String getFunction() {
-      return (String) map.get("functionKey");
-    }
-
-    @CheckForNull
-    public Number getCoefficientValue() {
-      return (Number) map.get("coefficientValue");
-    }
-
-
-    @CheckForNull
-    public String getCoefficientUnit() {
-      return (String) map.get("coefficientUnit");
-    }
-
-
-    @CheckForNull
-    public Number getOffsetValue() {
-      return (Number) map.get("offsetValue");
-    }
-
-
-    @CheckForNull
-    public String getOffsetUnit() {
-      return (String) map.get("offsetUnit");
-    }
-
-    public boolean isEnabled() {
-      return (Boolean) map.get("enabled");
-    }
-  }
-
 }