]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5446 Missing rule parameter values on Quality profiles
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Thu, 17 Jul 2014 05:15:05 +0000 (07:15 +0200)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Thu, 17 Jul 2014 05:15:05 +0000 (07:15 +0200)
12 files changed:
server/sonar-server/src/main/java/org/sonar/server/db/migrations/BaseDataChange.java
server/sonar-server/src/main/java/org/sonar/server/db/migrations/BaseSqlStatement.java
server/sonar-server/src/main/java/org/sonar/server/db/migrations/DataChange.java
server/sonar-server/src/main/java/org/sonar/server/db/migrations/Select.java
server/sonar-server/src/main/java/org/sonar/server/db/migrations/SelectImpl.java
server/sonar-server/src/main/java/org/sonar/server/db/migrations/SqlStatement.java
server/sonar-server/src/main/java/org/sonar/server/db/migrations/v45/AddMissingRuleParameterDefaultValuesMigration.java
server/sonar-server/src/test/java/org/sonar/server/db/migrations/BaseDataChangeTest.java
server/sonar-server/src/test/java/org/sonar/server/db/migrations/v45/AddMissingRuleParameterDefaultValuesMigrationTest.java [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingRuleParameterDefaultValuesMigrationTest/after.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingRuleParameterDefaultValuesMigrationTest/before.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingRuleParameterDefaultValuesMigrationTest/schema.sql [new file with mode: 0644]

index 473818b1b5a1a0b91df9576c960813cfe8893a5d..c659a355dc79af3f69629466c96b8f7672cc1a86 100644 (file)
@@ -35,15 +35,17 @@ public abstract class BaseDataChange implements DataChange, DatabaseMigration {
 
   @Override
   public final void execute() throws SQLException {
-    Connection connection = null;
+    Connection readConnection = null, writeConnection = null;
     try {
-      connection = db.getDataSource().getConnection();
-      connection.setAutoCommit(false);
-      Context context = new Context(db, connection);
+      readConnection = db.getDataSource().getConnection();
+      writeConnection = db.getDataSource().getConnection();
+      writeConnection.setAutoCommit(false);
+      Context context = new Context(db, readConnection, writeConnection);
       execute(context);
 
     } finally {
-      DbUtils.closeQuietly(connection);
+      DbUtils.closeQuietly(readConnection);
+      DbUtils.closeQuietly(writeConnection);
     }
   }
 }
index 1d31fd0f88ca31142bf4c4234c8d274ce0daa57c..f04e2da2078dd70f4e8ebeb43c6138d6170e7084 100644 (file)
@@ -22,7 +22,6 @@ package org.sonar.server.db.migrations;
 import org.apache.commons.dbutils.DbUtils;
 
 import javax.annotation.Nullable;
-
 import java.sql.PreparedStatement;
 import java.sql.SQLException;
 import java.sql.Timestamp;
@@ -40,7 +39,7 @@ abstract class BaseSqlStatement<CHILD extends SqlStatement> implements SqlStatem
   public CHILD close() {
     DbUtils.closeQuietly(pstmt);
     pstmt = null;
-    return (CHILD)this;
+    return (CHILD) this;
   }
 
   @Override
@@ -79,6 +78,16 @@ abstract class BaseSqlStatement<CHILD extends SqlStatement> implements SqlStatem
     return (CHILD) this;
   }
 
