diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2015-09-25 17:19:28 +0200 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2015-09-29 08:39:14 +0200 |
commit | 99374f79d07f74e433104df73cc3717284b8ac02 (patch) | |
tree | a805dc6cc6977d0a0db631c96facb1bbb2e27054 /sonar-db/src | |
parent | cdcc70c8fe05b3d7add42e88014ff0f558426f70 (diff) | |
download | sonarqube-99374f79d07f74e433104df73cc3717284b8ac02.tar.gz sonarqube-99374f79d07f74e433104df73cc3717284b8ac02.zip |
SONAR-6332 Prevent provisioning projects with same key on MySQL
Diffstat (limited to 'sonar-db/src')
8 files changed, 269 insertions, 160 deletions
diff --git a/sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java b/sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java index 47c6575f459..96199463731 100644 --- a/sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java +++ b/sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java @@ -135,6 +135,10 @@ public class ComponentDao implements Dao { return executeLargeInputs(keys, new KeyToDto(mapper(session))); } + public List<ComponentDto> selectComponentsHavingSameKeyOrderedById(DbSession session, String key) { + return mapper(session).selectComponentsHavingSameKeyOrderedById(key); + } + private static class KeyToDto implements Function<List<String>, List<ComponentDto>> { private final ComponentMapper mapper; @@ -271,6 +275,10 @@ public class ComponentDao implements Dao { mapper(session).update(item); } + public void delete(DbSession session, long componentId) { + mapper(session).delete(componentId); + } + private ComponentMapper mapper(DbSession session) { return session.getMapper(ComponentMapper.class); } diff --git a/sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java b/sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java index 1fcdb3d1a7f..dc2ab91b60b 100644 --- a/sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java +++ b/sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java @@ -118,10 +118,14 @@ public interface ComponentMapper { List<ComponentDto> selectGhostProjects(Map<String, Object> parameters, RowBounds rowBounds); + List<ComponentDto> selectComponentsHavingSameKeyOrderedById(String key); + long countGhostProjects(Map<String, Object> parameters); void insert(ComponentDto componentDto); void update(ComponentDto componentDto); + void delete(long componentId); + } diff --git a/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml b/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml index 8087982763e..bcfcbeac7b4 100644 --- a/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml +++ b/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml @@ -52,6 +52,15 @@ </where> </select> + <select id="selectComponentsHavingSameKeyOrderedById" parameterType="String" resultType="Component"> + SELECT id + FROM projects p + <where> + AND p.kee=#{key} + </where> + ORDER BY p.id ASC + </select> + <select id="selectById" parameterType="long" resultType="Component"> SELECT <include refid="componentColumns"/> @@ -362,7 +371,7 @@ #{createdAt,jdbcType=TIMESTAMP}, #{authorizationUpdatedAt,jdbcType=BIGINT}) </insert> - <insert id="update" parameterType="Component" useGeneratedKeys="false"> + <update id="update" parameterType="Component" useGeneratedKeys="false"> UPDATE projects SET kee=#{kee,jdbcType=VARCHAR}, deprecated_kee=#{deprecatedKey,jdbcType=VARCHAR}, @@ -381,6 +390,10 @@ enabled=#{enabled,jdbcType=BOOLEAN}, authorization_updated_at=#{authorizationUpdatedAt,jdbcType=BIGINT} WHERE uuid=#{uuid} - </insert> + </update> + + <delete id="delete" parameterType="long"> + DELETE FROM projects WHERE id=#{id} + </delete> </mapper> diff --git a/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java b/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java index 8bc9f827393..1343b4d0b0d 100644 --- a/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java +++ b/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java @@ -52,13 +52,15 @@ public class ComponentDaoTest { @Rule public DbTester db = DbTester.create(System2.INSTANCE); + DbSession dbSession = db.getSession(); + ComponentDao underTest = new ComponentDao(); @Test public void get_by_uuid() { db.prepareDbUnit(getClass(), "shared.xml"); - - ComponentDto result = underTest.selectByUuid(db.getSession(), "KLMN").get(); + + ComponentDto result = underTest.selectByUuid(dbSession, "KLMN").get(); assertThat(result).isNotNull(); assertThat(result.uuid()).isEqualTo("KLMN"); assertThat(result.moduleUuid()).isEqualTo("EFGH"); @@ -74,14 +76,14 @@ public class ComponentDaoTest { assertThat(result.language()).isEqualTo("java"); assertThat(result.getCopyResourceId()).isNull(); - assertThat(underTest.selectByUuid(db.getSession(), "UNKNOWN")).isAbsent(); + assertThat(underTest.selectByUuid(dbSession, "UNKNOWN")).isAbsent(); } @Test public void get_by_uuid_on_technical_project_copy() { db.prepareDbUnit(getClass(), "shared.xml"); - ComponentDto result = underTest.selectByUuid(db.getSession(), "STUV").get(); + ComponentDto result = underTest.selectByUuid(dbSession, "STUV").get(); assertThat(result).isNotNull(); assertThat(result.uuid()).isEqualTo("STUV"); assertThat(result.moduleUuid()).isEqualTo("OPQR"); @@ -102,7 +104,7 @@ public class ComponentDaoTest { public void get_by_uuid_on_disabled_component() { db.prepareDbUnit(getClass(), "shared.xml"); - ComponentDto result = underTest.selectByUuid(db.getSession(), "DCBA").get(); + ComponentDto result = underTest.selectByUuid(dbSession, "DCBA").get(); assertThat(result).isNotNull(); assertThat(result.isEnabled()).isFalse(); } @@ -113,14 +115,14 @@ public class ComponentDaoTest { db.prepareDbUnit(getClass(), "shared.xml"); - underTest.selectOrFailByUuid(db.getSession(), "unknown"); + underTest.selectOrFailByUuid(dbSession, "unknown"); } @Test public void get_by_key() { db.prepareDbUnit(getClass(), "shared.xml"); - Optional<ComponentDto> optional = underTest.selectByKey(db.getSession(), "org.struts:struts-core:src/org/struts/RequestContext.java"); + Optional<ComponentDto> optional = underTest.selectByKey(dbSession, "org.struts:struts-core:src/org/struts/RequestContext.java"); assertThat(optional).isPresent(); ComponentDto result = optional.get(); @@ -133,7 +135,7 @@ public class ComponentDaoTest { assertThat(result.language()).isEqualTo("java"); assertThat(result.parentProjectId()).isEqualTo(2); - assertThat(underTest.selectByKey(db.getSession(), "unknown")).isAbsent(); + assertThat(underTest.selectByKey(dbSession, "unknown")).isAbsent(); } @Test @@ -142,14 +144,14 @@ public class ComponentDaoTest { db.prepareDbUnit(getClass(), "shared.xml"); - underTest.selectOrFailByKey(db.getSession(), "unknown"); + underTest.selectOrFailByKey(dbSession, "unknown"); } @Test public void get_by_key_on_disabled_component() { db.prepareDbUnit(getClass(), "shared.xml"); - ComponentDto result = underTest.selectOrFailByKey(db.getSession(), "org.disabled.project"); + ComponentDto result = underTest.selectOrFailByKey(dbSession, "org.disabled.project"); assertThat(result.isEnabled()).isFalse(); } @@ -157,7 +159,7 @@ public class ComponentDaoTest { public void get_by_key_on_a_root_project() { db.prepareDbUnit(getClass(), "shared.xml"); - ComponentDto result = underTest.selectOrFailByKey(db.getSession(), "org.struts:struts"); + ComponentDto result = underTest.selectOrFailByKey(dbSession, "org.struts:struts"); assertThat(result.key()).isEqualTo("org.struts:struts"); assertThat(result.deprecatedKey()).isEqualTo("org.struts:struts"); assertThat(result.path()).isNull(); @@ -175,7 +177,7 @@ public class ComponentDaoTest { public void get_by_keys() { db.prepareDbUnit(getClass(), "shared.xml"); - List<ComponentDto> results = underTest.selectByKeys(db.getSession(), Collections.singletonList("org.struts:struts-core:src/org/struts/RequestContext.java")); + List<ComponentDto> results = underTest.selectByKeys(dbSession, Collections.singletonList("org.struts:struts-core:src/org/struts/RequestContext.java")); assertThat(results).hasSize(1); ComponentDto result = results.get(0); @@ -189,14 +191,14 @@ public class ComponentDaoTest { assertThat(result.language()).isEqualTo("java"); assertThat(result.parentProjectId()).isEqualTo(2); - assertThat(underTest.selectByKeys(db.getSession(), Collections.singletonList("unknown"))).isEmpty(); + assertThat(underTest.selectByKeys(dbSession, Collections.singletonList("unknown"))).isEmpty(); } @Test public void get_by_ids() { db.prepareDbUnit(getClass(), "shared.xml"); - List<ComponentDto> results = underTest.selectByIds(db.getSession(), newArrayList(4L)); + List<ComponentDto> results = underTest.selectByIds(dbSession, newArrayList(4L)); assertThat(results).hasSize(1); ComponentDto result = results.get(0); @@ -210,14 +212,14 @@ public class ComponentDaoTest { assertThat(result.language()).isEqualTo("java"); assertThat(result.parentProjectId()).isEqualTo(2); - assertThat(underTest.selectByIds(db.getSession(), newArrayList(555L))).isEmpty(); + assertThat(underTest.selectByIds(dbSession, newArrayList(555L))).isEmpty(); } @Test public void get_by_uuids() { db.prepareDbUnit(getClass(), "shared.xml"); - List<ComponentDto> results = underTest.selectByUuids(db.getSession(), newArrayList("KLMN")); + List<ComponentDto> results = underTest.selectByUuids(dbSession, newArrayList("KLMN")); assertThat(results).hasSize(1); ComponentDto result = results.get(0); @@ -235,14 +237,14 @@ public class ComponentDaoTest { assertThat(result.scope()).isEqualTo("FIL"); assertThat(result.language()).isEqualTo("java"); - assertThat(underTest.selectByUuids(db.getSession(), newArrayList("unknown"))).isEmpty(); + assertThat(underTest.selectByUuids(dbSession, newArrayList("unknown"))).isEmpty(); } @Test public void get_by_uuids_on_removed_components() { db.prepareDbUnit(getClass(), "shared.xml"); - List<ComponentDto> results = underTest.selectByUuids(db.getSession(), newArrayList("DCBA")); + List<ComponentDto> results = underTest.selectByUuids(dbSession, newArrayList("DCBA")); assertThat(results).hasSize(1); ComponentDto result = results.get(0); @@ -254,25 +256,25 @@ public class ComponentDaoTest { public void select_existing_uuids() { db.prepareDbUnit(getClass(), "shared.xml"); - List<String> results = underTest.selectExistingUuids(db.getSession(), newArrayList("KLMN")); + List<String> results = underTest.selectExistingUuids(dbSession, newArrayList("KLMN")); assertThat(results).containsOnly("KLMN"); - assertThat(underTest.selectExistingUuids(db.getSession(), newArrayList("KLMN", "unknown"))).hasSize(1); - assertThat(underTest.selectExistingUuids(db.getSession(), newArrayList("unknown"))).isEmpty(); + assertThat(underTest.selectExistingUuids(dbSession, newArrayList("KLMN", "unknown"))).hasSize(1); + assertThat(underTest.selectExistingUuids(dbSession, newArrayList("unknown"))).isEmpty(); } @Test public void get_by_id() { db.prepareDbUnit(getClass(), "shared.xml"); - assertThat(underTest.selectOrFailById(db.getSession(), 4L)).isNotNull(); + assertThat(underTest.selectOrFailById(dbSession, 4L)).isNotNull(); } @Test public void get_by_id_on_disabled_component() { db.prepareDbUnit(getClass(), "shared.xml"); - Optional<ComponentDto> result = underTest.selectById(db.getSession(), 10L); + Optional<ComponentDto> result = underTest.selectById(dbSession, 10L); assertThat(result).isPresent(); assertThat(result.get().isEnabled()).isFalse(); } @@ -281,23 +283,23 @@ public class ComponentDaoTest { public void fail_to_get_by_id_when_project_not_found() { db.prepareDbUnit(getClass(), "shared.xml"); - underTest.selectOrFailById(db.getSession(), 111L); + underTest.selectOrFailById(dbSession, 111L); } @Test public void get_nullable_by_id() { db.prepareDbUnit(getClass(), "shared.xml"); - assertThat(underTest.selectById(db.getSession(), 4L)).isPresent(); - assertThat(underTest.selectById(db.getSession(), 111L)).isAbsent(); + assertThat(underTest.selectById(dbSession, 4L)).isPresent(); + assertThat(underTest.selectById(dbSession, 111L)).isAbsent(); } @Test public void count_by_id() { db.prepareDbUnit(getClass(), "shared.xml"); - assertThat(underTest.existsById(4L, db.getSession())).isTrue(); - assertThat(underTest.existsById(111L, db.getSession())).isFalse(); + assertThat(underTest.existsById(4L, dbSession)).isTrue(); + assertThat(underTest.existsById(111L, dbSession)).isFalse(); } @Test @@ -305,34 +307,34 @@ public class ComponentDaoTest { db.prepareDbUnit(getClass(), "multi-modules.xml"); // Sub project of a file - List<ComponentDto> results = underTest.selectSubProjectsByComponentUuids(db.getSession(), newArrayList("HIJK")); + List<ComponentDto> results = underTest.selectSubProjectsByComponentUuids(dbSession, newArrayList("HIJK")); assertThat(results).hasSize(1); assertThat(results.get(0).getKey()).isEqualTo("org.struts:struts-data"); // Sub project of a directory - results = underTest.selectSubProjectsByComponentUuids(db.getSession(), newArrayList("GHIJ")); + results = underTest.selectSubProjectsByComponentUuids(dbSession, newArrayList("GHIJ")); assertThat(results).hasSize(1); assertThat(results.get(0).getKey()).isEqualTo("org.struts:struts-data"); // Sub project of a sub module - results = underTest.selectSubProjectsByComponentUuids(db.getSession(), newArrayList("FGHI")); + results = underTest.selectSubProjectsByComponentUuids(dbSession, newArrayList("FGHI")); assertThat(results).hasSize(1); assertThat(results.get(0).getKey()).isEqualTo("org.struts:struts"); // Sub project of a module - results = underTest.selectSubProjectsByComponentUuids(db.getSession(), newArrayList("EFGH")); + results = underTest.selectSubProjectsByComponentUuids(dbSession, newArrayList("EFGH")); assertThat(results).hasSize(1); assertThat(results.get(0).getKey()).isEqualTo("org.struts:struts"); // Sub project of a project - assertThat(underTest.selectSubProjectsByComponentUuids(db.getSession(), newArrayList("ABCD"))).isEmpty(); + assertThat(underTest.selectSubProjectsByComponentUuids(dbSession, newArrayList("ABCD"))).isEmpty(); // SUb projects of a component and a sub module - assertThat(underTest.selectSubProjectsByComponentUuids(db.getSession(), newArrayList("HIJK", "FGHI"))).hasSize(2); + assertThat(underTest.selectSubProjectsByComponentUuids(dbSession, newArrayList("HIJK", "FGHI"))).hasSize(2); - assertThat(underTest.selectSubProjectsByComponentUuids(db.getSession(), newArrayList("unknown"))).isEmpty(); + assertThat(underTest.selectSubProjectsByComponentUuids(dbSession, newArrayList("unknown"))).isEmpty(); - assertThat(underTest.selectSubProjectsByComponentUuids(db.getSession(), Collections.<String>emptyList())).isEmpty(); + assertThat(underTest.selectSubProjectsByComponentUuids(dbSession, Collections.<String>emptyList())).isEmpty(); } @Test @@ -340,20 +342,20 @@ public class ComponentDaoTest { db.prepareDbUnit(getClass(), "multi-modules.xml"); // From root project - List<ComponentDto> modules = underTest.selectEnabledDescendantModules(db.getSession(), "ABCD"); + List<ComponentDto> modules = underTest.selectEnabledDescendantModules(dbSession, "ABCD"); assertThat(modules).extracting("uuid").containsOnly("ABCD", "EFGH", "FGHI"); // From module - modules = underTest.selectEnabledDescendantModules(db.getSession(), "EFGH"); + modules = underTest.selectEnabledDescendantModules(dbSession, "EFGH"); assertThat(modules).extracting("uuid").containsOnly("EFGH", "FGHI"); // From sub module - modules = underTest.selectEnabledDescendantModules(db.getSession(), "FGHI"); + modules = underTest.selectEnabledDescendantModules(dbSession, "FGHI"); assertThat(modules).extracting("uuid").containsOnly("FGHI"); // Folder - assertThat(underTest.selectEnabledDescendantModules(db.getSession(), "GHIJ")).isEmpty(); - assertThat(underTest.selectEnabledDescendantModules(db.getSession(), "unknown")).isEmpty(); + assertThat(underTest.selectEnabledDescendantModules(dbSession, "GHIJ")).isEmpty(); + assertThat(underTest.selectEnabledDescendantModules(dbSession, "unknown")).isEmpty(); } @Test @@ -361,15 +363,15 @@ public class ComponentDaoTest { db.prepareDbUnit(getClass(), "multi-modules.xml"); // From root project, disabled sub module is returned - List<ComponentDto> modules = underTest.selectDescendantModules(db.getSession(), "ABCD"); + List<ComponentDto> modules = underTest.selectDescendantModules(dbSession, "ABCD"); assertThat(modules).extracting("uuid").containsOnly("ABCD", "EFGH", "FGHI", "IHGF"); // From module, disabled sub module is returned - modules = underTest.selectDescendantModules(db.getSession(), "EFGH"); + modules = underTest.selectDescendantModules(dbSession, "EFGH"); assertThat(modules).extracting("uuid").containsOnly("EFGH", "FGHI", "IHGF"); // From removed sub module -> should not be returned - assertThat(underTest.selectDescendantModules(db.getSession(), "IHGF")).isEmpty(); + assertThat(underTest.selectDescendantModules(dbSession, "IHGF")).isEmpty(); } @Test @@ -377,30 +379,30 @@ public class ComponentDaoTest { db.prepareDbUnit(getClass(), "select_module_files_tree.xml"); // From root project - List<FilePathWithHashDto> files = underTest.selectEnabledDescendantFiles(db.getSession(), "ABCD"); + List<FilePathWithHashDto> files = underTest.selectEnabledDescendantFiles(dbSession, "ABCD"); assertThat(files).extracting("uuid").containsOnly("EFGHI", "HIJK"); assertThat(files).extracting("moduleUuid").containsOnly("EFGH", "FGHI"); assertThat(files).extracting("srcHash").containsOnly("srcEFGHI", "srcHIJK"); assertThat(files).extracting("path").containsOnly("src/org/struts/pom.xml", "src/org/struts/RequestContext.java"); // From module - files = underTest.selectEnabledDescendantFiles(db.getSession(), "EFGH"); + files = underTest.selectEnabledDescendantFiles(dbSession, "EFGH"); assertThat(files).extracting("uuid").containsOnly("EFGHI", "HIJK"); assertThat(files).extracting("moduleUuid").containsOnly("EFGH", "FGHI"); assertThat(files).extracting("srcHash").containsOnly("srcEFGHI", "srcHIJK"); assertThat(files).extracting("path").containsOnly("src/org/struts/pom.xml", "src/org/struts/RequestContext.java"); // From sub module - files = underTest.selectEnabledDescendantFiles(db.getSession(), "FGHI"); + files = underTest.selectEnabledDescendantFiles(dbSession, "FGHI"); assertThat(files).extracting("uuid").containsOnly("HIJK"); assertThat(files).extracting("moduleUuid").containsOnly("FGHI"); assertThat(files).extracting("srcHash").containsOnly("srcHIJK"); assertThat(files).extracting("path").containsOnly("src/org/struts/RequestContext.java"); // From directory - assertThat(underTest.selectEnabledDescendantFiles(db.getSession(), "GHIJ")).isEmpty(); + assertThat(underTest.selectEnabledDescendantFiles(dbSession, "GHIJ")).isEmpty(); - assertThat(underTest.selectEnabledDescendantFiles(db.getSession(), "unknown")).isEmpty(); + assertThat(underTest.selectEnabledDescendantFiles(dbSession, "unknown")).isEmpty(); } @Test @@ -408,69 +410,69 @@ public class ComponentDaoTest { db.prepareDbUnit(getClass(), "select_module_files_tree.xml"); // From root project - List<FilePathWithHashDto> files = underTest.selectEnabledFilesFromProject(db.getSession(), "ABCD"); + List<FilePathWithHashDto> files = underTest.selectEnabledFilesFromProject(dbSession, "ABCD"); assertThat(files).extracting("uuid").containsOnly("EFGHI", "HIJK"); assertThat(files).extracting("moduleUuid").containsOnly("EFGH", "FGHI"); assertThat(files).extracting("srcHash").containsOnly("srcEFGHI", "srcHIJK"); assertThat(files).extracting("path").containsOnly("src/org/struts/pom.xml", "src/org/struts/RequestContext.java"); // From module - assertThat(underTest.selectEnabledFilesFromProject(db.getSession(), "EFGH")).isEmpty(); + assertThat(underTest.selectEnabledFilesFromProject(dbSession, "EFGH")).isEmpty(); // From sub module - assertThat(underTest.selectEnabledFilesFromProject(db.getSession(), "FGHI")).isEmpty(); + assertThat(underTest.selectEnabledFilesFromProject(dbSession, "FGHI")).isEmpty(); // From directory - assertThat(underTest.selectEnabledFilesFromProject(db.getSession(), "GHIJ")).isEmpty(); + assertThat(underTest.selectEnabledFilesFromProject(dbSession, "GHIJ")).isEmpty(); - assertThat(underTest.selectEnabledFilesFromProject(db.getSession(), "unknown")).isEmpty(); + assertThat(underTest.selectEnabledFilesFromProject(dbSession, "unknown")).isEmpty(); } @Test public void select_all_components_from_project() { db.prepareDbUnit(getClass(), "multi-modules.xml"); - List<ComponentDto> components = underTest.selectAllComponentsFromProjectKey(db.getSession(), "org.struts:struts"); + List<ComponentDto> components = underTest.selectAllComponentsFromProjectKey(dbSession, "org.struts:struts"); // Removed components are included assertThat(components).hasSize(8); - assertThat(underTest.selectAllComponentsFromProjectKey(db.getSession(), "UNKNOWN")).isEmpty(); + assertThat(underTest.selectAllComponentsFromProjectKey(dbSession, "UNKNOWN")).isEmpty(); } @Test public void select_modules_from_project() { db.prepareDbUnit(getClass(), "multi-modules.xml"); - List<ComponentDto> components = underTest.selectEnabledModulesFromProjectKey(db.getSession(), "org.struts:struts"); + List<ComponentDto> components = underTest.selectEnabledModulesFromProjectKey(dbSession, "org.struts:struts"); assertThat(components).hasSize(3); - assertThat(underTest.selectEnabledModulesFromProjectKey(db.getSession(), "UNKNOWN")).isEmpty(); + assertThat(underTest.selectEnabledModulesFromProjectKey(dbSession, "UNKNOWN")).isEmpty(); } @Test public void select_views_and_sub_views() { db.prepareDbUnit(getClass(), "shared_views.xml"); - assertThat(underTest.selectAllViewsAndSubViews(db.getSession())).extracting("uuid").containsOnly("ABCD", "EFGH", "FGHI", "IJKL"); - assertThat(underTest.selectAllViewsAndSubViews(db.getSession())).extracting("projectUuid").containsOnly("ABCD", "EFGH", "IJKL"); + assertThat(underTest.selectAllViewsAndSubViews(dbSession)).extracting("uuid").containsOnly("ABCD", "EFGH", "FGHI", "IJKL"); + assertThat(underTest.selectAllViewsAndSubViews(dbSession)).extracting("projectUuid").containsOnly("ABCD", "EFGH", "IJKL"); } @Test public void select_projects_from_view() { db.prepareDbUnit(getClass(), "shared_views.xml"); - assertThat(underTest.selectProjectsFromView(db.getSession(), "ABCD", "ABCD")).containsOnly("JKLM"); - assertThat(underTest.selectProjectsFromView(db.getSession(), "EFGH", "EFGH")).containsOnly("KLMN", "JKLM"); - assertThat(underTest.selectProjectsFromView(db.getSession(), "FGHI", "EFGH")).containsOnly("JKLM"); - assertThat(underTest.selectProjectsFromView(db.getSession(), "IJKL", "IJKL")).isEmpty(); - assertThat(underTest.selectProjectsFromView(db.getSession(), "Unknown", "Unknown")).isEmpty(); + assertThat(underTest.selectProjectsFromView(dbSession, "ABCD", "ABCD")).containsOnly("JKLM"); + assertThat(underTest.selectProjectsFromView(dbSession, "EFGH", "EFGH")).containsOnly("KLMN", "JKLM"); + assertThat(underTest.selectProjectsFromView(dbSession, "FGHI", "EFGH")).containsOnly("JKLM"); + assertThat(underTest.selectProjectsFromView(dbSession, "IJKL", "IJKL")).isEmpty(); + assertThat(underTest.selectProjectsFromView(dbSession, "Unknown", "Unknown")).isEmpty(); } @Test public void select_projects() { db.prepareDbUnit(getClass(), "select_provisioned_projects.xml"); - List<ComponentDto> result = underTest.selectProjects(db.getSession()); + List<ComponentDto> result = underTest.selectProjects(dbSession); assertThat(result).extracting("id").containsOnly(42L, 1L); } @@ -479,7 +481,7 @@ public class ComponentDaoTest { public void select_provisioned_projects() { db.prepareDbUnit(getClass(), "select_provisioned_projects.xml"); - List<ComponentDto> result = underTest.selectProvisionedProjects(db.getSession(), 0, 10, null); + List<ComponentDto> result = underTest.selectProvisionedProjects(dbSession, 0, 10, null); ComponentDto project = result.get(0); assertThat(result).hasSize(1); @@ -490,7 +492,7 @@ public class ComponentDaoTest { public void count_provisioned_projects() { db.prepareDbUnit(getClass(), "select_provisioned_projects.xml"); - int numberOfProjects = underTest.countProvisionedProjects(db.getSession(), null); + int numberOfProjects = underTest.countProvisionedProjects(dbSession, null); assertThat(numberOfProjects).isEqualTo(1); } @@ -499,18 +501,18 @@ public class ComponentDaoTest { public void select_ghost_projects() { db.prepareDbUnit(getClass(), "select_ghost_projects.xml"); - List<ComponentDto> result = underTest.selectGhostProjects(db.getSession(), 0, 10, null); + List<ComponentDto> result = underTest.selectGhostProjects(dbSession, 0, 10, null); assertThat(result).hasSize(1); assertThat(result.get(0).key()).isEqualTo("org.ghost.project"); - assertThat(underTest.countGhostProjects(db.getSession(), null)).isEqualTo(1); + assertThat(underTest.countGhostProjects(dbSession, null)).isEqualTo(1); } @Test public void selectResourcesByRootId() { db.prepareDbUnit(getClass(), "shared.xml"); - List<ComponentDto> resources = underTest.selectByProjectUuid("ABCD", db.getSession()); + List<ComponentDto> resources = underTest.selectByProjectUuid("ABCD", dbSession); assertThat(resources).extracting("id").containsOnly(1l, 2l, 3l, 4l); } @@ -540,8 +542,8 @@ public class ComponentDaoTest { .setCreatedAt(DateUtils.parseDate("2014-06-18")) .setAuthorizationUpdatedAt(123456789L); - underTest.insert(db.getSession(), componentDto); - db.getSession().commit(); + underTest.insert(dbSession, componentDto); + dbSession.commit(); assertThat(componentDto.getId()).isNotNull(); db.assertDbUnit(getClass(), "insert-result.xml", "projects"); @@ -569,8 +571,8 @@ public class ComponentDaoTest { .setCreatedAt(DateUtils.parseDate("2014-06-18")) .setAuthorizationUpdatedAt(123456789L); - underTest.insert(db.getSession(), componentDto); - db.getSession().commit(); + underTest.insert(dbSession, componentDto); + dbSession.commit(); assertThat(componentDto.getId()).isNotNull(); db.assertDbUnit(getClass(), "insert_disabled_component-result.xml", "projects"); @@ -599,15 +601,27 @@ public class ComponentDaoTest { .setEnabled(false) .setAuthorizationUpdatedAt(12345678910L); - underTest.update(db.getSession(), componentDto); - db.getSession().commit(); + underTest.update(dbSession, componentDto); + dbSession.commit(); db.assertDbUnit(getClass(), "update-result.xml", "projects"); } @Test + public void delete() throws Exception { + ComponentDto project1= insertProject(newProjectDto().setKey("PROJECT_1")); + insertProject(newProjectDto().setKey("PROJECT_2")); + + underTest.delete(dbSession, project1.getId()); + dbSession.commit(); + + assertThat(underTest.selectByKey(dbSession, "PROJECT_1")).isAbsent(); + assertThat(underTest.selectByKey(dbSession, "PROJECT_2")).isPresent(); + } + + @Test public void select_components_with_paging_query_and_qualifiers() { - DbSession session = db.getSession(); + DbSession session = dbSession; underTest.insert(session, newProjectDto().setName("aaaa-name")); underTest.insert(session, newView()); underTest.insert(session, newDeveloper("project-name")); @@ -620,4 +634,10 @@ public class ComponentDaoTest { 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; + } } diff --git a/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoWithDuplicatedKeysTest.java b/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoWithDuplicatedKeysTest.java new file mode 100644 index 00000000000..038c58a63f7 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoWithDuplicatedKeysTest.java @@ -0,0 +1,72 @@ +/* + * 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.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.sonar.api.utils.System2; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.test.DbTests; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.db.component.ComponentTesting.newProjectDto; + +/** + * On H2, the index on PROJECTS.KEE is unique. In order to simulate the MySQL behaviour where the index is not unique, we need to create a schema where there's no unique index on PROJECTS.KEE + */ +@Category(DbTests.class) +public class ComponentDaoWithDuplicatedKeysTest { + + static final String PROJECT_KEY = "PROJECT_KEY"; + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, ComponentDaoWithDuplicatedKeysTest.class, "schema.sql"); + + DbClient dbClient = db.getDbClient(); + + DbSession dbSession = db.getSession(); + + ComponentDao underTest = new ComponentDao(); + + @Test + public void select_components_having_same_key() { + insertProject(newProjectDto().setKey(PROJECT_KEY)); + insertProject(newProjectDto().setKey(PROJECT_KEY)); + insertProject(newProjectDto().setKey(PROJECT_KEY)); + insertProject(newProjectDto().setKey("ANOTHER_PROJECT_KEY")); + + assertThat(underTest.selectComponentsHavingSameKeyOrderedById(db.getSession(), PROJECT_KEY)).hasSize(3); + } + + @Test + public void return_nothing() throws Exception { + assertThat(underTest.selectComponentsHavingSameKeyOrderedById(db.getSession(), PROJECT_KEY)).isEmpty(); + } + + private ComponentDto insertProject(ComponentDto project) { + dbClient.componentDao().insert(dbSession, project); + dbSession.commit(); + return project; + } +} diff --git a/sonar-db/src/test/resources/org/sonar/db/component/ComponentDaoTest/delete-result.xml b/sonar-db/src/test/resources/org/sonar/db/component/ComponentDaoTest/delete-result.xml index dab26ba7f8d..d525297195a 100644 --- a/sonar-db/src/test/resources/org/sonar/db/component/ComponentDaoTest/delete-result.xml +++ b/sonar-db/src/test/resources/org/sonar/db/component/ComponentDaoTest/delete-result.xml @@ -1,94 +1,23 @@ <dataset> - <!-- Struts projects is authorized for all user --> - <group_roles id="1" group_id="[null]" resource_id="1" role="user"/> - - - <!-- root project --> - <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" deprecated_kee="org.struts:struts" - uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD." - description="the description" long_name="Apache Struts" - enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" created_at="[null]" authorization_updated_at="123456789"/> - <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[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="1228222680000" build_date="1228222680000" - version="[null]" path=""/> - <snapshots id="10" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" - status="P" islast="[false]" 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="1228136280000" build_date="1228136280000" - version="[null]" path=""/> - <!-- module --> - <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" deprecated_kee="[null]" + <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD.EFGH." scope="PRJ" qualifier="BRC" long_name="Struts Core" - description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" created_at="[null]" authorization_updated_at="[null]"/> - <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1" - 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="1228222680000" build_date="1228222680000" - version="[null]" path="1."/> + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]"/> <!-- directory --> - <projects long_name="org.struts" id="3" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts" deprecated_kee="[null]" + <projects long_name="org.struts" id="3" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts" uuid="GHIJ" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH." name="src/org/struts" root_id="2" description="[null]" - enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" created_at="[null]" authorization_updated_at="[null]"/> - <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1" - 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="1228222680000" build_date="1228222680000" - version="[null]" path="1.2."/> + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" authorization_updated_at="[null]"/> <!-- file --> - <!--<projects long_name="org.struts.RequestContext" id="4" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java"--> - <!--uuid="KLMN" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH."--> - <!--name="RequestContext.java" root_id="2"--> - <!--description="[null]"--> - <!--enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java" authorization_updated_at="[null]" />--> - - <snapshots id="4" project_id="4" parent_snapshot_id="3" root_project_id="1" root_snapshot_id="1" - 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="1228222680000" build_date="1228222680000" - version="[null]" path="1.2.3."/> - - <projects id="10" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.disabled.project" name="Disabled Project" - uuid="DCBA" project_uuid="DCBA" module_uuid="[null]" module_uuid_path="." - description="the description" long_name="Disabled project" - enabled="[false]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" authorization_updated_at="123456789"/> - - <!-- Developer and technical project copy --> - <projects id="11" root_id="[null]" scope="PRJ" qualifier="DEV" kee="DEV:anakin@skywalker.name" name="Anakin Skywalker" - uuid="OPQR" project_uuid="OPQR" module_uuid="[null]" module_uuid_path=".OPQR." - description="the description" long_name="Anakin Skywalker" - enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" authorization_updated_at="123456789"/> - <projects id="12" root_id="11" scope="PRJ" qualifier="DEV_PRJ" kee="DEV:anakin@skywalker.name:org.struts:struts" name="Apache Struts" - uuid="STUV" project_uuid="OPQR" module_uuid="OPQR" module_uuid_path=".OPQR." - description="the description" long_name="Apache Struts" - enabled="[true]" language="[null]" copy_resource_id="1" person_id="11" path="[null]" authorization_updated_at="123456789"/> + <projects long_name="org.struts.RequestContext" id="4" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java" + uuid="KLMN" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH." + name="RequestContext.java" root_id="2" + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java" authorization_updated_at="[null]"/> </dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/component/ComponentDaoTest/delete.xml b/sonar-db/src/test/resources/org/sonar/db/component/ComponentDaoTest/delete.xml new file mode 100644 index 00000000000..78749b4753e --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/component/ComponentDaoTest/delete.xml @@ -0,0 +1,29 @@ +<dataset> + + <!-- root project --> + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" deprecated_kee="org.struts:struts" name="Struts" + uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD." + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" authorization_updated_at="123456789"/> + + <!-- module --> + <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" + uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD.EFGH." + scope="PRJ" qualifier="BRC" long_name="Struts Core" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]"/> + + <!-- directory --> + <projects long_name="org.struts" id="3" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts" + uuid="GHIJ" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH." + name="src/org/struts" root_id="2" + description="[null]" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" authorization_updated_at="[null]"/> + + <!-- file --> + <projects long_name="org.struts.RequestContext" id="4" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java" + uuid="KLMN" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH." + name="RequestContext.java" root_id="2" + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java" authorization_updated_at="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/component/ComponentDaoWithDuplicatedKeysTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/component/ComponentDaoWithDuplicatedKeysTest/schema.sql new file mode 100644 index 00000000000..5b314d137e7 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/component/ComponentDaoWithDuplicatedKeysTest/schema.sql @@ -0,0 +1,34 @@ +CREATE TABLE "PROJECTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(400), + "ROOT_ID" INTEGER, + "UUID" VARCHAR(50), + "PROJECT_UUID" VARCHAR(50), + "MODULE_UUID" VARCHAR(50), + "MODULE_UUID_PATH" VARCHAR(4000), + "NAME" VARCHAR(256), + "DESCRIPTION" VARCHAR(2000), + "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10), + "DEPRECATED_KEE" VARCHAR(400), + "PATH" VARCHAR(2000), + "LANGUAGE" VARCHAR(20), + "COPY_RESOURCE_ID" INTEGER, + "LONG_NAME" VARCHAR(256), + "PERSON_ID" INTEGER, + "CREATED_AT" TIMESTAMP, + "AUTHORIZATION_UPDATED_AT" BIGINT +); + +CREATE INDEX "PROJECTS_KEE" ON "PROJECTS" ("KEE"); + +CREATE INDEX "PROJECTS_ROOT_ID" ON "PROJECTS" ("ROOT_ID"); + +CREATE UNIQUE INDEX "PROJECTS_UUID" ON "PROJECTS" ("UUID"); + +CREATE INDEX "PROJECTS_PROJECT_UUID" ON "PROJECTS" ("PROJECT_UUID"); + +CREATE INDEX "PROJECTS_MODULE_UUID" ON "PROJECTS" ("MODULE_UUID"); + +CREATE INDEX "PROJECTS_QUALIFIER" ON "PROJECTS" ("QUALIFIER"); |