]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4301 Improve performance when searching component children ids from specified...
authorJulien Lancelot <julien.lancelot@gmail.com>
Thu, 30 May 2013 08:48:54 +0000 (10:48 +0200)
committerJulien Lancelot <julien.lancelot@gmail.com>
Thu, 30 May 2013 08:49:05 +0000 (10:49 +0200)
sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java
sonar-core/src/main/java/org/sonar/core/issue/db/IssueMapper.java
sonar-core/src/main/java/org/sonar/core/issue/db/IssueStatsDao.java
sonar-core/src/main/java/org/sonar/core/issue/db/IssueStatsMapper.java
sonar-core/src/main/java/org/sonar/core/resource/ResourceDao.java
sonar-core/src/main/java/org/sonar/core/resource/ResourceMapper.java
sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml
sonar-core/src/main/resources/org/sonar/core/resource/ResourceMapper.xml
sonar-core/src/test/java/org/sonar/core/resource/ResourceDaoTest.java
sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/fixture.xml

index 92de3dcd68bdc10bd0f5ee55c055ba671cc9ce4d..0a030d6889caf38f3f79798751d4c60b01d104d4 100644 (file)
@@ -100,7 +100,7 @@ public class IssueDao implements BatchComponent, ServerComponent {
 
   private List<IssueDto> selectIssues(IssueQuery query, @Nullable Integer userId, Integer maxResults, SqlSession session){
     IssueMapper mapper = session.getMapper(IssueMapper.class);
-    return mapper.selectIssues(query, userId, query.requiredRole(), maxResults);
+    return mapper.selectIssues(query, query.componentRoots(), userId, query.requiredRole(), maxResults);
   }
 
   @VisibleForTesting
index f5e85754ef8da1669efb6211dbbe1bf01d863a72..c37fe4803caa4dc345a9de7f142e467471d30107 100644 (file)
@@ -24,6 +24,7 @@ import org.sonar.api.issue.IssueQuery;
 
 import javax.annotation.Nullable;
 
+import java.util.Collection;
 import java.util.List;
 
 public interface IssueMapper {
@@ -32,8 +33,8 @@ public interface IssueMapper {
 
   List<IssueDto> selectNonClosedIssues(int rootComponentId);
 
-  List<IssueDto> selectIssues(@Param("query") IssueQuery query, @Nullable @Param("userId") Integer userId, @Param("role") String role,
-                                          @Param("maxResults") Integer maxResult);
+  List<IssueDto> selectIssues(@Param("query") IssueQuery query, @Param("componentRootKeys") Collection<String> componentRootKeys,
+                              @Nullable @Param("userId") Integer userId, @Param("role") String role, @Param("maxResults") Integer maxResult);
 
   void insert(IssueDto issue);
 
index b5cfc3dfdc8700e0adec883d1322dac4b20964ad..059e8888df9b23af6a04e2fbc2db7c110ec104bd 100644 (file)
@@ -44,7 +44,7 @@ public class IssueStatsDao implements ServerComponent {
     SqlSession session = mybatis.openSession();
     try {
       IssueStatsMapper mapper = session.getMapper(IssueStatsMapper.class);
-      return mapper.selectIssuesColumn(query, column, userId, query.requiredRole());
+      return mapper.selectIssuesColumn(query, column, query.componentRoots(), userId, query.requiredRole());
     } finally {
       MyBatis.closeQuietly(session);
     }
index 3f401bf783e6e690243f5278d3c261078a70fdbb..e2e097ec6c97e63aec1830a036033b5151e580b4 100644 (file)
@@ -25,11 +25,12 @@ import org.sonar.api.issue.IssueQuery;
 
 import javax.annotation.Nullable;
 
+import java.util.Collection;
 import java.util.List;
 
 public interface IssueStatsMapper {
 
-  List<Object> selectIssuesColumn(@Param("query") IssueQuery query, @Param("column") String column,
+  List<Object> selectIssuesColumn(@Param("query") IssueQuery query, @Param("column") String column, @Param("componentRootKeys") Collection<String> componentRootKeys,
                                   @Nullable @Param("userId") Integer userId, @Param("role") String role);
 
 }
index 661527f987d25cf7ca30bb231a4e271fe0d91dfc..4901abda11cbce6a3aa8d892bef85006874a57ec 100644 (file)
@@ -154,6 +154,18 @@ public class ResourceDao {
     }
   }
 
+  public List<Integer> findChildrenComponentIds(Collection<String> componentRootKeys){
+    if (componentRootKeys.isEmpty()) {
+      return Collections.emptyList();
+    }
+    SqlSession session = mybatis.openSession();
+    try {
+      return session.getMapper(ResourceMapper.class).selectChildrenComponentIds(componentRootKeys);
+    } finally {
+      MyBatis.closeQuietly(session);
+    }
+  }
+
   @CheckForNull
   public ResourceDto getRootProjectByComponentKey(String componentKey) {
     SqlSession session = mybatis.openSession();
index 7e500ac589a79ecde435ba06334ace06c868c063..2d1c7429d2136f1fb9c2c091983b765b26631088 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.core.resource;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.session.ResultHandler;
 
+import java.util.Collection;
 import java.util.List;
 
 public interface ResourceMapper {
@@ -65,6 +66,11 @@ public interface ResourceMapper {
    */
   ResourceDto selectRootProjectByComponentId(@Param("componentId") Long componentId);
 
+  /**
+   * @since 3.6
+   */
+  List<Integer> selectChildrenComponentIds(@Param("componentRootKeys") Collection<String> componentRootKeys);
+
 
   void insert(ResourceDto resource);
 
index 3ebf476c91e1693fa82b15b807a1de8e35cac7e6..09c2ab1fb1433bbd393ab4ee5e0b87abeeda9d04 100644 (file)
   <sql id="selectQueryConditions">
     from issues i
     inner join (<include refid="org.sonar.core.user.AuthorizationMapper.selectAuthorizedRootProjectsIdsQuery" />) authorizedProjects on authorizedProjects.root_project_id=i.root_component_id
-    <if test="query.componentRoots() != null and query.componentRoots().size() > 0">
-      inner join projects rootprojects on rootprojects.enabled=${_true} and rootprojects.kee in
-      <foreach item="componentRoot" index="index" collection="query.componentRoots()" open="(" separator="," close=")">
-        #{componentRoot}
-      </foreach>
-      inner join snapshots rootsnapshots on rootsnapshots.project_id=rootprojects.id and rootsnapshots.islast=${_true}
-      inner join snapshots s on s.project_id=i.component_id and s.islast=${_true} and
-      (s.id=rootsnapshots.id or ((s.root_snapshot_id=rootsnapshots.id or s.root_snapshot_id=rootsnapshots.root_snapshot_id) and
-      <choose>
-        <when test="_databaseId == 'mssql'">
-          s.path LIKE rootsnapshots.path + CAST(rootsnapshots.id AS varchar(15)) + '.%'
-        </when>
-        <when test="_databaseId == 'mysql'">
-          s.path LIKE concat(rootsnapshots.path, rootsnapshots.id, '.%')
-        </when>
-        <otherwise>
-          s.path LIKE rootsnapshots.path || rootsnapshots.id || '.%'
-        </otherwise>
-      </choose>
-      ))
+    <if test="componentRootKeys != null and componentRootKeys.size() > 0">
+      inner join (<include refid="org.sonar.core.resource.ResourceMapper.selectChildrenComponentIdsQuery" />) components on components.project_id=i.component_id
     </if>
     <if test="query.components() != null and query.components().size() > 0">
       inner join projects project_component on project_component.id=i.component_id and project_component.enabled=${_true} and project_component.kee in
index 1b1270b7dbe0de275d31992d200eb2ed0905583d..41de56b693121058d03b042b0f1dfc4885286941 100644 (file)
     </where>
   </select>
 
+  <select id="selectChildrenComponentIds" parameterType="map" resultType="int">
+    <include refid="selectChildrenComponentIdsQuery" />
+  </select>
+
+  <sql id="selectChildrenComponentIdsQuery">
+    select s.project_id
+    from snapshots s
+    inner join snapshots rootsnapshots on (rootsnapshots.id=s.id or ((rootsnapshots.id=s.root_snapshot_id or rootsnapshots.root_snapshot_id=s.root_snapshot_id) and
+      <choose>
+        <when test="_databaseId == 'mssql'">
+          s.path LIKE rootsnapshots.path + CAST(rootsnapshots.id AS varchar(15)) + '.%'
+        </when>
+        <when test="_databaseId == 'mysql'">
+          s.path LIKE concat(rootsnapshots.path, rootsnapshots.id, '.%')
+        </when>
+        <otherwise>
+          s.path LIKE rootsnapshots.path || rootsnapshots.id || '.%'
+        </otherwise>
+      </choose>))
+      and rootsnapshots.islast=${_true}
+    <where>
+      and s.islast=${_true}
+      and rootsnapshots.project_id in
+      (select p.id from projects p where p.enabled=${_true}
+        and p.kee in <foreach item="componentKey" index="index" collection="componentRootKeys" open="(" separator="," close=")">#{componentKey}</foreach>)
+    </where>
+  </sql>
+
+
   <insert id="insert" parameterType="Resource" useGeneratedKeys="true" keyProperty="id">
     insert into projects
     (name, long_name, description, scope, qualifier, kee, language, root_id, copy_resource_id, person_id, enabled, created_at)
index 3ef4e1105684a7eb35713f56fdfd8985a4fcdf44..00102831f4e78fc943d61a14e3564508c3b993d5 100644 (file)
@@ -28,6 +28,7 @@ import org.sonar.api.resources.Scopes;
 import org.sonar.core.persistence.AbstractDaoTestCase;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
 import static com.google.common.collect.Lists.newArrayList;
@@ -245,4 +246,17 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
 
     assertEmptyTables("projects");
   }
+
+  @Test
+  public void should_find_children_component_ids(){
+    setupData("fixture");
+
+    assertThat(dao.findChildrenComponentIds(newArrayList("org.struts:struts"))).hasSize(4);
+    assertThat(dao.findChildrenComponentIds(newArrayList("org.struts:struts-core"))).hasSize(3);
+    assertThat(dao.findChildrenComponentIds(newArrayList("org.struts:struts:org.struts"))).hasSize(2);
+    assertThat(dao.findChildrenComponentIds(newArrayList("org.struts:struts:org.struts.RequestContext"))).hasSize(1);
+
+    assertThat(dao.findChildrenComponentIds(newArrayList("unknown"))).isEmpty();
+    assertThat(dao.findChildrenComponentIds(Collections.<String>emptyList())).isEmpty();
+  }
 }
index 6c362ca796300b8b9a6afad0b0ce085b75faf5f6..6445d143ed7b3e11481058e6ce8d3ac645eb0935 100644 (file)
@@ -5,28 +5,28 @@
             description="the description" long_name="Apache Struts"
             enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"/>
   <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
-               status="P" islast="[false]" purge_status="[null]"
+               status="P" islast="[true]" purge_status="[null]"
                period1_mode="[null]" period1_param="[null]" period1_date="[null]"
                period2_mode="[null]" period2_param="[null]" period2_date="[null]"
                period3_mode="[null]" period3_param="[null]" period3_date="[null]"
                period4_mode="[null]" period4_param="[null]" period4_date="[null]"
                period5_mode="[null]" period5_param="[null]" period5_date="[null]"
                depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
-               version="[null]" path="[null]"/>
+               version="[null]" path=""/>
 
   <!-- project -->
   <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
             scope="PRJ" qualifier="BRC" long_name="Struts Core"
             description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"/>
   <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
-               status="P" islast="[false]" purge_status="[null]"
+               status="P" islast="[true]" purge_status="[null]"
                period1_mode="[null]" period1_param="[null]" period1_date="[null]"
                period2_mode="[null]" period2_param="[null]" period2_date="[null]"
                period3_mode="[null]" period3_param="[null]" period3_date="[null]"
                period4_mode="[null]" period4_param="[null]" period4_date="[null]"
                period5_mode="[null]" period5_param="[null]" period5_date="[null]"
                depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
-               version="[null]" path="[null]"/>
+               version="[null]" path="1."/>
 
   <!-- directory -->
   <projects long_name="org.struts" id="3" scope="DIR" qualifier="PAC" kee="org.struts:struts:org.struts"
               description="[null]"
               enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"/>
   <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1"
-               status="P" islast="[false]" purge_status="[null]"
+               status="P" islast="[true]" purge_status="[null]"
                period1_mode="[null]" period1_param="[null]" period1_date="[null]"
                period2_mode="[null]" period2_param="[null]" period2_date="[null]"
                period3_mode="[null]" period3_param="[null]" period3_date="[null]"
                period4_mode="[null]" period4_param="[null]" period4_date="[null]"
                period5_mode="[null]" period5_param="[null]" period5_date="[null]"
                depth="[null]" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
-               version="[null]" path="[null]"/>
+               version="[null]" path="1.2."/>
 
   <!-- file -->
   <projects long_name="org.struts.RequestContext" id="4" scope="FIL" qualifier="CLA" kee="org.struts:struts:org.struts.RequestContext"
             enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"/>
 
   <snapshots id="4" project_id="4" parent_snapshot_id="3" root_project_id="1" root_snapshot_id="1"
-               status="P" islast="[false]" purge_status="[null]"
+               status="P" islast="[true]" purge_status="[null]"
                period1_mode="[null]" period1_param="[null]" period1_date="[null]"
                period2_mode="[null]" period2_param="[null]" period2_date="[null]"
                period3_mode="[null]" period3_param="[null]" period3_date="[null]"
                period4_mode="[null]" period4_param="[null]" period4_date="[null]"
                period5_mode="[null]" period5_param="[null]" period5_date="[null]"
                depth="[null]" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
-               version="[null]" path="[null]"/>
+               version="[null]" path="1.2.3."/>
 </dataset>