+  @Override
+  public CHILD setDouble(int columnIndex, @Nullable Double value) throws SQLException {
+    if (value == null) {
+      pstmt.setNull(columnIndex, Types.DECIMAL);
+    } else {
+      pstmt.setDouble(columnIndex, value);
+    }
+    return (CHILD) this;
+  }
+
   @Override
   public CHILD setDate(int columnIndex, @Nullable Date value) throws SQLException {
     if (value == null) {
index 20075cbf8bb30fdf07975ae101621c7389f52e7c..01646b169261f9aae8c5267ed66ddcfff65b4928 100644 (file)
@@ -28,23 +28,24 @@ public interface DataChange {
 
   class Context {
     private final Database db;
-    private final Connection connection;
+    private final Connection readConnection, writeConnection;
 
-    public Context(Database db, Connection connection) {
+    public Context(Database db, Connection readConnection, Connection writeConnection) {
       this.db = db;
-      this.connection = connection;
+      this.readConnection = readConnection;
+      this.writeConnection = writeConnection;
     }
 
     public Select prepareSelect(String sql) throws SQLException {
-      return SelectImpl.create(db, connection, sql);
+      return SelectImpl.create(db, readConnection, sql);
     }
 
     public Upsert prepareUpsert(String sql) throws SQLException {
-      return UpsertImpl.create(connection, sql);
+      return UpsertImpl.create(writeConnection, sql);
     }
 
     public MassUpdate prepareMassUpdate() throws SQLException {
-      return new MassUpdate(db, connection);
+      return new MassUpdate(db, writeConnection);
     }
   }
 
index b9cb30522c177ab12416386f6bf393e7a0d9a941..57eb407d38aa0e7a3b7f0b21e16513054e086ff5 100644 (file)
@@ -74,6 +74,7 @@ public interface Select extends SqlStatement<Select> {
   }
 
   static interface RowReader<T> {
+    RowReader<Long> LONG = new LongReader();
     T read(Row row) throws SQLException;
   }
 
@@ -87,13 +88,14 @@ public interface Select extends SqlStatement<Select> {
     }
   }
 
-  public static final LongReader LONG_READER = new LongReader();
-
   static interface RowHandler<T> {
     void handle(Row row) throws SQLException;
   }
 
-  <T> List<T> query(RowReader<T> reader) throws SQLException;
+  <T> List<T> list(RowReader<T> reader) throws SQLException;
+
+  @CheckForNull
+  <T> T get(RowReader<T> reader) throws SQLException;
 
   void scroll(RowHandler handler) throws SQLException;
 }
index e8c05a3f4326edf7a32372a6f358093a95329c75..b49fc88edee07aba640a4af55da644521cd3bd64 100644 (file)
@@ -37,7 +37,7 @@ class SelectImpl extends BaseSqlStatement<Select> implements Select {
   }
 
   @Override
-  public <T> List<T> query(Select.RowReader<T> reader) throws SQLException {
+  public <T> List<T> list(Select.RowReader<T> reader) throws SQLException {
     ResultSet rs = pstmt.executeQuery();
     Select.Row row = new Select.Row(rs);
     try {
@@ -52,6 +52,21 @@ class SelectImpl extends BaseSqlStatement<Select> implements Select {
     }
   }
 
+  @Override
+  public <T> T get(Select.RowReader<T> reader) throws SQLException {
+    ResultSet rs = pstmt.executeQuery();
+    Select.Row row = new Select.Row(rs);
+    try {
+      if (rs.next()) {
+        return reader.read(row);
+      }
+      return null;
+    } finally {
+      DbUtils.closeQuietly(rs);
+      close();
+    }
+  }
+
   @Override
   public void scroll(Select.RowHandler handler) throws SQLException {
     ResultSet rs = pstmt.executeQuery();
index a8caf209ea7aaf3efade13384280a183eda21d2f..4a679308550ddd5daeb9e9a48458a6901ab1171a 100644 (file)
@@ -28,6 +28,8 @@ public interface SqlStatement<CHILD extends SqlStatement> {
 
   CHILD setDate(int columnIndex, @Nullable Date value) throws SQLException;
 
+  CHILD setDouble(int columnIndex, @Nullable Double value) throws SQLException;
+
   CHILD setInt(int columnIndex, @Nullable Integer value) throws SQLException;
 
   CHILD setLong(int columnIndex, @Nullable Long value) throws SQLException;
index d11e9c09c2b4b4837ab5723e3324fef3b3f8f613..f76bffa840286645097c6d5e105fa3fa07fe63f6 100644 (file)
  */
 package org.sonar.server.db.migrations.v45;
 
-import org.apache.commons.dbutils.DbUtils;
+import org.sonar.api.utils.System2;
 import org.sonar.core.persistence.Database;
 import org.sonar.server.db.migrations.BaseDataChange;
 import org.sonar.server.db.migrations.Select;
 import org.sonar.server.db.migrations.Upsert;
 
-import java.sql.Connection;
 import java.sql.SQLException;
 import java.util.Date;
 import java.util.List;
@@ -35,17 +34,19 @@ import java.util.List;
  */
 public class AddMissingRuleParameterDefaultValuesMigration extends BaseDataChange {
 
-  public AddMissingRuleParameterDefaultValuesMigration(Database db) {
+  private final System2 system;
+
+  public AddMissingRuleParameterDefaultValuesMigration(Database db, System2 system) {
     super(db);
+    this.system = system;
   }
 
   @Override
   public void execute(Context context) {
-    Connection connection = null;
     try {
       // get all the parameters with default value
       List<RuleParam> ruleParameters = context.prepareSelect("select id,rule_id,name,default_value from rules_parameters where default_value is not null")
-        .query(new Select.RowReader<RuleParam>() {
+        .list(new Select.RowReader<RuleParam>() {
           @Override
           public RuleParam read(Select.Row row) throws SQLException {
             return new RuleParam(row.getLong(1), row.getLong(2), row.getString(3), row.getString(4));
@@ -58,7 +59,7 @@ public class AddMissingRuleParameterDefaultValuesMigration extends BaseDataChang
           "where ar.rule_id=? and arp.id is null")
           .setLong(1, ruleParameter.id)
           .setLong(2, ruleParameter.ruleId)
-          .query(new Select.RowReader<ActiveRule>() {
+          .list(new Select.RowReader<ActiveRule>() {
             @Override
             public ActiveRule read(Select.Row row) throws SQLException {
               return new ActiveRule(row.getLong(1), row.getLong(2));
@@ -74,24 +75,22 @@ public class AddMissingRuleParameterDefaultValuesMigration extends BaseDataChang
             .setString(4, ruleParameter.name)
             .addBatch();
         }
-        upsert.execute();
+        upsert.execute().commit().close();
 
         // update date for ES indexation
         upsert = context.prepareUpsert("update active_rules set updated_at=? where id=?");
-        Date now = new Date();
+        Date now = new Date(system.now());
         for (ActiveRule activeRule : activeRules) {
           upsert
             .setDate(1, now)
             .setLong(2, activeRule.id)
             .addBatch();
         }
-        upsert.execute();
+        upsert.execute().commit().close();
 
       }
     } catch (SQLException e) {
       e.printStackTrace();
-    } finally {
-      DbUtils.closeQuietly(connection);
     }
   }
 
@@ -115,16 +114,4 @@ public class AddMissingRuleParameterDefaultValuesMigration extends BaseDataChang
       this.profileId = profileId;
     }
   }
-
-  private static class ActiveRuleParam {
-    final long activeRuleId, ruleParamId;
-    final String value, ruleParamKey;
-
-    ActiveRuleParam(long activeRuleId, long ruleParamId, String ruleParamKey, String value) {
-      this.activeRuleId = activeRuleId;
-      this.ruleParamId = ruleParamId;
-      this.ruleParamKey = ruleParamKey;
-      this.value = value;
-    }
-  }
 }
index 2b1b1babbbab6864d52b08947cff77c63f0850ad..2896cb6384b983ee4437468b22ef2774bcd379b6 100644 (file)
@@ -51,7 +51,7 @@ public class BaseDataChangeTest extends AbstractDaoTestCase {
     new BaseDataChange(db.database()) {
       @Override
       public void execute(Context context) throws SQLException {
-        ids.addAll(context.prepareSelect("select id from persons order by id desc").query(Select.LONG_READER));
+        ids.addAll(context.prepareSelect("select id from persons order by id desc").list(Select.RowReader.LONG));
       }
     }.execute();
     assertThat(ids).containsExactly(3L, 2L, 1L);
@@ -67,7 +67,7 @@ public class BaseDataChangeTest extends AbstractDaoTestCase {
       public void execute(Context context) throws SQLException {
         persons.addAll(context
           .prepareSelect("select id,login,age,enabled,updated_at from persons where id=2")
-          .query(new UserReader()));
+          .list(new UserReader()));
       }
     }.execute();
     assertThat(persons).hasSize(1);
@@ -86,7 +86,7 @@ public class BaseDataChangeTest extends AbstractDaoTestCase {
     new BaseDataChange(db.database()) {
       @Override
       public void execute(Context context) throws SQLException {
-        ids.addAll(context.prepareSelect("select id from persons where id>=?").setLong(1, 2L).query(Select.LONG_READER));
+        ids.addAll(context.prepareSelect("select id from persons where id>=?").setLong(1, 2L).list(Select.RowReader.LONG));
       }
     }.execute();
     assertThat(ids).containsOnly(2L, 3L);
@@ -101,7 +101,7 @@ public class BaseDataChangeTest extends AbstractDaoTestCase {
       @Override
       public void execute(Context context) throws SQLException {
         // parameter value is not set
-        ids.addAll(context.prepareSelect("select id from persons where id>=?").query(Select.LONG_READER));
+        ids.addAll(context.prepareSelect("select id from persons where id>=?").list(Select.RowReader.LONG));
       }
     };
     try {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/db/migrations/v45/AddMissingRuleParameterDefaultValuesMigrationTest.java b/server/sonar-server/src/test/java/org/sonar/server/db/migrations/v45/AddMissingRuleParameterDefaultValuesMigrationTest.java
new file mode 100644 (file)
index 0000000..c4021bc
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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.server.db.migrations.v45;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.System2;
+import org.sonar.core.persistence.TestDatabase;
+import org.sonar.server.db.migrations.DatabaseMigration;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class AddMissingRuleParameterDefaultValuesMigrationTest {
+
+  @ClassRule
+  public static TestDatabase db = new TestDatabase().schema(AddMissingRuleParameterDefaultValuesMigrationTest.class, "schema.sql");
+
+  DatabaseMigration migration;
+  System2 system = mock(System2.class);
+
+  @Before
+  public void setUp() throws Exception {
+    db.executeUpdateSql("truncate table rules_parameters");
+    db.executeUpdateSql("truncate table active_rules");
+    db.executeUpdateSql("truncate table active_rule_parameters");
+    migration = new AddMissingRuleParameterDefaultValuesMigration(db.database(), system);
+    when(system.now()).thenReturn(DateUtils.parseDate("2014-04-28").getTime());
+  }
+
+  @Test
+  public void execute() throws Exception {
+    db.prepareDbUnit(getClass(), "before.xml");
+
+    migration.execute();
+
+    db.assertDbUnit(getClass(), "after.xml", "rules_parameters", "active_rules", "active_rule_parameters");
+  }
+
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingRuleParameterDefaultValuesMigrationTest/after.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingRuleParameterDefaultValuesMigrationTest/after.xml
new file mode 100644 (file)
index 0000000..5a463c1
--- /dev/null
@@ -0,0 +1,20 @@
+<dataset>
+  <!-- with default value -->
+  <rules_parameters id="1" rule_id="10" name="max" param_type="INT" default_value="10" description="[null]" />
+
+  <!-- without default value, to be ignored -->
+  <rules_parameters id="2" rule_id="10" name="min" param_type="INT" default_value="[null]" description="[null]" />
+
+  <!-- this active rule has all parameters -->
+  <active_rules id="100" profile_id="1000" rule_id="10" failure_level="3" inheritance="[null]"
+                created_at="2012-01-01" updated_at="2012-01-01" />
+  <active_rule_parameters id="10000" active_rule_id="100" rules_parameter_id="1" rules_parameter_key="max" value="9"/>
+  <active_rule_parameters id="10001" active_rule_id="100" rules_parameter_id="2" rules_parameter_key="min" value="4"/>
+
+  <!-- this active rule does not have parameters. UPDATED_AT CHANGED  -->
+  <active_rules id="101" profile_id="1000" rule_id="10" failure_level="3" inheritance="[null]"
+                created_at="2012-01-01" updated_at="2014-04-28" />
+
+  <!-- newly created -->
+  <active_rule_parameters id="10002" active_rule_id="101" rules_parameter_id="1" rules_parameter_key="max" value="10"/>
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingRuleParameterDefaultValuesMigrationTest/before.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingRuleParameterDefaultValuesMigrationTest/before.xml
new file mode 100644 (file)
index 0000000..b8914e4
--- /dev/null
@@ -0,0 +1,17 @@
+<dataset>
+  <!-- with default value -->
+  <rules_parameters id="1" rule_id="10" name="max" param_type="INT" default_value="10" description="[null]" />
+
+  <!-- without default value, to be ignored -->
+  <rules_parameters id="2" rule_id="10" name="min" param_type="INT" default_value="[null]" description="[null]" />
+
+  <!-- this active rule has all parameters -->
+  <active_rules id="100" profile_id="1000" rule_id="10" failure_level="3" inheritance="[null]"
+                created_at="2012-01-01" updated_at="2012-01-01" />
+  <active_rule_parameters id="10000" active_rule_id="100" rules_parameter_id="1" rules_parameter_key="max" value="9"/>
+  <active_rule_parameters id="10001" active_rule_id="100" rules_parameter_id="2" rules_parameter_key="min" value="4"/>
+
+  <!-- this active rule does not have parameters  -->
+  <active_rules id="101" profile_id="1000" rule_id="10" failure_level="3" inheritance="[null]"
+                created_at="2012-01-01" updated_at="2012-01-01" />
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingRuleParameterDefaultValuesMigrationTest/schema.sql b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingRuleParameterDefaultValuesMigrationTest/schema.sql
new file mode 100644 (file)
index 0000000..ebb5744
--- /dev/null
@@ -0,0 +1,28 @@
+CREATE TABLE "RULES_PARAMETERS" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "RULE_ID" INTEGER NOT NULL,
+  "NAME" VARCHAR(128) NOT NULL,
+  "PARAM_TYPE" VARCHAR(512) NOT NULL,
+  "DEFAULT_VALUE" VARCHAR(4000),
+  "DESCRIPTION" VARCHAR(4000)
+);
+
+
+CREATE TABLE "ACTIVE_RULES" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "PROFILE_ID" INTEGER NOT NULL,
+  "RULE_ID" INTEGER NOT NULL,
+  "FAILURE_LEVEL" INTEGER NOT NULL,
+  "INHERITANCE" VARCHAR(10),
+  "CREATED_AT" TIMESTAMP,
+  "UPDATED_AT" TIMESTAMP
+);
+
+
+CREATE TABLE "ACTIVE_RULE_PARAMETERS" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "ACTIVE_RULE_ID" INTEGER NOT NULL,
+  "RULES_PARAMETER_ID" INTEGER NOT NULL,
+  "RULES_PARAMETER_KEY" VARCHAR(128),
+  "VALUE" VARCHAR(4000)
+);