]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6857 ComponentDao with a generic way to search for components
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Wed, 30 Sep 2015 14:17:20 +0000 (16:17 +0200)
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Fri, 2 Oct 2015 07:23:01 +0000 (09:23 +0200)
25 files changed:
server/sonar-server/src/test/java/org/sonar/server/component/SnapshotTesting.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportComputeMeasureVariationsStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportPersistSnapshotsStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/ValidateProjectStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsComputeMeasureVariationsStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsPersistSnapshotsStepTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/IssueCommentServiceMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/measure/custom/ws/SearchActionTest.java
server/sonar-server/src/test/java/org/sonar/server/project/ws/BulkDeleteActionTest.java
server/sonar-server/src/test/java/org/sonar/server/project/ws/DeleteActionTest.java
server/sonar-server/src/test/java/org/sonar/server/project/ws/GhostsActionTest.java
server/sonar-server/src/test/java/org/sonar/server/project/ws/ProvisionedActionTest.java
server/sonar-server/src/test/java/org/sonar/server/ui/ws/ComponentNavigationActionTest.java
sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java
sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java
sonar-db/src/main/java/org/sonar/db/component/ComponentQuery.java [new file with mode: 0644]
sonar-db/src/main/java/org/sonar/db/dialect/AbstractDialect.java
sonar-db/src/main/java/org/sonar/db/dialect/Dialect.java
sonar-db/src/main/java/org/sonar/db/dialect/WildcardPosition.java [new file with mode: 0644]
sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml
sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java
sonar-db/src/test/java/org/sonar/db/component/ComponentDbTester.java [new file with mode: 0644]
sonar-db/src/test/java/org/sonar/db/component/SnapshotTesting.java [new file with mode: 0644]
sonar-db/src/test/java/org/sonar/db/dialect/DialectTest.java [new file with mode: 0644]

diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/SnapshotTesting.java b/server/sonar-server/src/test/java/org/sonar/server/component/SnapshotTesting.java
deleted file mode 100644 (file)
index e370073..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.server.component;
-
-import com.google.common.base.Preconditions;
-import org.assertj.core.util.Strings;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.SnapshotDto;
-
-public class SnapshotTesting {
-
-  /**
-   * Can be used for modules and files
-   */
-  public static SnapshotDto createForComponent(ComponentDto component, SnapshotDto parentSnapshot) {
-    Preconditions.checkNotNull(parentSnapshot.getId(), "The parent snapshot need to be persisted before creating this snapshot");
-    Long parentRootId = parentSnapshot.getRootId();
-    return createBasicSnapshot(component, parentSnapshot.getRootProjectId())
-      .setRootId(parentRootId != null ? parentRootId : parentSnapshot.getId())
-      .setParentId(parentSnapshot.getId())
-      .setPath(Strings.isNullOrEmpty(parentSnapshot.getPath()) ? Long.toString(parentSnapshot.getId()) + "." : parentSnapshot.getPath() + Long.toString(parentSnapshot.getId()) + ".");
-  }
-
-  public static SnapshotDto createForProject(ComponentDto project) {
-    return createBasicSnapshot(project, project.getId())
-        .setPath("");
-  }
-
-  public static SnapshotDto createForView(ComponentDto view) {
-    return createBasicSnapshot(view, view.getId())
-        .setPath("");
-  }
-
-  private static SnapshotDto createBasicSnapshot(ComponentDto component, Long rootProjectId) {
-    Preconditions.checkNotNull(component.getId(), "The project need to be persisted before creating this snapshot");
-    Preconditions.checkNotNull(rootProjectId, "Root project id is null");
-    return new SnapshotDto()
-      .setComponentId(component.getId())
-      .setRootProjectId(rootProjectId)
-      .setStatus(SnapshotDto.STATUS_PROCESSED)
-      .setQualifier(component.qualifier())
-      .setScope(component.scope())
-      .setCreatedAt(System.currentTimeMillis())
-      .setBuildDate(System.currentTimeMillis())
-      .setLast(true);
-  }
-
-}
index a072dfd9a894487712113bbe2a0ffe20a961da7b..1b74b2c70ca08c5b7cf1aa9d082099e8f9e2b888 100644 (file)
@@ -46,8 +46,8 @@ import org.sonar.server.computation.period.PeriodsHolderRule;
 import org.sonar.test.DbTests;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.server.component.SnapshotTesting.createForComponent;
-import static org.sonar.server.component.SnapshotTesting.createForProject;
+import static org.sonar.db.component.SnapshotTesting.createForComponent;
+import static org.sonar.db.component.SnapshotTesting.newSnapshotForProject;
 
 @Category(DbTests.class)
 public class ReportComputeMeasureVariationsStepTest {
@@ -100,7 +100,7 @@ public class ReportComputeMeasureVariationsStepTest {
 
   @Test
   public void do_nothing_when_no_raw_measure() {
-    SnapshotDto period1ProjectSnapshot = createForProject(PROJECT_DTO);
+    SnapshotDto period1ProjectSnapshot = newSnapshotForProject(PROJECT_DTO);
     dbClient.snapshotDao().insert(session, period1ProjectSnapshot);
     dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.getId(), period1ProjectSnapshot.getId(), 60d));
     session.commit();
@@ -128,7 +128,7 @@ public class ReportComputeMeasureVariationsStepTest {
   @Test
   public void set_variation() {
     // Project
-    SnapshotDto period1ProjectSnapshot = createForProject(PROJECT_DTO);
+    SnapshotDto period1ProjectSnapshot = newSnapshotForProject(PROJECT_DTO);
     dbClient.snapshotDao().insert(session, period1ProjectSnapshot);
     dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.getId(), period1ProjectSnapshot.getId(), 60d));
 
@@ -157,11 +157,11 @@ public class ReportComputeMeasureVariationsStepTest {
 
   @Test
   public void set_variations_on_all_periods() {
-    SnapshotDto period1ProjectSnapshot = createForProject(PROJECT_DTO).setLast(false);
-    SnapshotDto period2ProjectSnapshot = createForProject(PROJECT_DTO).setLast(false);
-    SnapshotDto period3ProjectSnapshot = createForProject(PROJECT_DTO).setLast(false);
-    SnapshotDto period4ProjectSnapshot = createForProject(PROJECT_DTO).setLast(false);
-    SnapshotDto period5ProjectSnapshot = createForProject(PROJECT_DTO).setLast(false);
+    SnapshotDto period1ProjectSnapshot = newSnapshotForProject(PROJECT_DTO).setLast(false);
+    SnapshotDto period2ProjectSnapshot = newSnapshotForProject(PROJECT_DTO).setLast(false);
+    SnapshotDto period3ProjectSnapshot = newSnapshotForProject(PROJECT_DTO).setLast(false);
+    SnapshotDto period4ProjectSnapshot = newSnapshotForProject(PROJECT_DTO).setLast(false);
+    SnapshotDto period5ProjectSnapshot = newSnapshotForProject(PROJECT_DTO).setLast(false);
     dbClient.snapshotDao().insert(session, period1ProjectSnapshot, period2ProjectSnapshot, period3ProjectSnapshot, period4ProjectSnapshot, period5ProjectSnapshot);
 
     dbClient.measureDao().insert(session,
@@ -197,7 +197,7 @@ public class ReportComputeMeasureVariationsStepTest {
 
   @Test
   public void set_variation_on_all_numeric_metrics() {
-    SnapshotDto period1ProjectSnapshot = createForProject(PROJECT_DTO);
+    SnapshotDto period1ProjectSnapshot = newSnapshotForProject(PROJECT_DTO);
     dbClient.snapshotDao().insert(session, period1ProjectSnapshot);
     dbClient.measureDao().insert(session,
       newMeasureDto(ISSUES_METRIC.getId(), PROJECT_DTO.getId(), period1ProjectSnapshot.getId(), 60d),
index e9d0ced4fd65f3fb44ad5629cac4a1bdf6c773ef..84bebad7585fd373729390c3f3b05e8f0af0411f 100644 (file)
@@ -35,7 +35,7 @@ import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.component.SnapshotQuery;
 import org.sonar.db.component.ComponentTesting;
-import org.sonar.server.component.SnapshotTesting;
+import org.sonar.db.component.SnapshotTesting;
 import org.sonar.server.computation.analysis.MutableAnalysisMetadataHolderRule;
 import org.sonar.server.computation.batch.TreeRootHolderRule;
 import org.sonar.server.computation.component.Component;
@@ -282,7 +282,7 @@ public class ReportPersistSnapshotsStepTest extends BaseStepTest {
   public void persist_snapshots_with_periods() {
     ComponentDto projectDto = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY).setName("Project");
     dbClient.componentDao().insert(dbTester.getSession(), projectDto);
-    SnapshotDto snapshotDto = SnapshotTesting.createForProject(projectDto).setCreatedAt(DateUtils.parseDateQuietly("2015-01-01").getTime());
+    SnapshotDto snapshotDto = SnapshotTesting.newSnapshotForProject(projectDto).setCreatedAt(DateUtils.parseDateQuietly("2015-01-01").getTime());
     dbClient.snapshotDao().insert(dbTester.getSession(), snapshotDto);
     dbTester.getSession().commit();
     periodsHolder.setPeriods(new Period(1, CoreProperties.TIMEMACHINE_MODE_DATE, "2015-01-01", analysisDate, 123L));
@@ -305,7 +305,7 @@ public class ReportPersistSnapshotsStepTest extends BaseStepTest {
 
     ComponentDto projectDto = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY).setName("Project");
     dbClient.componentDao().insert(dbTester.getSession(), projectDto);
-    SnapshotDto projectSnapshot = SnapshotTesting.createForProject(projectDto);
+    SnapshotDto projectSnapshot = SnapshotTesting.newSnapshotForProject(projectDto);
     dbClient.snapshotDao().insert(dbTester.getSession(), projectSnapshot);
 
     ComponentDto moduleDto = ComponentTesting.newModuleDto("BCDE", projectDto).setKey("MODULE_KEY").setName("Module");
@@ -355,7 +355,7 @@ public class ReportPersistSnapshotsStepTest extends BaseStepTest {
   public void set_no_period_on_snapshots_when_no_period() {
     ComponentDto projectDto = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY).setName("Project");
     dbClient.componentDao().insert(dbTester.getSession(), projectDto);
-    SnapshotDto snapshotDto = SnapshotTesting.createForProject(projectDto);
+    SnapshotDto snapshotDto = SnapshotTesting.newSnapshotForProject(projectDto);
     dbClient.snapshotDao().insert(dbTester.getSession(), snapshotDto);
     dbTester.getSession().commit();
 
index 7a32cee3485c9773113fed5453ce3c6697bcf996..bc24a015cae76935fb0027b936a53bb6b3e02815 100644 (file)
@@ -33,7 +33,7 @@ import org.sonar.db.DbClient;
 import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.ComponentTesting;
-import org.sonar.server.component.SnapshotTesting;
+import org.sonar.db.component.SnapshotTesting;
 import org.sonar.server.computation.batch.BatchReportReaderRule;
 import org.sonar.server.computation.batch.TreeRootHolderRule;
 import org.sonar.server.computation.component.Component;
@@ -247,7 +247,7 @@ public class ValidateProjectStepTest {
 
     ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY);
     dbClient.componentDao().insert(dbTester.getSession(), project);
-    dbClient.snapshotDao().insert(dbTester.getSession(), SnapshotTesting.createForProject(project).setCreatedAt(1420088400000L)); // 2015-01-01
+    dbClient.snapshotDao().insert(dbTester.getSession(), SnapshotTesting.newSnapshotForProject(project).setCreatedAt(1420088400000L)); // 2015-01-01
     dbTester.getSession().commit();
 
     treeRootHolder.setRoot(ReportComponent.builder(Component.Type.PROJECT, 1).setUuid("ABCD").setKey(PROJECT_KEY).build());
@@ -274,7 +274,7 @@ public class ValidateProjectStepTest {
 
     ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY);
     dbClient.componentDao().insert(dbTester.getSession(), project);
-    dbClient.snapshotDao().insert(dbTester.getSession(), SnapshotTesting.createForProject(project).setCreatedAt(1433131200000L)); // 2015-06-01
+    dbClient.snapshotDao().insert(dbTester.getSession(), SnapshotTesting.newSnapshotForProject(project).setCreatedAt(1433131200000L)); // 2015-06-01
     dbTester.getSession().commit();
 
     treeRootHolder.setRoot(ReportComponent.builder(Component.Type.PROJECT, 1).setUuid("ABCD").setKey(PROJECT_KEY).build());
index 90408c5570952ab61fde99f10b1abd3d2bb0c690..f498a21c0928e774ede9317f461023cba7857129 100644 (file)
@@ -46,9 +46,9 @@ import org.sonar.server.computation.period.PeriodsHolderRule;
 import org.sonar.test.DbTests;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.server.component.SnapshotTesting.createForComponent;
-import static org.sonar.server.component.SnapshotTesting.createForProject;
-import static org.sonar.server.component.SnapshotTesting.createForView;
+import static org.sonar.db.component.SnapshotTesting.createForComponent;
+import static org.sonar.db.component.SnapshotTesting.newSnapshotForProject;
+import static org.sonar.db.component.SnapshotTesting.newSnapshotForView;
 
 @Category(DbTests.class)
 public class ViewsComputeMeasureVariationsStepTest {
@@ -101,7 +101,7 @@ public class ViewsComputeMeasureVariationsStepTest {
 
   @Test
   public void do_nothing_when_no_raw_measure() {
-    SnapshotDto period1ViewSnapshot = createForView(VIEW_DTO);
+    SnapshotDto period1ViewSnapshot = newSnapshotForView(VIEW_DTO);
     dbClient.snapshotDao().insert(session, period1ViewSnapshot);
     dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.getId(), period1ViewSnapshot.getId(), 60d));
     session.commit();
@@ -129,7 +129,7 @@ public class ViewsComputeMeasureVariationsStepTest {
   @Test
   public void set_variation() {
     // View
-    SnapshotDto period1ViewSnapshot = createForView(VIEW_DTO);
+    SnapshotDto period1ViewSnapshot = newSnapshotForView(VIEW_DTO);
     dbClient.snapshotDao().insert(session, period1ViewSnapshot);
     dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.getId(), period1ViewSnapshot.getId(), 60d));
 
@@ -158,11 +158,11 @@ public class ViewsComputeMeasureVariationsStepTest {
 
   @Test
   public void set_variations_on_all_periods() {
-    SnapshotDto period1ViewSnapshot = createForProject(VIEW_DTO).setLast(false);
-    SnapshotDto period2ViewSnapshot = createForProject(VIEW_DTO).setLast(false);
-    SnapshotDto period3ViewSnapshot = createForProject(VIEW_DTO).setLast(false);
-    SnapshotDto period4ViewSnapshot = createForProject(VIEW_DTO).setLast(false);
-    SnapshotDto period5ViewSnapshot = createForProject(VIEW_DTO).setLast(false);
+    SnapshotDto period1ViewSnapshot = newSnapshotForProject(VIEW_DTO).setLast(false);
+    SnapshotDto period2ViewSnapshot = newSnapshotForProject(VIEW_DTO).setLast(false);
+    SnapshotDto period3ViewSnapshot = newSnapshotForProject(VIEW_DTO).setLast(false);
+    SnapshotDto period4ViewSnapshot = newSnapshotForProject(VIEW_DTO).setLast(false);
+    SnapshotDto period5ViewSnapshot = newSnapshotForProject(VIEW_DTO).setLast(false);
     dbClient.snapshotDao().insert(session, period1ViewSnapshot, period2ViewSnapshot, period3ViewSnapshot, period4ViewSnapshot, period5ViewSnapshot);
 
     dbClient.measureDao().insert(session,
@@ -198,7 +198,7 @@ public class ViewsComputeMeasureVariationsStepTest {
 
   @Test
   public void set_variation_on_all_numeric_metrics() {
-    SnapshotDto period1ViewSnapshot = createForProject(VIEW_DTO);
+    SnapshotDto period1ViewSnapshot = newSnapshotForProject(VIEW_DTO);
     dbClient.snapshotDao().insert(session, period1ViewSnapshot);
     dbClient.measureDao().insert(session,
       newMeasureDto(ISSUES_METRIC.getId(), VIEW_DTO.getId(), period1ViewSnapshot.getId(), 60d),
index 432f5cc877732dbe82a31d5c45da423f30f78e03..fb517d68bf21a6df284c0cfbb465dd472151c81a 100644 (file)
@@ -51,7 +51,7 @@ import static org.sonar.db.component.ComponentTesting.newProjectCopy;
 import static org.sonar.db.component.ComponentTesting.newProjectDto;
 import static org.sonar.db.component.ComponentTesting.newSubView;
 import static org.sonar.db.component.ComponentTesting.newView;
-import static org.sonar.server.component.SnapshotTesting.createForProject;
+import static org.sonar.db.component.SnapshotTesting.newSnapshotForProject;
 import static org.sonar.server.computation.component.Component.Type.PROJECT_VIEW;
 import static org.sonar.server.computation.component.Component.Type.SUBVIEW;
 import static org.sonar.server.computation.component.Component.Type.VIEW;
@@ -182,8 +182,8 @@ public class ViewsPersistSnapshotsStepTest extends BaseStepTest {
   public void persist_snapshots_with_periods() {
     ComponentDto viewDto = save(newView("ABCD").setKey(valueOf(PROJECT_KEY)).setName("Project"));
     ComponentDto subViewDto = save(newSubView(viewDto, "CDEF", "key").setKey("2"));
-    SnapshotDto viewSnapshotDto = save(createForProject(viewDto).setCreatedAt(DateUtils.parseDateQuietly("2015-01-01").getTime()));
-    SnapshotDto subViewSnapshotDto = save(createForProject(subViewDto).setCreatedAt(DateUtils.parseDateQuietly("2015-01-01").getTime()));
+    SnapshotDto viewSnapshotDto = save(newSnapshotForProject(viewDto).setCreatedAt(DateUtils.parseDateQuietly("2015-01-01").getTime()));
+    SnapshotDto subViewSnapshotDto = save(newSnapshotForProject(subViewDto).setCreatedAt(DateUtils.parseDateQuietly("2015-01-01").getTime()));
     dbTester.getSession().commit();
 
     Component subView = ViewsComponent.builder(SUBVIEW, 2).setUuid("ABCD").build();
index c68780b4fc6dec5de169ebdc4b3c6ea44e20d871..0facac5f24b64e38253225ff01d9867cc8e046d9 100644 (file)
@@ -45,7 +45,7 @@ import org.sonar.db.rule.RuleDto;
 import org.sonar.db.rule.RuleTesting;
 import org.sonar.db.user.UserDto;
 import org.sonar.db.component.ComponentTesting;
-import org.sonar.server.component.SnapshotTesting;
+import org.sonar.db.component.SnapshotTesting;
 import org.sonar.server.issue.index.IssueIndexer;
 import org.sonar.server.permission.PermissionChange;
 import org.sonar.server.permission.PermissionUpdater;
@@ -88,7 +88,7 @@ public class IssueBulkChangeServiceMediumTest {
 
     project = ComponentTesting.newProjectDto().setKey("MyProject");
     tester.get(ComponentDao.class).insert(session, project);
-    SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
+    SnapshotDto projectSnapshot = SnapshotTesting.newSnapshotForProject(project);
     tester.get(SnapshotDao.class).insert(session, projectSnapshot);
 
     file = ComponentTesting.newFileDto(project).setKey("MyComponent");
index d9f4c802d0c67623e7c37ea281ba62514e335fc6..920f3da59502d3e2bfa0d868abd3697d87f82b1b 100644 (file)
@@ -44,7 +44,7 @@ import org.sonar.db.issue.IssueDto;
 import org.sonar.db.rule.RuleDto;
 import org.sonar.db.rule.RuleTesting;
 import org.sonar.db.component.ComponentTesting;
-import org.sonar.server.component.SnapshotTesting;
+import org.sonar.db.component.SnapshotTesting;
 import org.sonar.server.issue.index.IssueIndexer;
 import org.sonar.server.permission.PermissionChange;
 import org.sonar.server.permission.PermissionUpdater;
@@ -85,7 +85,7 @@ public class IssueCommentServiceMediumTest {
 
     project = ComponentTesting.newProjectDto();
     tester.get(ComponentDao.class).insert(session, project);
-    SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
+    SnapshotDto projectSnapshot = SnapshotTesting.newSnapshotForProject(project);
     tester.get(SnapshotDao.class).insert(session, projectSnapshot);
 
     file = ComponentTesting.newFileDto(project);
index 282de27bafecd5d36cd853669529723f89a20352..71fa47a68b54d80702048b1c054bc6cd4eca7c72 100644 (file)
@@ -45,7 +45,7 @@ import org.sonar.db.measure.custom.CustomMeasureDto;
 import org.sonar.db.metric.MetricDto;
 import org.sonar.server.component.ComponentFinder;
 import org.sonar.db.component.ComponentTesting;
-import org.sonar.server.component.SnapshotTesting;
+import org.sonar.db.component.SnapshotTesting;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.es.EsTester;
 import org.sonar.server.exceptions.ForbiddenException;
@@ -208,7 +208,7 @@ public class SearchActionTest {
     dbClient.customMeasureDao().insert(dbSession, newCustomMeasure(1, metric)
       .setCreatedAt(yesterday)
       .setUpdatedAt(yesterday));
-    dbClient.snapshotDao().insert(dbSession, SnapshotTesting.createForProject(defaultProject));
+    dbClient.snapshotDao().insert(dbSession, SnapshotTesting.newSnapshotForProject(defaultProject));
     dbSession.commit();
 
     String response = newRequest()
index 71cf3db443343dc42b73803dddf89feafdfe68d5..4238a605471740c4b2c8988fe39e03180cf44c72 100644 (file)
@@ -52,7 +52,7 @@ import org.sonar.db.rule.RuleDto;
 import org.sonar.db.rule.RuleTesting;
 import org.sonar.server.component.ComponentCleanerService;
 import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.component.SnapshotTesting;
+import org.sonar.db.component.SnapshotTesting;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.es.EsTester;
 import org.sonar.server.exceptions.ForbiddenException;
@@ -226,7 +226,7 @@ public class BulkDeleteActionTest {
     dbClient.deprecatedRuleDao().insert(dbSession, rule);
     IssueDto issue = IssueTesting.newDto(rule, project, project).setKee("issue-key-" + suffix);
     dbClient.componentDao().insert(dbSession, project);
-    SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, SnapshotTesting.createForProject(project));
+    SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, SnapshotTesting.newSnapshotForProject(project));
     dbClient.issueDao().insert(dbSession, issue);
     dbSession.commit();
 
index 1a590fd3df5727225db387b8b97664980df11276..4f4bcef3f876143b3e05a8cd51f9cc3782024735 100644 (file)
@@ -50,7 +50,7 @@ import org.sonar.db.rule.RuleDto;
 import org.sonar.db.rule.RuleTesting;
 import org.sonar.server.component.ComponentCleanerService;
 import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.component.SnapshotTesting;
+import org.sonar.db.component.SnapshotTesting;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.es.EsTester;
 import org.sonar.server.exceptions.ForbiddenException;
@@ -248,7 +248,7 @@ public class DeleteActionTest {
     dbClient.deprecatedRuleDao().insert(dbSession, rule);
     IssueDto issue = IssueTesting.newDto(rule, project, project).setKee("issue-key-" + suffix);
     dbClient.componentDao().insert(dbSession, project);
-    SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, SnapshotTesting.createForProject(project));
+    SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, SnapshotTesting.newSnapshotForProject(project));
     dbClient.issueDao().insert(dbSession, issue);
     dbSession.commit();
 
index 124513278f6b28fdd3e8c35896401ef26faa59ba..0f91139b5830b9694db5940c5b595b3a1bdfbb4b 100644 (file)
@@ -35,7 +35,7 @@ import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.component.ComponentTesting;
-import org.sonar.server.component.SnapshotTesting;
+import org.sonar.db.component.SnapshotTesting;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.WsTester;
@@ -142,14 +142,14 @@ public class GhostsActionTest {
       .setName("HBase")
       .setCreatedAt(DateUtils.parseDateTime("2015-03-04T23:03:44+0100"));
     dbClient.componentDao().insert(db.getSession(), hBaseProject);
-    dbClient.snapshotDao().insert(db.getSession(), SnapshotTesting.createForProject(hBaseProject)
+    dbClient.snapshotDao().insert(db.getSession(), SnapshotTesting.newSnapshotForProject(hBaseProject)
       .setStatus(SnapshotDto.STATUS_UNPROCESSED));
     ComponentDto roslynProject = ComponentTesting.newProjectDto("c526ef20-131b-4486-9357-063fa64b5079")
       .setKey("com.microsoft.roslyn:roslyn")
       .setName("Roslyn")
       .setCreatedAt(DateUtils.parseDateTime("2013-03-04T23:03:44+0100"));
     dbClient.componentDao().insert(db.getSession(), roslynProject);
-    dbClient.snapshotDao().insert(db.getSession(), SnapshotTesting.createForProject(roslynProject)
+    dbClient.snapshotDao().insert(db.getSession(), SnapshotTesting.newSnapshotForProject(roslynProject)
       .setStatus(SnapshotDto.STATUS_UNPROCESSED));
     db.getSession().commit();
 
@@ -171,7 +171,7 @@ public class GhostsActionTest {
       .setName("ghost-name-" + id)
       .setKey("ghost-key-" + id);
     dbClient.componentDao().insert(db.getSession(), project);
-    SnapshotDto snapshot = SnapshotTesting.createForProject(project)
+    SnapshotDto snapshot = SnapshotTesting.newSnapshotForProject(project)
       .setStatus(SnapshotDto.STATUS_UNPROCESSED);
     dbClient.snapshotDao().insert(db.getSession(), snapshot);
     db.getSession().commit();
@@ -183,7 +183,7 @@ public class GhostsActionTest {
       .setName("analyzed-name-" + id)
       .setKey("analyzed-key-" + id);
     dbClient.componentDao().insert(db.getSession(), project);
-    SnapshotDto snapshot = SnapshotTesting.createForProject(project);
+    SnapshotDto snapshot = SnapshotTesting.newSnapshotForProject(project);
     dbClient.snapshotDao().insert(db.getSession(), snapshot);
     db.getSession().commit();
   }
index 18a14f58e2bd3d9a43863f797088c123a5b7398c..c0cc0420755dac3c15f171a96e6b8d30de4257b0 100644 (file)
@@ -37,7 +37,7 @@ import org.sonar.db.component.ComponentDao;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.component.ComponentTesting;
-import org.sonar.server.component.SnapshotTesting;
+import org.sonar.db.component.SnapshotTesting;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.WsTester;
@@ -74,7 +74,7 @@ public class ProvisionedActionTest {
     userSessionRule.setGlobalPermissions(GlobalPermissions.PROVISIONING);
     ComponentDto analyzedProject = ComponentTesting.newProjectDto("analyzed-uuid-1");
     componentDao.insert(db.getSession(), newProvisionedProject("1"), newProvisionedProject("2"), analyzedProject);
-    SnapshotDto snapshot = SnapshotTesting.createForProject(analyzedProject);
+    SnapshotDto snapshot = SnapshotTesting.newSnapshotForProject(analyzedProject);
     dbClient.snapshotDao().insert(db.getSession(), snapshot);
     db.getSession().commit();
 
index 1e7bc2c27155adb6281017718ee633e9ba479deb..75867abb12ebd2216d0e92aa2e8c9ec943743bda 100644 (file)
@@ -50,7 +50,7 @@ import org.sonar.db.dashboard.DashboardDto;
 import org.sonar.db.property.PropertyDto;
 import org.sonar.server.component.ComponentFinder;
 import org.sonar.db.component.ComponentTesting;
-import org.sonar.server.component.SnapshotTesting;
+import org.sonar.db.component.SnapshotTesting;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.tester.UserSessionRule;
@@ -194,7 +194,7 @@ public class ComponentNavigationActionTest {
     ComponentDto project = ComponentTesting.newProjectDto("abcd")
       .setKey("polop").setName("Polop").setLanguage("xoo");
     dbClient.componentDao().insert(dbTester.getSession(), project);
-    dbClient.snapshotDao().insert(dbTester.getSession(), SnapshotTesting.createForProject(project));
+    dbClient.snapshotDao().insert(dbTester.getSession(), SnapshotTesting.newSnapshotForProject(project));
     dbTester.getSession().commit();
 
     userSessionRule.addProjectUuidPermissions(UserRole.USER, "abcd");
@@ -208,7 +208,7 @@ public class ComponentNavigationActionTest {
     ComponentDto project = ComponentTesting.newProjectDto("abcd")
       .setKey("polop").setName("Polop").setLanguage("xoo");
     dbClient.componentDao().insert(dbTester.getSession(), project);
-    dbClient.snapshotDao().insert(dbTester.getSession(), SnapshotTesting.createForProject(project));
+    dbClient.snapshotDao().insert(dbTester.getSession(), SnapshotTesting.newSnapshotForProject(project));
     dbTester.getSession().commit();
 
     userSessionRule
@@ -354,7 +354,7 @@ public class ComponentNavigationActionTest {
       .setPath(directory.path());
     dbClient.componentDao().insert(dbTester.getSession(), project, module, directory, file);
 
-    SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
+    SnapshotDto projectSnapshot = SnapshotTesting.newSnapshotForProject(project);
     dbClient.snapshotDao().insert(dbTester.getSession(), projectSnapshot);
     SnapshotDto moduleSnapshot = SnapshotTesting.createForComponent(module, projectSnapshot);
     dbClient.snapshotDao().insert(dbTester.getSession(), moduleSnapshot);
index 9619946373104f9db579af34b1bcbea72cbde145..4f4a9cc49cac16f5b14a768830bbf2b885b474e3 100644 (file)
@@ -66,6 +66,14 @@ public class ComponentDao implements Dao {
     return componentDto.get();
   }
 
+  public List<ComponentDto> selectByQuery(DbSession session, ComponentQuery query, int offset, int limit) {
+    return mapper(session).selectByQuery(query, new RowBounds(offset, limit));
+  }
+
+  public int countByQuery(DbSession session, ComponentQuery query) {
+    return mapper(session).countByQuery(query);
+  }
+
   public boolean existsById(Long id, DbSession session) {
     return mapper(session).countById(id) > 0;
   }
@@ -186,7 +194,7 @@ public class ComponentDao implements Dao {
    * Does not return component copies
    */
   public List<ComponentDto> selectComponents(DbSession session, Collection<String> qualifiers, int offset, int limit, @Nullable String query) {
-    Map<String, Object> parameters = newHashMapWithExpectedSize(2);
+    Map<String, Object> parameters = newHashMapWithExpectedSize(3);
     addProjectQualifier(parameters);
     addPartialQueryParameterIfNotNull(parameters, query);
     addQualifiers(parameters, qualifiers);
index dc2ab91b60b33891726f1546c8ad34f60f6bedbc..774c14a378daf6276c90924886bd8aa1bad91ef4 100644 (file)
@@ -57,6 +57,10 @@ public interface ComponentMapper {
 
   List<String> selectExistingUuids(@Param("uuids") Collection<String> uuids);
 
+  List<ComponentDto> selectByQuery(ComponentQuery query, RowBounds rowBounds);
+
+  int countByQuery(ComponentQuery query);
+
   /**
    * Return all project (PRJ/TRK) uuids
    */
@@ -127,5 +131,4 @@ public interface ComponentMapper {
   void update(ComponentDto componentDto);
 
   void delete(long componentId);
-
 }
diff --git a/sonar-db/src/main/java/org/sonar/db/component/ComponentQuery.java b/sonar-db/src/main/java/org/sonar/db/component/ComponentQuery.java
new file mode 100644 (file)
index 0000000..6c4e361
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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.db.component;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import org.sonar.db.Database;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.sonar.db.dialect.WildcardPosition.AFTER;
+
+public class ComponentQuery {
+  private final Database database;
+  private final String nameOrKeyQuery;
+  private final String[] qualifiers;
+
+  public ComponentQuery(Database database, @Nullable String nameOrKeyQuery, String... qualifiers) {
+    checkArgument(qualifiers.length > 0, "At least one qualifier must be provided");
+
+    this.database = database;
+    this.nameOrKeyQuery = nameOrKeyQuery;
+    this.qualifiers = qualifiers;
+  }
+
+  public String[] getQualifiers() {
+    return qualifiers;
+  }
+
+  @CheckForNull
+  public String getNameOrKeyQuery() {
+    return nameOrKeyQuery;
+  }
+
+  @CheckForNull
+  public String getNameOrKeyQueryToSqlForResourceIndex() {
+    return database.getDialect().buildLikeValue(nameOrKeyQuery, AFTER).toLowerCase();
+  }
+
+  @CheckForNull
+  public String getNameOrKeyQueryToSqlForProjectKey() {
+    return database.getDialect().buildLikeValue(nameOrKeyQuery, AFTER);
+  }
+}
index 236c90acd1b0253ce775f6252afaab5468413f7f..5aeb289f4954c7d490b5105d35c0c45a22019489 100644 (file)
@@ -87,4 +87,44 @@ abstract class AbstractDialect implements Dialect {
   public int getScrollSingleRowFetchSize() {
     return 1;
   }
+
+  @Override
+  public String buildLikeValue(String value, WildcardPosition wildcardPosition) {
+    String escapedValue = escapePercentAndUnderscore(value);
+    String wildcard = "%";
+    switch (wildcardPosition) {
+      case BEFORE:
+        escapedValue = wildcard + escapedValue;
+        break;
+      case AFTER:
+        escapedValue += wildcard;
+        break;
+      case BEFORE_AND_AFTER:
+        escapedValue = wildcard + escapedValue + wildcard;
+        break;
+      default:
+        throw new UnsupportedOperationException("Unhandled WildcardPosition: " + wildcardPosition);
+    }
+
+    return appendEscapeBackslachForSomeDb(escapedValue);
+  }
+
+  /**
+   * Replace escape percent and underscore by adding a slash just before
+   */
+  private static String escapePercentAndUnderscore(String value) {
+    return value
+      .replaceAll("%", "\\\\%")
+      .replaceAll("_", "\\\\_");
+  }
+
+  private String appendEscapeBackslachForSomeDb(String value) {
+    return isOracleOrMsSql()
+      ? (value + " ESCAPE '\\'")
+      : value;
+  }
+
+  private boolean isOracleOrMsSql() {
+    return getId().equals(Oracle.ID) || getId().equals(MsSql.ID);
+  }
 }
index 3d0a0f6e730145c2eface2de092815947a1b6a86..a6fba169d91dfb4c7657042a6b8d60857293b173 100644 (file)
@@ -89,4 +89,10 @@ public interface Dialect {
    * @return a boolean
    */
   boolean supportsMigration();
+
+  /**
+   * Returns an escaped value in parameter, with the desired wildcards.
+   * Suitable to be used in a like sql query
+   */
+  String buildLikeValue(String value, WildcardPosition wildcardPosition);
 }
diff --git a/sonar-db/src/main/java/org/sonar/db/dialect/WildcardPosition.java b/sonar-db/src/main/java/org/sonar/db/dialect/WildcardPosition.java
new file mode 100644 (file)
index 0000000..0b8780b
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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.db.dialect;
+
+public enum WildcardPosition {
+  BEFORE, AFTER, BEFORE_AND_AFTER
+}
index da674300494a26a7596f77576739c88c55edad6d..8d846a61e39cb061bd498b178d5b075197aaf6bb 100644 (file)
     ORDER BY UPPER(p.name), p.name
   </select>
 
+  <select id="selectByQuery" resultType="Component">
+    select
+    <include refid="componentColumns"/>
+    <include refid="sqlSelectByQuery"/>
+    ORDER BY LOWER(p.name), p.name
+  </select>
+
+  <select id="countByQuery" resultType="int">
+    select count(p.id)
+    <include refid="sqlSelectByQuery"/>
+  </select>
+
+  <sql id="sqlSelectByQuery">
+    from projects p
+    <where>
+      AND p.enabled=${_true}
+      AND p.copy_resource_id is null
+      AND p.qualifier in
+      <foreach collection="qualifiers" item="qualifier" open="(" close=")" separator=",">
+        #{qualifier}
+      </foreach>
+      <if test="nameOrKeyQuery!=null">
+        AND (exists (
+        select 1
+        from resource_index ri
+        where
+        ri.resource_id=p.id
+        AND ri.qualifier in
+        <foreach collection="qualifiers" item="qualifier" open="(" close=")" separator=",">
+          #{qualifier}
+        </foreach>
+        AND ri.kee like #{nameOrKeyQueryToSqlForResourceIndex})
+        OR p.kee like #{nameOrKeyQueryToSqlForProjectKey})
+      </if>
+    </where>
+  </sql>
+
   <select id="countRootComponents" resultType="int">
     select count(p.id)
     from projects p
index f7125fd1d34ffebd042071482a87b849b02dc5a5..0ca8782056fa0f79cef56353cb9ea862a6af16b9 100644 (file)
@@ -51,6 +51,7 @@ public class ComponentDaoTest {
 
   @Rule
   public DbTester db = DbTester.create(System2.INSTANCE);
+  ComponentDbTester componentDb = new ComponentDbTester(db);
 
   DbSession dbSession = db.getSession();
 
@@ -59,7 +60,7 @@ public class ComponentDaoTest {
   @Test
   public void get_by_uuid() {
     db.prepareDbUnit(getClass(), "shared.xml");
-    
+
     ComponentDto result = underTest.selectByUuid(dbSession, "KLMN").get();
     assertThat(result).isNotNull();
     assertThat(result.uuid()).isEqualTo("KLMN");
@@ -612,8 +613,8 @@ public class ComponentDaoTest {
 
   @Test
   public void delete() throws Exception {
-    ComponentDto project1= insertProject(newProjectDto().setKey("PROJECT_1"));
-    insertProject(newProjectDto().setKey("PROJECT_2"));
+    ComponentDto project1 = componentDb.insertComponent(newProjectDto().setKey("PROJECT_1"));
+    componentDb.insertComponent(newProjectDto().setKey("PROJECT_2"));
 
     underTest.delete(dbSession, project1.getId());
     dbSession.commit();
@@ -624,23 +625,62 @@ public class ComponentDaoTest {
 
   @Test
   public void select_components_with_paging_query_and_qualifiers() {
-    DbSession session = dbSession;
-    underTest.insert(session, newProjectDto().setName("aaaa-name"));
-    underTest.insert(session, newView());
-    underTest.insert(session, newDeveloper("project-name"));
+    underTest.insert(dbSession, newProjectDto().setName("aaaa-name"));
+    underTest.insert(dbSession, newView());
+    underTest.insert(dbSession, newDeveloper("project-name"));
     for (int i = 9; i >= 1; i--) {
-      underTest.insert(session, newProjectDto().setName("project-" + i));
+      underTest.insert(dbSession, newProjectDto().setName("project-" + i));
     }
 
-    List<ComponentDto> result = underTest.selectComponents(session, singleton(Qualifiers.PROJECT), 1, 3, "project");
+    List<ComponentDto> result = underTest.selectComponents(dbSession, singleton(Qualifiers.PROJECT), 1, 3, "project");
 
     assertThat(result).hasSize(3);
     assertThat(result).extracting("name").containsExactly("project-2", "project-3", "project-4");
   }
 
-  private ComponentDto insertProject(ComponentDto project) {
-    underTest.insert(dbSession, project);
-    dbSession.commit();
-    return project;
+  @Test
+  public void select_by_query_with_paging_query_and_qualifiers() {
+    componentDb.insertProjectAndSnapshot(dbSession, newProjectDto().setName("aaaa-name"));
+    componentDb.insertProjectAndSnapshot(dbSession, newView());
+    componentDb.insertProjectAndSnapshot(dbSession, newDeveloper("project-name"));
+    for (int i = 9; i >= 1; i--) {
+      componentDb.insertProjectAndSnapshot(dbSession, newProjectDto().setName("project-" + i));
+    }
+    db.commit();
+    componentDb.indexProjects();
+
+    ComponentQuery query = new ComponentQuery(db.database(), "oJect", Qualifiers.PROJECT);
+    List<ComponentDto> result = underTest.selectByQuery(dbSession, query, 1, 3);
+
+    assertThat(result).hasSize(3);
+    assertThat(underTest.countByQuery(dbSession, query)).isEqualTo(9);
+    assertThat(result).extracting("name").containsExactly("project-2", "project-3", "project-4");
+  }
+
+  @Test
+  public void select_by_query_name_with_special_characters() {
+    componentDb.insertProjectAndSnapshot(dbSession, newProjectDto().setName("project-_%-name"));
+    db.commit();
+    componentDb.indexProjects();
+
+    ComponentQuery query = new ComponentQuery(db.database(), "-_%-", Qualifiers.PROJECT);
+    List<ComponentDto> result = underTest.selectByQuery(dbSession, query, 0, 10);
+
+    assertThat(result).hasSize(1);
+    assertThat(result.get(0).name()).isEqualTo("project-_%-name");
+  }
+
+  @Test
+  public void select_by_query_key_with_special_characters() {
+    componentDb.insertProjectAndSnapshot(dbSession, newProjectDto()
+      .setKey("project-_%-key"));
+    db.commit();
+    componentDb.indexProjects();
+
+    ComponentQuery query = new ComponentQuery(db.database(), "project-_%-", Qualifiers.PROJECT);
+    List<ComponentDto> result = underTest.selectByQuery(dbSession, query, 0, 10);
+
+    assertThat(result).hasSize(1);
+    assertThat(result.get(0).key()).isEqualTo("project-_%-key");
   }
 }
diff --git a/sonar-db/src/test/java/org/sonar/db/component/ComponentDbTester.java b/sonar-db/src/test/java/org/sonar/db/component/ComponentDbTester.java
new file mode 100644 (file)
index 0000000..731a05a
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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.db.component;
+
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+
+import static org.sonar.db.component.SnapshotTesting.newSnapshotForProject;
+
+public class ComponentDbTester {
+  private final DbTester db;
+  private final DbClient dbClient;
+  private final DbSession dbSession;
+
+  public ComponentDbTester(DbTester db) {
+    this.db = db;
+    this.dbClient = db.getDbClient();
+    this.dbSession = db.getSession();
+  }
+
+  public void insertProjectAndSnapshot(DbSession dbSession, ComponentDto component) {
+    dbClient.componentDao().insert(dbSession, component);
+    dbClient.snapshotDao().insert(dbSession, newSnapshotForProject(component));
+  }
+
+  public ComponentDto insertComponent(ComponentDto component) {
+    dbClient.componentDao().insert(dbSession, component);
+    return component;
+  }
+
+  public void indexProjects() {
+    dbClient.componentIndexDao().indexProjects();
+    db.commit();
+  }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/component/SnapshotTesting.java b/sonar-db/src/test/java/org/sonar/db/component/SnapshotTesting.java
new file mode 100644 (file)
index 0000000..10c3eb0
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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.db.component;
+
+import com.google.common.base.Preconditions;
+import org.assertj.core.util.Strings;
+
+public class SnapshotTesting {
+
+  /**
+   * Can be used for modules and files
+   */
+  public static SnapshotDto createForComponent(ComponentDto component, SnapshotDto parentSnapshot) {
+    Preconditions.checkNotNull(parentSnapshot.getId(), "The parent snapshot need to be persisted before creating this snapshot");
+    Long parentRootId = parentSnapshot.getRootId();
+    return createBasicSnapshot(component, parentSnapshot.getRootProjectId())
+      .setRootId(parentRootId != null ? parentRootId : parentSnapshot.getId())
+      .setParentId(parentSnapshot.getId())
+      .setPath(Strings.isNullOrEmpty(parentSnapshot.getPath()) ? Long.toString(parentSnapshot.getId()) + "." : parentSnapshot.getPath() + Long.toString(parentSnapshot.getId()) + ".");
+  }
+
+  public static SnapshotDto newSnapshotForProject(ComponentDto project) {
+    return createBasicSnapshot(project, project.getId())
+        .setPath("");
+  }
+
+  public static SnapshotDto newSnapshotForView(ComponentDto view) {
+    return createBasicSnapshot(view, view.getId())
+        .setPath("");
+  }
+
+  private static SnapshotDto createBasicSnapshot(ComponentDto component, Long rootProjectId) {
+    Preconditions.checkNotNull(component.getId(), "The project need to be persisted before creating this snapshot");
+    Preconditions.checkNotNull(rootProjectId, "Root project id is null");
+    return new SnapshotDto()
+      .setComponentId(component.getId())
+      .setRootProjectId(rootProjectId)
+      .setStatus(SnapshotDto.STATUS_PROCESSED)
+      .setQualifier(component.qualifier())
+      .setScope(component.scope())
+      .setCreatedAt(System.currentTimeMillis())
+      .setBuildDate(System.currentTimeMillis())
+      .setLast(true);
+  }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/dialect/DialectTest.java b/sonar-db/src/test/java/org/sonar/db/dialect/DialectTest.java
new file mode 100644 (file)
index 0000000..c20b8cc
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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.db.dialect;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.db.dialect.WildcardPosition.AFTER;
+import static org.sonar.db.dialect.WildcardPosition.BEFORE;
+import static org.sonar.db.dialect.WildcardPosition.BEFORE_AND_AFTER;
+
+public class DialectTest {
+
+  Dialect underTest = new H2();
+
+  @Test
+  public void buildLikeValue_with_H2() {
+    String escapedValue = "like-\\_\\%-value";
+    String wildcard = "%";
+
+    assertThat(underTest.buildLikeValue("like-_%-value", BEFORE)).isEqualTo(wildcard + escapedValue);
+    assertThat(underTest.buildLikeValue("like-_%-value", AFTER)).isEqualTo(escapedValue + wildcard);
+    assertThat(underTest.buildLikeValue("like-_%-value", BEFORE_AND_AFTER)).isEqualTo(wildcard + escapedValue + wildcard);
+  }
+
+  @Test
+  public void buildLikeValue_with_Oracle() {
+    underTest = new Oracle();
+    String escapedValue = "like-\\_\\%-value";
+    String wildcard = "%";
+
+    assertThat(underTest.buildLikeValue("like-_%-value", BEFORE_AND_AFTER)).isEqualTo(wildcard + escapedValue + wildcard + " ESCAPE '\\'");
+
+  }
+}