]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9087 make PROJECTS.PROJECT_UUID not nullable
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Wed, 12 Apr 2017 12:39:46 +0000 (14:39 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Thu, 27 Apr 2017 12:25:54 +0000 (14:25 +0200)
54 files changed:
server/sonar-db-core/src/main/resources/org/sonar/db/version/schema-h2.ddl
server/sonar-db-dao/src/test/resources/org/sonar/db/component/ComponentKeyUpdaterDaoTest/shared.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/component/ComponentKeyUpdaterDaoTest/shouldBulkUpdateKey-result.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/component/ComponentKeyUpdaterDaoTest/shouldBulkUpdateKeyOnOnlyOneSubmodule-result.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/component/ComponentKeyUpdaterDaoTest/shouldNotUpdateAllSubmodules-result.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/component/ComponentKeyUpdaterDaoTest/shouldNotUpdateAllSubmodules.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/component/ComponentKeyUpdaterDaoTest/shouldUpdateKey-result.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/component/SnapshotDaoTest/select_previous_version_snapshots.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/duplication/DuplicationDaoTest/insert.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/duplication/DuplicationDaoTest/select_candidates.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/permission/AuthorizationDaoTest/anonymous_should_be_authorized.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/permission/AuthorizationDaoTest/group_should_be_authorized.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/permission/AuthorizationDaoTest/keep_authorized_project_ids_for_anonymous.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/permission/AuthorizationDaoTest/keep_authorized_project_ids_for_group.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/permission/AuthorizationDaoTest/keep_authorized_project_ids_for_user.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/permission/AuthorizationDaoTest/keep_authorized_users_for_role_and_project_for_anonymous.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/permission/AuthorizationDaoTest/keep_authorized_users_for_role_and_project_for_group.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/permission/AuthorizationDaoTest/keep_authorized_users_for_role_and_project_for_user.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/permission/AuthorizationDaoTest/should_return_root_project_keys_for_anonymous.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/permission/AuthorizationDaoTest/should_return_root_project_keys_for_group.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/permission/AuthorizationDaoTest/should_return_root_project_keys_for_user.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/permission/AuthorizationDaoTest/user_should_be_authorized.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeCommandsTest/shouldDeleteResource.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeDaoTest/should_delete_all_closed_issues.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeDaoTest/should_delete_old_closed_issues.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest/shared.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/qualityprofile/QualityProfileDaoTest/projects.xml
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v64/DbVersion64.java
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v64/MakeProjectUuidNotNullable.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v64/PurgeComponentsWithoutProjectUuid.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v64/DbVersion64Test.java
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v64/MakeProjectUuidNotNullableTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v64/PurgeComponentsWithoutProjectUuidTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v64/MakeProjectUuidNotNullableTest/projects_with_nullable_project_uuid.sql [new file with mode: 0644]
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v64/PurgeComponentsWithoutProjectUuidTest/projects_and_children_tables.sql [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistMeasuresStepTest.java
server/sonar-server/src/test/java/org/sonar/server/projectlink/ws/DeleteActionTest.java
server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/step/LoadPeriodsStepTest/empty.xml
server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/step/LoadPeriodsStepTest/no_previous_version.xml
server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/step/LoadPeriodsStepTest/previous_version_deleted.xml
server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/step/LoadPeriodsStepTest/previous_version_is_last_one.xml
server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/step/LoadPeriodsStepTest/shared.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/ServerIssueStorageTest/load_component_id_from_db.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/ServerIssueStorageTest/load_project_id_from_db.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/ServerIssueStorageTest/should_insert_new_issues.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/ServerIssueStorageTest/should_update_issues.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/index/IssueIndexerTest/index.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/index/IssueIndexerTest/index_project.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/index/IssueResultSetIteratorTest/extract_directory_path.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/index/IssueResultSetIteratorTest/extract_file_path.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/index/IssueResultSetIteratorTest/many_projects.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/index/IssueResultSetIteratorTest/one_issue.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/index/IssueResultSetIteratorTest/shared.xml

index b24a231643a942ed0a5265028bebfd602d5acade..5255f8fb9f42fb6a466b2131534fea921a51b5f1 100644 (file)
@@ -279,7 +279,7 @@ CREATE TABLE "PROJECTS" (
   "UUID" VARCHAR(50) NOT NULL,
   "UUID_PATH" VARCHAR(1500) NOT NULL,
   "ROOT_UUID" VARCHAR(50) NOT NULL,
-  "PROJECT_UUID" VARCHAR(50),
+  "PROJECT_UUID" VARCHAR(50) NOT NULL,
   "MODULE_UUID" VARCHAR(50),
   "MODULE_UUID_PATH" VARCHAR(1500),
   "NAME" VARCHAR(2000),
index 8a85d6953856c3ac187b222e68bbc54ab5a7436f..a1daa9c18f2f68db7dbfe3442dde6fda6626052e 100644 (file)
@@ -35,7 +35,7 @@
             b_path="[null]"
             b_qualifier="[null]"
   />
-  ²
+
 
   <!-- **************** First sub project **************** -->
   <projects organization_uuid="org1"
             name="Struts UI"
             uuid="E"
             uuid_path="A.E."
-            project_uuid="[null]"
+            project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".E."
             scope="PRJ"
             root_uuid="E"
             uuid="F"
             uuid_path="A.E.F."
-            project_uuid="[null]"
+            project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
             description="[null]"
             root_uuid="E"
             uuid="G"
             uuid_path="A.E.F.G."
-            project_uuid="[null]"
+            project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
             description="[null]"
             name="Foo Struts Core"
             uuid="H"
             uuid_path="H."
-            project_uuid="[null]"
+            project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".H."
             scope="PRJ"
index c734f270dde9548593aecb0b8887fb9e45c8a8a3..734fce89948fa8713ff02057439b1ca4de2aa16e 100644 (file)
             name="Struts UI"
             uuid="E"
             uuid_path="A.E."
-            project_uuid="[null]"
+            project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".E."
             scope="PRJ"
             root_uuid="E"
             uuid="F"
             uuid_path="A.E.F."
-            project_uuid="[null]"
+            project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
             description="[null]"
             root_uuid="E"
             uuid="G"
             uuid_path="A.E.F.G."
-            project_uuid="[null]"
+            project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
             description="[null]"
             name="Foo Struts Core"
             uuid="H"
             uuid_path="H."
-            project_uuid="[null]"
+            project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".H."
             scope="PRJ"
index f0ca1fc2d8f0498fc8ecf083570025a6c957eb3a..e930d3427ca6f24401a68a8dcf72a750a759e688 100644 (file)
             name="Struts UI"
             uuid="E"
             uuid_path="A.E."
-            project_uuid="[null]"
+            project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".E."
             scope="PRJ"
             root_uuid="E"
             uuid="F"
             uuid_path="A.E.F."
-            project_uuid="[null]"
+            project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
             description="[null]"
             root_uuid="E"
             uuid="G"
             uuid_path="A.E.F.G."
-            project_uuid="[null]"
+            project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
             description="[null]"
             name="Foo Struts Core"
             uuid="H"
             uuid_path="H."
-            project_uuid="[null]"
+            project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".H."
             scope="PRJ"
index c233d66e2fc4f0bd0ab353f303a7480e6ceec70c..666ebdd23c76b5c9f0f557cbf3ce18d977590c1e 100644 (file)
             name="Struts UI"
             uuid="E"
             uuid_path="A.E."
-            project_uuid="[null]"
+            project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".E."
             scope="PRJ"
             root_uuid="E"
             uuid="F"
             uuid_path="A.E.F."
-            project_uuid="[null]"
+            project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
             description="[null]"
             root_uuid="E"
             uuid="G"
             uuid_path="A.E.F.G."
-            project_uuid="[null]"
+            project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
             description="[null]"
index b16db8645503295456a3174b0b74309f43defb2c..a52ab410de54e6875ea74ab0573ba262a400eeb0 100644 (file)
             name="Struts UI"
             uuid="E"
             uuid_path="A.E."
-            project_uuid="[null]"
+            project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".E."
             scope="PRJ"
             root_uuid="E"
             uuid="F"
             uuid_path="A.E.F."
-            project_uuid="[null]"
+            project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
             description="[null]"
             root_uuid="E"
             uuid="G"
             uuid_path="A.E.F.G."
-            project_uuid="[null]"
+            project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
             description="[null]"
index eb73a95d604b4b85e4c255b3873f255b7f1ad6f8..5cf415c7f97e44c8a00be42d224642fc45121d0e 100644 (file)
             name="Struts UI"
             uuid="E"
             uuid_path="A.E."
-            project_uuid="[null]"
+            project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".E."
             scope="PRJ"
             root_uuid="E"
             uuid="F"
             uuid_path="A.E.F."
-            project_uuid="[null]"
+            project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
             description="[null]"
             root_uuid="E"
             uuid="G"
             uuid_path="A.E.F.G."
-            project_uuid="[null]"
+            project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
             description="[null]"
             name="Foo Struts Core"
             uuid="H"
             uuid_path="H."
-            project_uuid="[null]"
+            project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".H."
             scope="PRJ"
index 16a491eea53401ff251dd1a5011228363db1a9ca..89e0fb54db9b9b2b1cb7cd9f9ac303c07c77bccc 100644 (file)
@@ -8,6 +8,7 @@
             kee="project"
             name="project"
             root_uuid="ABCD"
+            project_uuid="ABCD"
             uuid="ABCD"
             uuid_path="NOT_USED"
             description="[null]"
index a4074f2e1dcbd12a4f20e18a48e2c80354386b34..f7ab895c5855986fbaa74b0f9013967a0eb584c5 100644 (file)
@@ -18,6 +18,7 @@
             uuid="uuid_1"
             uuid_path="NOT_USED"
             root_uuid="uuid_root"
+            project_uuid="uuid_root"
             kee="foo"
             enabled="1"
             scope="FIL"
index ebbfc3482fd6103d35fcef430b6f316ae831379e..d6d3628fcc266628e8c1752afd84649bbe80e354 100644 (file)
@@ -19,6 +19,7 @@
             uuid="uuid_1"
             uuid_path="NOT_USED"
             root_uuid="uuid_root_1"
+            project_uuid="uuid_root_1"
             kee="bar-old"
             enabled="[true]"
             scope="FIL"
@@ -44,6 +45,7 @@
             uuid="uuid_2"
             uuid_path="NOT_USED"
             root_uuid="uuid_root_2"
+            project_uuid="uuid_root_2"
             kee="bar-last"
             enabled="[true]"
             scope="FIL"
@@ -69,6 +71,7 @@
             uuid="uuid_3"
             uuid_path="NOT_USED"
             root_uuid="uuid_root_3"
+            project_uuid="uuid_root_3"
             kee="foo-old"
             enabled="[true]"
             scope="FIL"
@@ -94,6 +97,7 @@
             uuid="uuid_4"
             uuid_path="NOT_USED"
             root_uuid="uuid_root_4"
+            project_uuid="uuid_root_4"
             kee="foo-last"
             enabled="[true]"
             scope="FIL"
             uuid="uuid_5"
             uuid_path="NOT_USED"
             root_uuid="uuid_root_5"
+            project_uuid="uuid_root_5"
             kee="foo"
             enabled="[true]"
             scope="FIL"
             uuid="uuid_6"
             uuid_path="NOT_USED"
             root_uuid="uuid_root_1"
+            project_uuid="uuid_root_1"
             kee="baz"
             enabled="[true]"
             scope="FIL"
index a06cc07314c867c6de07a9852ffda69413dd9462..f0682ce10cb0dc5086c3c0a5f1ddbc6465fa4f12 100644 (file)
@@ -22,6 +22,7 @@
             id="301"
             kee="pj-w-snapshot:package"
             root_uuid="EDFG"
+            project_uuid="EDFG"
             uuid="ABCD"
             uuid_path="NOT_USED"
             module_uuid="EDFG"/>
@@ -29,6 +30,7 @@
             id="302"
             kee="pj-w-snapshot:file"
             root_uuid="EDFG"
+            project_uuid="EDFG"
             uuid="BCDE"
             uuid_path="NOT_USED"
             module_uuid="EDFG"/>
@@ -36,6 +38,7 @@
             id="303"
             kee="pj-w-snapshot:other"
             root_uuid="EDFG"
+            project_uuid="EDFG"
             uuid="CDEF"
             uuid_path="NOT_USED"
             module_uuid="EDFG"/>
@@ -45,6 +48,7 @@
             uuid="EDFG"
             uuid_path="NOT_USED"
             root_uuid="EDFG"
+            project_uuid="EDFG"
             module_uuid="[null]"/>
   <projects organization_uuid="org1"
             id="400"
index e106b84c5bd0db2d29c54a4da9e2a7f22958a2b4..4600adb1fd73747593b7e0e1fdc4cfaec447f274 100644 (file)
@@ -24,6 +24,7 @@
             id="301"
             kee="pj-w-snapshot:package"
             root_uuid="DEFG"
+            project_uuid="DEFG"
             uuid="ABCD"
             uuid_path="NOT_USED"
             module_uuid="DEFG"/>
@@ -31,6 +32,7 @@
             id="302"
             kee="pj-w-snapshot:file"
             root_uuid="DEFG"
+            project_uuid="DEFG"
             uuid="BCDE"
             uuid_path="NOT_USED"
             module_uuid="DEFG"/>
@@ -38,6 +40,7 @@
             id="303"
             kee="pj-w-snapshot:other"
             root_uuid="DEFG"
+            project_uuid="DEFG"
             uuid="CDEF"
             uuid_path="NOT_USED"
             module_uuid="DEFG"/>
@@ -47,6 +50,7 @@
             uuid="DEFG"
             uuid_path="NOT_USED"
             root_uuid="DEFG"
+            project_uuid="DEFG"
             module_uuid="[null]"/>
   <projects organization_uuid="org1"
             id="400"
@@ -54,6 +58,7 @@
             uuid="EFGH"
             uuid_path="NOT_USED"
             root_uuid="EFGH"
+            project_uuid="EFGH"
             module_uuid="[null]"/>
 
 </dataset>
index 15490848b379cf9e1ec2ccd319200d9620b532f1..48672a816241f8b4b38d05908eb84e716da654ed 100644 (file)
@@ -19,6 +19,7 @@
             uuid="DEFG"
             uuid_path="NOT_USED"
             root_uuid="DEFG"
+            project_uuid="DEFG"
             module_uuid="[null]"
             enabled="[true]"/>
   <projects organization_uuid="org1"
@@ -27,6 +28,7 @@
             uuid="EFGH"
             uuid_path="NOT_USED"
             root_uuid="EFGH"
+            project_uuid="EFGH"
             module_uuid="[null]"
             enabled="[true]"/>
 
index fcebe81297bc35c047fad9127d3e4948b125247d..69a8954c9f1bba42df0e1a88345582c762b1ad90 100644 (file)
@@ -19,6 +19,7 @@
             uuid="DEFG"
             uuid_path="NOT_USED"
             root_uuid="DEFG"
+            project_uuid="DEFG"
             module_uuid="[null]"
             enabled="[true]"/>
   <projects organization_uuid="org1"
@@ -27,6 +28,7 @@
             uuid="EFGH"
             uuid_path="NOT_USED"
             root_uuid="EFGH"
+            project_uuid="EFGH"
             module_uuid="[null]"
             enabled="[true]"/>
 
index 4063a186b29c41a599672a58dae5ed133e54d477..d5bd2ec06d585eed5a2b3bcc6d2fac150bbfcfa0 100644 (file)
@@ -18,6 +18,7 @@
             uuid="DEFG"
             uuid_path="NOT_USED"
             root_uuid="DEFG"
+            project_uuid="DEFG"
             module_uuid="[null]"
             enabled="[true]"/>
   <projects organization_uuid="org1"
@@ -26,6 +27,7 @@
             uuid="EFGH"
             uuid_path="NOT_USED"
             root_uuid="EFGH"
+            project_uuid="EFGH"
             module_uuid="[null]"
             enabled="[true]"/>
 
index 6bf48995401e2d4c44e675ca1ff661f7b41f93c8..43cc092757f2bbf3f98bf1452773fc4210f75298 100644 (file)
@@ -41,6 +41,7 @@
             uuid="DEFG"
             uuid_path="NOT_USED"
             root_uuid="DEFG"
+            project_uuid="DEFG"
             module_uuid="[null]"/>
   <projects organization_uuid="org1"
             id="400"
@@ -48,6 +49,7 @@
             uuid="EFGH"
             uuid_path="NOT_USED"
             root_uuid="EFGH"
+            project_uuid="EFGH"
             module_uuid="[null]"/>
 
 </dataset>
index 6983aebaf8790fa2a3f5180fb91f4509c5e2e02e..11e228bffeafccd3636dfdbd6be4822a027e3c46 100644 (file)
@@ -41,6 +41,7 @@
             uuid="DEFG"
             uuid_path="NOT_USED"
             root_uuid="DEFG"
+            project_uuid="DEFG"
             module_uuid="[null]"/>
   <projects organization_uuid="org1"
             id="400"
@@ -48,6 +49,7 @@
             uuid="EFGH"
             uuid_path="NOT_USED"
             root_uuid="EFGH"
+            project_uuid="EFGH"
             module_uuid="[null]"/>
 
 </dataset>
index 6475b6ce25f224f475d2d5e5c89b94376fad9671..59824f33c3b0b1291ea6b8afd2875c7ea88242af 100644 (file)
@@ -36,6 +36,7 @@
             uuid="DEFG"
             uuid_path="NOT_USED"
             root_uuid="DEFG"
+            project_uuid="DEFG"
             module_uuid="[null]"/>
   <projects organization_uuid="org1"
             id="400"
@@ -43,6 +44,7 @@
             uuid="EFGH"
             uuid_path="NOT_USED"
             root_uuid="EFGH"
+            project_uuid="EFGH"
             module_uuid="[null]"/>
 
 </dataset>
index f883b12fdbaeadee089d0b15ccde58ca819d57fd..39ae6471835e038171438c0baa43baec49a5282d 100644 (file)
@@ -18,6 +18,7 @@
             uuid="ABCD"
             uuid_path="NOT_USED"
             root_uuid="ABCD"
+            project_uuid="ABCD"
             module_uuid="[null]"
             kee="pj-w-snapshot"
             scope="PRJ"
@@ -28,6 +29,7 @@
             uuid="BCDE"
             uuid_path="NOT_USED"
             root_uuid="BCDE"
+            project_uuid="BCDE"
             module_uuid="[null]"
             kee="pj-w-snapshot1"
             scope="PRJ"
@@ -38,6 +40,7 @@
             uuid="CDEF"
             uuid_path="NOT_USED"
             root_uuid="CDEF"
+            project_uuid="CDEF"
             module_uuid="[null]"
             kee="pj-w-snapshot2"
             scope="PRJ"
@@ -49,6 +52,7 @@
             uuid="DEFG"
             uuid_path="NOT_USED"
             root_uuid="DEFG"
+            project_uuid="DEFG"
             module_uuid="[null]"
             kee="pj-w-snapshot3"
             scope="PRJ"
index 865ef0002620af0a5dc99bc994198425f1df4d65..1efb1cccc47823804683dc491e54e3805f0b8c37 100644 (file)
@@ -20,6 +20,7 @@
             uuid="ABCD"
             uuid_path="NOT_USED"
             root_uuid="ABCD"
+            project_uuid="ABCD"
             module_uuid="[null]"
             kee="pj-w-snapshot"
             scope="PRJ"
@@ -30,6 +31,7 @@
             uuid="BCDE"
             uuid_path="NOT_USED"
             root_uuid="BCDE"
+            project_uuid="BCDE"
             module_uuid="[null]"
             kee="pj-w-snapshot1"
             scope="PRJ"
@@ -40,6 +42,7 @@
             uuid="CDEF"
             uuid_path="NOT_USED"
             root_uuid="CDEF"
+            project_uuid="CDEF"
             module_uuid="[null]"
             kee="pj-w-snapshot2"
             scope="PRJ"
@@ -51,6 +54,7 @@
             uuid="DEFG"
             uuid_path="NOT_USED"
             root_uuid="DEFG"
+            project_uuid="DEFG"
             module_uuid="[null]"
             kee="pj-w-snapshot3"
             scope="PRJ"
index ebeb0828cf8d6fea770257ff1d15eff34edfd1a2..4ba055aa869d4d2512b09b6672482d8a7d677ca0 100644 (file)
@@ -19,6 +19,7 @@
             uuid="ABCD"
             uuid_path="NOT_USED"
             root_uuid="ABCD"
+            project_uuid="ABCD"
             module_uuid="[null]"
             kee="pj-w-snapshot"
             scope="PRJ"
@@ -29,6 +30,7 @@
             uuid="BCDE"
             uuid_path="NOT_USED"
             root_uuid="BCDE"
+            project_uuid="BCDE"
             module_uuid="[null]"
             kee="pj-w-snapshot1"
             scope="PRJ"
@@ -39,6 +41,7 @@
             uuid="CDEF"
             uuid_path="NOT_USED"
             root_uuid="CDEF"
+            project_uuid="CDEF"
             module_uuid="[null]"
             kee="pj-w-snapshot2"
             scope="PRJ"
@@ -50,6 +53,7 @@
             uuid="DEFG"
             uuid_path="NOT_USED"
             root_uuid="DEFG"
+            project_uuid="DEFG"
             module_uuid="[null]"
             kee="pj-w-snapshot3"
             scope="PRJ"
index aac77f3ec7f1978ca52071d0f5e3efe08703a1f4..c4e6323e503c81543e2c30ba6c62852a9b245072 100644 (file)
@@ -25,6 +25,7 @@
             uuid="DEFG"
             uuid_path="NOT_USED"
             root_uuid="DEFG"
+            project_uuid="DEFG"
             module_uuid="[null]"/>
   <projects organization_uuid="org1"
             id="400"
@@ -32,5 +33,6 @@
             uuid="EFGH"
             uuid_path="NOT_USED"
             root_uuid="EFGH"
+            project_uuid="EFGH"
             module_uuid="[null]"/>
 </dataset>
index 3d6194b56b7001f8b53b375bc441e4270c12eac9..6794843926f97e37ff822a71488e156e442a5526 100644 (file)
@@ -6,6 +6,7 @@
             uuid_path="NOT_USED"
             enabled="[true]"
             root_uuid="uuid_1"
+            project_uuid="uuid_1"
             long_name="[null]"
             scope="PRJ"
             qualifier="TRK"
index 103f0b8adcd482264b77486f5ed6972717f500ae..95bb3dfba072b81b832cb79c3ab04e362553f45b 100644 (file)
@@ -5,6 +5,7 @@
             uuid_path="NOT_USED"
             enabled="[true]"
             root_uuid="1"
+            project_uuid="1"
             created_at="[null]"
             long_name="[null]"
             scope="PRJ"
index 17c663de33f9536aaa861a9c3d1972848319b924..a27f41c6b1436a6f98fc42218ffc8f42251e6600 100644 (file)
@@ -5,6 +5,7 @@
             uuid_path="NOT_USED"
             enabled="[true]"
             root_uuid="P1"
+            project_uuid="P1"
             created_at="[null]"
             long_name="[null]"
             scope="PRJ"
index 13ca29d2acc6b600b8e8c23c85bdd4caefd7d86d..b0c08cb330ffa494f307300753996a4874744b0a 100644 (file)
@@ -9,6 +9,7 @@
             uuid="A"
             uuid_path="NOT_USED"
             root_uuid="A"
+            project_uuid="A"
             kee="project-one"
             name="Project One"
             qualifier="TRK"
@@ -20,6 +21,7 @@
             uuid="B"
             uuid_path="NOT_USED"
             root_uuid="B"
+            project_uuid="B"
             kee="project-two"
             name="Project Two"
             qualifier="TRK"
@@ -31,6 +33,7 @@
             uuid="C"
             uuid_path="NOT_USED"
             root_uuid="C"
+            project_uuid="C"
             kee="project-three"
             name="Project Three"
             qualifier="TRK"
@@ -42,6 +45,7 @@
             uuid="D"
             uuid_path="NOT_USED"
             root_uuid="D"
+            project_uuid="D"
             kee="project-four"
             name="Project Four"
             qualifier="TRK"
@@ -53,6 +57,7 @@
             uuid="E"
             uuid_path="NOT_USED"
             root_uuid="E"
+            project_uuid="E"
             kee="project-five"
             name="Project Five"
             qualifier="TRK"
@@ -64,6 +69,7 @@
             uuid="F"
             uuid_path="NOT_USED"
             root_uuid="F"
+            project_uuid="F"
             kee="view-six"
             name="View Six"
             qualifier="VW"
@@ -75,6 +81,7 @@
             uuid="G"
             uuid_path="NOT_USED"
             root_uuid="G"
+            project_uuid="G"
             kee="file-one"
             name="File One"
             qualifier="TRK"
index 4cdb013dfc9bfaeab821a3738aeda4c89e0090ec..c9465a2abd63b45fc94135666fbc198afe54ccb5 100644 (file)
@@ -25,6 +25,7 @@
             uuid="A"
             uuid_path="NOT_USED"
             root_uuid="A"
+            project_uuid="A"
             kee="org.codehaus.sonar:sonar"
             name="SonarQube"
             enabled="[true]"
@@ -33,6 +34,7 @@
             uuid="B"
             uuid_path="NOT_USED"
             root_uuid="B"
+            project_uuid="B"
             kee="org.codehaus.sonar-plugins.java:java"
             name="SonarQube Java"
             enabled="[true]"
@@ -41,6 +43,7 @@
             uuid="C"
             uuid_path="NOT_USED"
             root_uuid="C"
+            project_uuid="C"
             kee="disabled:project"
             name="Disabled Project"
             enabled="[false]"
index 8c619f53a08b78ad7773ec236c48483cb67a8547..189c0ee588dc5d3802bc734da4857ecc535302c9 100644 (file)
@@ -45,7 +45,6 @@ public class DbVersion64 implements DbVersion {
       .add(1615, "Create table RULES_METADATA", CreateRulesMetadata.class)
       .add(1616, "Populate table RULES_METADATA", PopulateRulesMetadata.class)
       .add(1617, "Drop metadata columns from RULES", DropMetadataColumnsFromRules.class)
-
       // ensure the index is made unique even on existing 6.4-SNAPSHOT instances (such as next or the developer machines)
       .add(1618, "Make index on ORGANIZATIONS.KEE unique", org.sonar.server.platform.db.migration.version.v63.MakeIndexOnOrganizationsKeeUnique.class)
       .add(1619, "Restore 'sonar-users' group", RestoreSonarUsersGroups.class)
@@ -60,6 +59,7 @@ public class DbVersion64 implements DbVersion {
       .add(1628, "Add columns CE_QUEUE.WORKER_UUID and EXECUTION_COUNT", AddCeQueueWorkerUuidAndExecutionCount.class)
       .add(1629, "Make CE_QUEUE.EXECUTION_COUNT not nullable", MakeCeQueueExecutionCountNotNullable.class)
       .add(1630, "Add columns CE_ACTIVITY.WORKER_UUID and EXECUTION_COUNT", AddCeActivityWorkerUuidAndExecutionCount.class)
-      .add(1631, "Make columns CE_ACTIVITY.EXECUTION_COUNT not nullable", MakeCeActivityExecutionCountNotNullable.class);
+      .add(1631, "Make columns CE_ACTIVITY.EXECUTION_COUNT not nullable", MakeCeActivityExecutionCountNotNullable.class)
+      .add(1632, "Make PROJECTS.PROJECT_UUID not nullable", MakeProjectUuidNotNullable.class);
   }
 }
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v64/MakeProjectUuidNotNullable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v64/MakeProjectUuidNotNullable.java
new file mode 100644 (file)
index 0000000..3506a3d
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.platform.db.migration.version.v64;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.DropIndexBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public class MakeProjectUuidNotNullable extends DdlChange {
+
+  private static final String TABLE_PROJECTS = "projects";
+  private static final String INDEX_PROJECTS_PROJECT_UUID = "projects_project_uuid";
+
+  public MakeProjectUuidNotNullable(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    VarcharColumnDef projectUuidCol = newVarcharColumnDefBuilder()
+      .setColumnName("project_uuid")
+      .setLimit(50)
+      .setIsNullable(false)
+      .build();
+
+    context.execute(new DropIndexBuilder(getDialect())
+      .setTable(TABLE_PROJECTS)
+      .setName(INDEX_PROJECTS_PROJECT_UUID)
+      .build());
+
+    context.execute(new AlterColumnsBuilder(getDialect(), TABLE_PROJECTS)
+      .updateColumn(projectUuidCol)
+      .build());
+
+    context.execute(new CreateIndexBuilder(getDialect())
+      .setTable(TABLE_PROJECTS)
+      .setName(INDEX_PROJECTS_PROJECT_UUID)
+      .setUnique(false).addColumn(projectUuidCol)
+      .build());
+  }
+
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v64/PurgeComponentsWithoutProjectUuid.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v64/PurgeComponentsWithoutProjectUuid.java
new file mode 100644 (file)
index 0000000..baa6c88
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.platform.db.migration.version.v64;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DataChange;
+import org.sonar.server.platform.db.migration.step.MassUpdate;
+
+public class PurgeComponentsWithoutProjectUuid extends DataChange {
+  public PurgeComponentsWithoutProjectUuid(Database db) {
+    super(db);
+  }
+
+  @Override
+  protected void execute(Context context) throws SQLException {
+    MassUpdate massUpdate = context.prepareMassUpdate();
+    massUpdate.select("select id,uuid from projects where project_uuid is null");
+    massUpdate.rowPluralName("rows in projects without project_uuid");
+    massUpdate.update("delete from duplications_index where analysis_uuid in (select uuid from snapshots where component_uuid=?)");
+    massUpdate.update("delete from project_measures where component_uuid=?");
+    massUpdate.update("delete from ce_activity where component_uuid=?");
+    massUpdate.update("delete from events where component_uuid=?");
+    massUpdate.update("delete from events where analysis_uuid in (select uuid from snapshots where component_uuid=?)");
+    massUpdate.update("delete from project_links where component_uuid=?");
+    massUpdate.update("delete from snapshots where component_uuid=?");
+    massUpdate.update("delete from issues where component_uuid=? or project_uuid=?");
+    massUpdate.update("delete from file_sources where file_uuid=? or project_uuid=?");
+    massUpdate.update("delete from group_roles where resource_id=?");
+    massUpdate.update("delete from user_roles where resource_id=?");
+    massUpdate.update("delete from properties where resource_id=?");
+    massUpdate.update("delete from projects where uuid=?");
+    massUpdate.execute((row, update, updateIndex) -> {
+      long componentId = row.getLong(1);
+      String componentUuid = row.getString(2);
+      switch (updateIndex) {
+        case 0:
+        case 1:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+          update.setString(1, componentUuid);
+          return true;
+        case 7:
+        case 8:
+          update.setString(1, componentUuid);
+          update.setString(2, componentUuid);
+          return true;
+        case 9:
+        case 10:
+        case 11:
+          update.setLong(1, componentId);
+          return true;
+        case 12:
+          update.setString(1, componentUuid);
+          return true;
+        default:
+          throw new IllegalArgumentException("Unsupported update index " + updateIndex);
+      }
+    });
+  }
+}
index e1cfd088962485ad551376a0465c35cab92de59d..bc815f2998a03f0f9563b66c45e19cefbdea58cf 100644 (file)
@@ -35,7 +35,6 @@ public class DbVersion64Test {
 
   @Test
   public void verify_migration_count() {
-    verifyMigrationCount(underTest, 32);
+    verifyMigrationCount(underTest, 33);
   }
 }
-
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v64/MakeProjectUuidNotNullableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v64/MakeProjectUuidNotNullableTest.java
new file mode 100644 (file)
index 0000000..0f5587d
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.platform.db.migration.version.v64;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import javax.annotation.Nullable;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.CoreDbTester;
+
+public class MakeProjectUuidNotNullableTest {
+  @Rule
+  public CoreDbTester db = CoreDbTester.createForSchema(MakeProjectUuidNotNullableTest.class, "projects_with_nullable_project_uuid.sql");
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private MakeProjectUuidNotNullable underTest = new MakeProjectUuidNotNullable(db.database());
+
+  @Test
+  public void execute_makes_column_project_uuid_not_nullable_on_empty_table() throws SQLException {
+    db.assertColumnDefinition("projects", "project_uuid", Types.VARCHAR, 50, true);
+
+    underTest.execute();
+
+    db.assertColumnDefinition("projects", "project_uuid", Types.VARCHAR, 50, false);
+  }
+
+  @Test
+  public void execute_makes_column_project_uuid_not_nullable_on_table_without_null_project_uuid() throws SQLException {
+    db.assertColumnDefinition("projects", "project_uuid", Types.VARCHAR, 50, true);
+    insertComponent("u1", "u1");
+    insertComponent("u2", "u1");
+
+    underTest.execute();
+
+    db.assertColumnDefinition("projects", "project_uuid", Types.VARCHAR, 50, false);
+  }
+
+  @Test
+  public void execute_fails_on_table_with_null_project_uuid() throws SQLException {
+    db.assertColumnDefinition("projects", "project_uuid", Types.VARCHAR, 50, true);
+    insertComponent("u1", "u1");
+    insertComponent("u2", "u1");
+    insertComponent("u3", null);
+
+    expectedException.expect(IllegalStateException.class);
+
+    underTest.execute();
+  }
+
+  private void insertComponent(String uuid, @Nullable String projectUuid) {
+    db.executeInsert(
+      "PROJECTS",
+      "ORGANIZATION_UUID", "org_" + uuid,
+      "UUID", uuid,
+      "UUID_PATH", "path_" + uuid,
+      "ROOT_UUID", "root_" + uuid,
+      "PROJECT_UUID", projectUuid);
+  }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v64/PurgeComponentsWithoutProjectUuidTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v64/PurgeComponentsWithoutProjectUuidTest.java
new file mode 100644 (file)
index 0000000..14a71ac
--- /dev/null
@@ -0,0 +1,360 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.platform.db.migration.version.v64;
+
+import java.sql.SQLException;
+import java.util.Random;
+import java.util.stream.Stream;
+import javax.annotation.Nullable;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.core.util.stream.MoreCollectors;
+import org.sonar.db.CoreDbTester;
+
+import static java.lang.String.valueOf;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class PurgeComponentsWithoutProjectUuidTest {
+
+  @Rule
+  public CoreDbTester db = CoreDbTester.createForSchema(PurgeComponentsWithoutProjectUuidTest.class, "projects_and_children_tables.sql");
+
+  private Random random = new Random();
+
+  private PurgeComponentsWithoutProjectUuid underTest = new PurgeComponentsWithoutProjectUuid(db.database());
+
+  @Test
+  public void execute_has_no_effect_when_every_tables_are_empty() throws SQLException {
+    underTest.execute();
+  }
+
+  @Test
+  public void execute_deletes_rows_from_PROJECTS_where_project_uuid_is_null() throws SQLException {
+    insertComponent("u1", "u1");
+    insertComponent("u2", "u1");
+    insertComponent("u3", null);
+
+    underTest.execute();
+
+    assertThat(db.select("select uuid from projects").stream()
+      .flatMap(map -> map.entrySet().stream())
+      .map(entry -> (String) entry.getValue())
+      .collect(MoreCollectors.toList()))
+        .containsOnly("u1", "u2");
+  }
+
+  @Test
+  public void executes_deletes_from_child_table_DUPLICATIONS_INDEX() throws SQLException {
+    insertComponent("u1", "foo");
+    insertComponent("u2", null);
+    Stream.of("u1", "u2").forEach(componentUuid -> {
+      String snapshotUuid = "s" + componentUuid;
+      insertSnapshot(snapshotUuid, componentUuid);
+      insertDuplicationsIndex(snapshotUuid, componentUuid);
+      insertDuplicationsIndex(snapshotUuid, "other_component" + random.nextInt(30));
+    });
+
+    underTest.execute();
+
+    assertThat(db.countSql("select count(1) from duplications_index where analysis_uuid = '" + "su1" + "'")).isEqualTo(2);
+    assertThat(db.countSql("select count(1) from duplications_index where analysis_uuid = '" + "su2" + "'")).isEqualTo(0);
+  }
+
+  @Test
+  public void execute_deletes_from_child_table_PROJECT_MEASURES() throws SQLException {
+    insertComponent("u1", "foo");
+    insertComponent("u2", null);
+    Stream.of("u1", "u2").forEach(componentUuid -> {
+      String snapshotUuid1 = "s1" + componentUuid;
+      insertSnapshot(snapshotUuid1, componentUuid);
+      insertProjectMeasure(snapshotUuid1, componentUuid);
+      String snapshotUuid2 = "s2" + componentUuid;
+      insertSnapshot(snapshotUuid2, "other_component" + random.nextInt(30));
+      insertProjectMeasure(snapshotUuid2, componentUuid);
+    });
+
+    underTest.execute();
+
+    assertThat(db.countSql("select count(1) from project_measures where component_uuid = '" + "u1" + "'")).isEqualTo(2);
+    assertThat(db.countSql("select count(1) from project_measures where component_uuid = '" + "u2" + "'")).isEqualTo(0);
+  }
+
+  @Test
+  public void execute_deletes_from_child_table_CE_ACTIVITY() throws SQLException {
+    insertComponent("u1", "foo");
+    insertComponent("u2", null);
+    Stream.of("u1", "u2").forEach(componentUuid -> {
+      insertCeActivity("ce1" + componentUuid, componentUuid);
+    });
+    insertCeActivity("ce2", null);
+
+    underTest.execute();
+
+    assertThat(db.countSql("select count(1) from ce_activity where component_uuid = '" + "u1" + "'")).isEqualTo(1);
+    assertThat(db.countSql("select count(1) from ce_activity where component_uuid = '" + "u2" + "'")).isEqualTo(0);
+    assertThat(db.countSql("select count(1) from ce_activity where component_uuid is null")).isEqualTo(1);
+  }
+
+  @Test
+  public void execute_deletes_from_child_table_EVENTS() throws SQLException {
+    insertComponent("u1", "foo");
+    insertComponent("u2", null);
+    String snapshotOfOtherComponent = "bar";
+    insertSnapshot(snapshotOfOtherComponent, "foo");
+    Stream.of("u1", "u2").forEach(componentUuid -> {
+      String snapshot1 = "s1" + componentUuid;
+      insertSnapshot(snapshot1, componentUuid);
+      insertEvent("e1" + componentUuid, snapshot1, null);
+      insertEvent("e2" + componentUuid, snapshot1, componentUuid);
+      insertEvent("e3" + componentUuid, snapshotOfOtherComponent, componentUuid);
+    });
+
+    underTest.execute();
+
+    assertThat(db.countSql("select count(1) from events where component_uuid = '" + "u1" + "'")).isEqualTo(2);
+    assertThat(db.countSql("select count(1) from events where analysis_uuid = '" + "s1u1" + "'")).isEqualTo(2);
+    assertThat(db.countSql("select count(1) from events where component_uuid = '" + "u2" + "'")).isEqualTo(0);
+    assertThat(db.countSql("select count(1) from events where analysis_uuid = '" + "s1u2" + "'")).isEqualTo(0);
+    assertThat(db.countSql("select count(1) from events where analysis_uuid = '" + snapshotOfOtherComponent + "'")).isEqualTo(1);
+  }
+
+  @Test
+  public void execute_deletes_from_child_table_PROJECT_LINKS() throws SQLException {
+    insertComponent("u1", "foo");
+    insertComponent("u2", null);
+    Stream.of("u1", "u2").forEach(componentUuid -> {
+      insertProjectLink(componentUuid);
+    });
+    insertProjectLink(null);
+
+    underTest.execute();
+
+    assertThat(db.countSql("select count(1) from project_links where component_uuid = '" + "u1" + "'")).isEqualTo(1);
+    assertThat(db.countSql("select count(1) from project_links where component_uuid = '" + "u2" + "'")).isEqualTo(0);
+    assertThat(db.countSql("select count(1) from project_links where component_uuid is null")).isEqualTo(1);
+  }
+
+  @Test
+  public void execute_deletes_from_child_table_SNAPSHOTS() throws SQLException {
+    insertComponent("u1", "foo");
+    insertComponent("u2", null);
+    Stream.of("u1", "u2").forEach(componentUuid -> {
+      insertSnapshot("s1" + componentUuid, componentUuid);
+    });
+
+    underTest.execute();
+
+    assertThat(db.countSql("select count(1) from snapshots where component_uuid = '" + "u1" + "'")).isEqualTo(1);
+    assertThat(db.countSql("select count(1) from snapshots where component_uuid = '" + "u2" + "'")).isEqualTo(0);
+  }
+
+  @Test
+  public void execute_deletes_from_child_table_ISSUES() throws SQLException {
+    insertComponent("u1", "foo");
+    insertComponent("u2", null);
+    Stream.of("u1", "u2").forEach(componentUuid -> {
+      insertIssue("s1" + componentUuid, componentUuid);
+    });
+    insertIssue("s2", null);
+
+    underTest.execute();
+
+    assertThat(db.countSql("select count(1) from issues where component_uuid = '" + "u1" + "'")).isEqualTo(1);
+    assertThat(db.countSql("select count(1) from issues where component_uuid = '" + "u2" + "'")).isEqualTo(0);
+    assertThat(db.countSql("select count(1) from issues where component_uuid is null")).isEqualTo(1);
+  }
+
+  @Test
+  public void execute_deletes_from_child_table_FILE_SOURCES() throws SQLException {
+    insertComponent("u1", "foo");
+    insertComponent("u2", null);
+    Stream.of("u1", "u2").forEach(componentUuid -> {
+      insertFileSource(componentUuid, "foo");
+      insertFileSource("bar", componentUuid);
+      insertFileSource(componentUuid, componentUuid);
+    });
+
+    underTest.execute();
+
+    assertThat(db.countSql("select count(1) from file_sources where project_uuid = '" + "u1" + "' or file_uuid = '" + "u1" + "'")).isEqualTo(3);
+    assertThat(db.countSql("select count(1) from file_sources where project_uuid = '" + "u2" + "' or file_uuid = '" + "u2" + "'")).isEqualTo(0);
+  }
+
+  @Test
+  public void execute_deletes_from_child_table_GROUP_ROLES() throws SQLException {
+    long project1 = insertComponent("u1", "foo");
+    long project2 = insertComponent("u2", null);
+    Stream.of(project1, project2).forEach(componentId -> {
+      insertGroupRole(componentId);
+    });
+    insertGroupRole(null);
+
+    underTest.execute();
+
+    assertThat(db.countSql("select count(1) from group_roles where RESOURCE_ID = " + project1)).isEqualTo(1);
+    assertThat(db.countSql("select count(1) from group_roles where RESOURCE_ID = " + project2)).isEqualTo(0);
+    assertThat(db.countSql("select count(1) from group_roles where RESOURCE_ID is null")).isEqualTo(1);
+  }
+
+  @Test
+  public void execute_deletes_from_child_table_USER_ROLES() throws SQLException {
+    long project1 = insertComponent("u1", "foo");
+    long project2 = insertComponent("u2", null);
+    Stream.of(project1, project2).forEach(componentId -> {
+      insertUserRole(componentId);
+    });
+    insertUserRole(null);
+
+    underTest.execute();
+
+    assertThat(db.countSql("select count(1) from user_roles where resource_id = " + project1)).isEqualTo(1);
+    assertThat(db.countSql("select count(1) from user_roles where resource_id = " + project2)).isEqualTo(0);
+    assertThat(db.countSql("select count(1) from user_roles where resource_id is null")).isEqualTo(1);
+  }
+
+  @Test
+  public void execute_deletes_from_child_table_PROPERTIES() throws SQLException {
+    long project1 = insertComponent("u1", "foo");
+    long project2 = insertComponent("u2", null);
+    Stream.of(project1, project2).forEach(componentId -> {
+      insertProperties(componentId);
+    });
+    insertProperties(null);
+
+    underTest.execute();
+
+    assertThat(db.countSql("select count(1) from properties where resource_id = " + project1)).isEqualTo(1);
+    assertThat(db.countSql("select count(1) from properties where resource_id = " + project2)).isEqualTo(0);
+    assertThat(db.countSql("select count(1) from properties where resource_id is null")).isEqualTo(1);
+  }
+
+  private long insertComponent(String uuid, @Nullable String projectUuid) {
+    db.executeInsert(
+      "PROJECTS",
+      "ORGANIZATION_UUID", "org_" + uuid,
+      "UUID", uuid,
+      "UUID_PATH", "path_" + uuid,
+      "ROOT_UUID", "root_" + uuid,
+      "PROJECT_UUID", projectUuid);
+    return (long) db.selectFirst("select id as \"ID\" from projects where uuid='" + uuid + "'").get("ID");
+  }
+
+  private void insertSnapshot(String uuid, String componentUuid) {
+    db.executeInsert(
+      "SNAPSHOTS",
+      "UUID", uuid,
+      "COMPONENT_UUID", componentUuid,
+      "STATUS", random.nextBoolean() ? "U" : "P",
+      "ISLAST", valueOf(random.nextBoolean()));
+  }
+
+  private void insertDuplicationsIndex(String snapshotUuid, String componentUuid) {
+    db.executeInsert(
+      "DUPLICATIONS_INDEX",
+      "ANALYSIS_UUID", snapshotUuid,
+      "COMPONENT_UUID", componentUuid,
+      "HASH", "hash_" + random.nextInt(100),
+      "INDEX_IN_FILE", valueOf(random.nextInt(50)),
+      "START_LINE", valueOf(random.nextInt(50)),
+      "END_LINE", valueOf(random.nextInt(50)));
+  }
+
+  private void insertProjectMeasure(String snapshotUuid, String componentUuid) {
+    db.executeInsert(
+      "PROJECT_MEASURES",
+      "METRIC_ID", valueOf(random.nextInt(50)),
+      "COMPONENT_UUID", componentUuid,
+      "ANALYSIS_UUID", snapshotUuid);
+  }
+
+  private void insertCeActivity(String uuid, @Nullable String componentUuid) {
+    db.executeInsert(
+      "CE_ACTIVITY",
+      "UUID", uuid,
+      "TASK_TYPE", "type_" + random.nextInt(10),
+      "STATUS", "status" + random.nextInt(10),
+      "COMPONENT_UUID", componentUuid,
+      "IS_LAST", valueOf(random.nextBoolean()),
+      "IS_LAST_KEY", "isLastKey" + random.nextInt(20),
+      "SUBMITTED_AT", valueOf(random.nextInt(555)),
+      "CREATED_AT", valueOf(random.nextInt(555)),
+      "UPDATED_AT", valueOf(random.nextInt(555)));
+  }
+
+  private void insertEvent(String uuid, String analysisUuid, @Nullable String componentUuid) {
+    db.executeInsert(
+      "EVENTS",
+      "UUID", uuid,
+      "ANALYSIS_UUID", analysisUuid,
+      "COMPONENT_UUID", componentUuid,
+      "EVENT_DATE", random.nextInt(),
+      "CREATED_AT", random.nextInt());
+  }
+
+  private void insertProjectLink(@Nullable String componentUuid) {
+    db.executeInsert(
+      "PROJECT_LINKS",
+      "COMPONENT_UUID", componentUuid,
+      "HREF", "href_" + random.nextInt());
+  }
+
+  private void insertIssue(String s, @Nullable String componentUuid) {
+    db.executeInsert(
+      "ISSUES",
+      "KEE", s,
+      "COMPONENT_UUID", componentUuid,
+      "MANUAL_SEVERITY", valueOf(random.nextBoolean()));
+  }
+
+  private void insertFileSource(String projectUuid, String fileUuid) {
+    db.executeInsert(
+      "FILE_SOURCES",
+      "PROJECT_UUID", projectUuid,
+      "FILE_UUID", fileUuid,
+      "CREATED_AT", valueOf(random.nextInt(555)),
+      "UPDATED_AT", valueOf(random.nextInt(555)));
+  }
+
+  private void insertGroupRole(@Nullable Long componentId) {
+    db.executeInsert(
+      "GROUP_ROLES",
+      "ORGANIZATION_UUID", "org_" + random.nextInt(20),
+      "GROUP_ID", random.nextBoolean() ? null : random.nextInt(),
+      "RESOURCE_ID", componentId == null ? null : valueOf(componentId),
+      "ROLE", "role_" + random.nextInt(10));
+  }
+
+  private void insertUserRole(@Nullable Long componentId) {
+    db.executeInsert(
+      "USER_ROLES",
+      "ORGANIZATION_UUID", "org_" + random.nextInt(20),
+      "USER_ID", random.nextBoolean() ? null : random.nextInt(),
+      "RESOURCE_ID", componentId == null ? null : valueOf(componentId),
+      "ROLE", "role_" + random.nextInt(10));
+  }
+
+  private void insertProperties(@Nullable Long componentId) {
+    db.executeInsert(
+        "PROPERTIES",
+        "PROP_KEY", "prop_" + random.nextInt(15),
+        "RESOURCE_ID", componentId == null ? null : valueOf(componentId),
+        "IS_EMPTY", valueOf(random.nextBoolean()));
+  }
+}
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v64/MakeProjectUuidNotNullableTest/projects_with_nullable_project_uuid.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v64/MakeProjectUuidNotNullableTest/projects_with_nullable_project_uuid.sql
new file mode 100644 (file)
index 0000000..95331fa
--- /dev/null
@@ -0,0 +1,44 @@
+CREATE TABLE "PROJECTS" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
+  "KEE" VARCHAR(400),
+  "UUID" VARCHAR(50) NOT NULL,
+  "UUID_PATH" VARCHAR(1500) NOT NULL,
+  "ROOT_UUID" VARCHAR(50) NOT NULL,
+  "PROJECT_UUID" VARCHAR(50),
+  "MODULE_UUID" VARCHAR(50),
+  "MODULE_UUID_PATH" VARCHAR(1500),
+  "NAME" VARCHAR(2000),
+  "DESCRIPTION" VARCHAR(2000),
+  "TAGS" VARCHAR(500),
+  "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE,
+  "SCOPE" VARCHAR(3),
+  "QUALIFIER" VARCHAR(10),
+  "DEPRECATED_KEE" VARCHAR(400),
+  "PATH" VARCHAR(2000),
+  "LANGUAGE" VARCHAR(20),
+  "COPY_COMPONENT_UUID" VARCHAR(50),
+  "LONG_NAME" VARCHAR(2000),
+  "DEVELOPER_UUID" VARCHAR(50),
+  "CREATED_AT" TIMESTAMP,
+  "AUTHORIZATION_UPDATED_AT" BIGINT,
+  "B_CHANGED" BOOLEAN,
+  "B_COPY_COMPONENT_UUID" VARCHAR(50),
+  "B_DESCRIPTION" VARCHAR(2000),
+  "B_ENABLED" BOOLEAN,
+  "B_UUID_PATH" VARCHAR(1500),
+  "B_LANGUAGE" VARCHAR(20),
+  "B_LONG_NAME" VARCHAR(500),
+  "B_MODULE_UUID" VARCHAR(50),
+  "B_MODULE_UUID_PATH" VARCHAR(1500),
+  "B_NAME" VARCHAR(500),
+  "B_PATH" VARCHAR(2000),
+  "B_QUALIFIER" VARCHAR(10)
+);
+CREATE INDEX "PROJECTS_ORGANIZATION" ON "PROJECTS" ("ORGANIZATION_UUID");
+CREATE UNIQUE INDEX "PROJECTS_KEE" ON "PROJECTS" ("KEE");
+CREATE INDEX "PROJECTS_ROOT_UUID" ON "PROJECTS" ("ROOT_UUID");
+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");
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v64/PurgeComponentsWithoutProjectUuidTest/projects_and_children_tables.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v64/PurgeComponentsWithoutProjectUuidTest/projects_and_children_tables.sql
new file mode 100644 (file)
index 0000000..e987c57
--- /dev/null
@@ -0,0 +1,242 @@
+CREATE TABLE "PROJECTS" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
+  "KEE" VARCHAR(400),
+  "UUID" VARCHAR(50) NOT NULL,
+  "UUID_PATH" VARCHAR(1500) NOT NULL,
+  "ROOT_UUID" VARCHAR(50) NOT NULL,
+  "PROJECT_UUID" VARCHAR(50),
+  "MODULE_UUID" VARCHAR(50),
+  "MODULE_UUID_PATH" VARCHAR(1500),
+  "NAME" VARCHAR(2000),
+  "DESCRIPTION" VARCHAR(2000),
+  "TAGS" VARCHAR(500),
+  "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE,
+  "SCOPE" VARCHAR(3),
+  "QUALIFIER" VARCHAR(10),
+  "DEPRECATED_KEE" VARCHAR(400),
+  "PATH" VARCHAR(2000),
+  "LANGUAGE" VARCHAR(20),
+  "COPY_COMPONENT_UUID" VARCHAR(50),
+  "LONG_NAME" VARCHAR(2000),
+  "DEVELOPER_UUID" VARCHAR(50),
+  "CREATED_AT" TIMESTAMP,
+  "AUTHORIZATION_UPDATED_AT" BIGINT,
+  "B_CHANGED" BOOLEAN,
+  "B_COPY_COMPONENT_UUID" VARCHAR(50),
+  "B_DESCRIPTION" VARCHAR(2000),
+  "B_ENABLED" BOOLEAN,
+  "B_UUID_PATH" VARCHAR(1500),
+  "B_LANGUAGE" VARCHAR(20),
+  "B_LONG_NAME" VARCHAR(500),
+  "B_MODULE_UUID" VARCHAR(50),
+  "B_MODULE_UUID_PATH" VARCHAR(1500),
+  "B_NAME" VARCHAR(500),
+  "B_PATH" VARCHAR(2000),
+  "B_QUALIFIER" VARCHAR(10)
+);
+CREATE INDEX "PROJECTS_ORGANIZATION" ON "PROJECTS" ("ORGANIZATION_UUID");
+CREATE UNIQUE INDEX "PROJECTS_KEE" ON "PROJECTS" ("KEE");
+CREATE INDEX "PROJECTS_ROOT_UUID" ON "PROJECTS" ("ROOT_UUID");
+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");
+
+CREATE TABLE "DUPLICATIONS_INDEX" (
+  "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "ANALYSIS_UUID" VARCHAR(50) NOT NULL,
+  "COMPONENT_UUID" VARCHAR(50) NOT NULL,
+  "HASH" VARCHAR(50) NOT NULL,
+  "INDEX_IN_FILE" INTEGER NOT NULL,
+  "START_LINE" INTEGER NOT NULL,
+  "END_LINE" INTEGER NOT NULL
+);
+CREATE INDEX "DUPLICATIONS_INDEX_HASH" ON "DUPLICATIONS_INDEX" ("HASH");
+CREATE INDEX "DUPLICATION_ANALYSIS_COMPONENT" ON "DUPLICATIONS_INDEX" ("ANALYSIS_UUID", "COMPONENT_UUID");
+
+CREATE TABLE "PROJECT_MEASURES" (
+  "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "VALUE" DOUBLE,
+  "METRIC_ID" INTEGER NOT NULL,
+  "COMPONENT_UUID" VARCHAR(50) NOT NULL,
+  "ANALYSIS_UUID" VARCHAR(50) NOT NULL,
+  "TEXT_VALUE" VARCHAR(4000),
+  "ALERT_STATUS" VARCHAR(5),
+  "ALERT_TEXT" VARCHAR(4000),
+  "DESCRIPTION" VARCHAR(4000),
+  "PERSON_ID" INTEGER,
+  "VARIATION_VALUE_1" DOUBLE,
+  "VARIATION_VALUE_2" DOUBLE,
+  "VARIATION_VALUE_3" DOUBLE,
+  "VARIATION_VALUE_4" DOUBLE,
+  "VARIATION_VALUE_5" DOUBLE,
+  "MEASURE_DATA" BINARY
+);
+CREATE INDEX "MEASURES_COMPONENT_UUID" ON "PROJECT_MEASURES" ("COMPONENT_UUID");
+CREATE INDEX "MEASURES_ANALYSIS_METRIC" ON "PROJECT_MEASURES" ("ANALYSIS_UUID", "METRIC_ID");
+CREATE INDEX "MEASURES_PERSON" ON "PROJECT_MEASURES" ("PERSON_ID");
+
+CREATE TABLE "CE_ACTIVITY" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "UUID" VARCHAR(40) NOT NULL,
+  "TASK_TYPE" VARCHAR(15) NOT NULL,
+  "COMPONENT_UUID" VARCHAR(40) NULL,
+  "ANALYSIS_UUID" VARCHAR(50) NULL,
+  "STATUS" VARCHAR(15) NOT NULL,
+  "IS_LAST" BOOLEAN NOT NULL,
+  "IS_LAST_KEY" VARCHAR(55) NOT NULL,
+  "SUBMITTER_LOGIN" VARCHAR(255) NULL,
+  "SUBMITTED_AT" BIGINT NOT NULL,
+  "STARTED_AT" BIGINT NULL,
+  "EXECUTED_AT" BIGINT NULL,
+  "CREATED_AT" BIGINT NOT NULL,
+  "UPDATED_AT" BIGINT NOT NULL,
+  "EXECUTION_TIME_MS" BIGINT NULL,
+  "ERROR_MESSAGE" VARCHAR(1000),
+  "ERROR_STACKTRACE" CLOB(2147483647)
+);
+CREATE UNIQUE INDEX "CE_ACTIVITY_UUID" ON "CE_ACTIVITY" ("UUID");
+CREATE INDEX "CE_ACTIVITY_COMPONENT_UUID" ON "CE_ACTIVITY" ("COMPONENT_UUID");
+CREATE INDEX "CE_ACTIVITY_ISLASTKEY" ON "CE_ACTIVITY" ("IS_LAST_KEY");
+CREATE INDEX "CE_ACTIVITY_ISLAST_STATUS" ON "CE_ACTIVITY" ("IS_LAST", "STATUS");
+
+CREATE TABLE "EVENTS" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "UUID" VARCHAR(40) NOT NULL,
+  "NAME" VARCHAR(400),
+  "ANALYSIS_UUID" VARCHAR(50) NOT NULL,
+  "COMPONENT_UUID" VARCHAR(50),
+  "CATEGORY" VARCHAR(50),
+  "EVENT_DATE" BIGINT NOT NULL,
+  "CREATED_AT" BIGINT NOT NULL,
+  "DESCRIPTION" VARCHAR(4000),
+  "EVENT_DATA"  VARCHAR(4000)
+);
+CREATE INDEX "EVENTS_ANALYSIS" ON "EVENTS" ("ANALYSIS_UUID");
+CREATE INDEX "EVENTS_COMPONENT_UUID" ON "EVENTS" ("COMPONENT_UUID");
+CREATE UNIQUE INDEX "EVENTS_UUID" ON "EVENTS" ("UUID");
+
+CREATE TABLE "PROJECT_LINKS" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "COMPONENT_UUID" VARCHAR(50),
+  "LINK_TYPE" VARCHAR(20),
+  "NAME" VARCHAR(128),
+  "HREF" VARCHAR(2048) NOT NULL
+);
+
+CREATE TABLE "SNAPSHOTS" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "UUID" VARCHAR(50) NOT NULL,
+  "CREATED_AT" BIGINT,
+  "BUILD_DATE" BIGINT,
+  "COMPONENT_UUID" VARCHAR(50) NOT NULL,
+  "STATUS" VARCHAR(4) NOT NULL DEFAULT 'U',
+  "PURGE_STATUS" INTEGER,
+  "ISLAST" BOOLEAN NOT NULL DEFAULT FALSE,
+  "VERSION" VARCHAR(500),
+  "PERIOD1_MODE" VARCHAR(100),
+  "PERIOD1_PARAM" VARCHAR(100),
+  "PERIOD1_DATE" BIGINT,
+  "PERIOD2_MODE" VARCHAR(100),
+  "PERIOD2_PARAM" VARCHAR(100),
+  "PERIOD2_DATE" BIGINT,
+  "PERIOD3_MODE" VARCHAR(100),
+  "PERIOD3_PARAM" VARCHAR(100),
+  "PERIOD3_DATE" BIGINT,
+  "PERIOD4_MODE" VARCHAR(100),
+  "PERIOD4_PARAM" VARCHAR(100),
+  "PERIOD4_DATE" BIGINT,
+  "PERIOD5_MODE" VARCHAR(100),
+  "PERIOD5_PARAM" VARCHAR(100),
+  "PERIOD5_DATE" BIGINT
+);
+CREATE INDEX "SNAPSHOT_COMPONENT" ON "SNAPSHOTS" ("COMPONENT_UUID");
+CREATE UNIQUE INDEX "ANALYSES_UUID" ON "SNAPSHOTS" ("UUID");
+
+CREATE TABLE "ISSUES" (
+  "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "KEE" VARCHAR(50) UNIQUE NOT NULL,
+  "COMPONENT_UUID" VARCHAR(50),
+  "PROJECT_UUID" VARCHAR(50),
+  "RULE_ID" INTEGER,
+  "SEVERITY" VARCHAR(10),
+  "MANUAL_SEVERITY" BOOLEAN NOT NULL,
+  "MESSAGE" VARCHAR(4000),
+  "LINE" INTEGER,
+  "GAP" DOUBLE,
+  "EFFORT" INTEGER,
+  "STATUS" VARCHAR(20),
+  "RESOLUTION" VARCHAR(20),
+  "CHECKSUM" VARCHAR(1000),
+  "REPORTER" VARCHAR(255),
+  "ASSIGNEE" VARCHAR(255),
+  "AUTHOR_LOGIN" VARCHAR(255),
+  "ACTION_PLAN_KEY" VARCHAR(50) NULL,
+  "ISSUE_ATTRIBUTES" VARCHAR(4000),
+  "TAGS" VARCHAR(4000),
+  "ISSUE_CREATION_DATE" BIGINT,
+  "ISSUE_CLOSE_DATE" BIGINT,
+  "ISSUE_UPDATE_DATE" BIGINT,
+  "CREATED_AT" BIGINT,
+  "UPDATED_AT" BIGINT,
+  "LOCATIONS" BLOB,
+  "ISSUE_TYPE" TINYINT
+);
+CREATE UNIQUE INDEX "ISSUES_KEE" ON "ISSUES" ("KEE");
+CREATE INDEX "ISSUES_COMPONENT_UUID" ON "ISSUES" ("COMPONENT_UUID");
+CREATE INDEX "ISSUES_PROJECT_UUID" ON "ISSUES" ("PROJECT_UUID");
+CREATE INDEX "ISSUES_RULE_ID" ON "ISSUES" ("RULE_ID");
+CREATE INDEX "ISSUES_RESOLUTION" ON "ISSUES" ("RESOLUTION");
+CREATE INDEX "ISSUES_ASSIGNEE" ON "ISSUES" ("ASSIGNEE");
+CREATE INDEX "ISSUES_CREATION_DATE" ON "ISSUES" ("ISSUE_CREATION_DATE");
+CREATE INDEX "ISSUES_UPDATED_AT" ON "ISSUES" ("UPDATED_AT");
+
+CREATE TABLE "FILE_SOURCES" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "PROJECT_UUID" VARCHAR(50) NOT NULL,
+  "FILE_UUID" VARCHAR(50) NOT NULL,
+  "LINE_HASHES" CLOB(2147483647),
+  "BINARY_DATA" BLOB,
+  "DATA_TYPE" VARCHAR(20),
+  "DATA_HASH" VARCHAR(50),
+  "SRC_HASH" VARCHAR(50),
+  "REVISION" VARCHAR(100),
+  "CREATED_AT" BIGINT NOT NULL,
+  "UPDATED_AT" BIGINT NOT NULL
+);
+CREATE INDEX "FILE_SOURCES_PROJECT_UUID" ON "FILE_SOURCES" ("PROJECT_UUID");
+CREATE UNIQUE INDEX "FILE_SOURCES_UUID_TYPE" ON "FILE_SOURCES" ("FILE_UUID", "DATA_TYPE");
+CREATE INDEX "FILE_SOURCES_UPDATED_AT" ON "FILE_SOURCES" ("UPDATED_AT");
+
+CREATE TABLE "GROUP_ROLES" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
+  "GROUP_ID" INTEGER,
+  "RESOURCE_ID" INTEGER,
+  "ROLE" VARCHAR(64) NOT NULL
+);
+CREATE INDEX "GROUP_ROLES_RESOURCE" ON "GROUP_ROLES" ("RESOURCE_ID");
+CREATE UNIQUE INDEX "UNIQ_GROUP_ROLES" ON "GROUP_ROLES" ("ORGANIZATION_UUID", "GROUP_ID", "RESOURCE_ID", "ROLE");
+
+CREATE TABLE "USER_ROLES" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
+  "USER_ID" INTEGER,
+  "RESOURCE_ID" INTEGER,
+  "ROLE" VARCHAR(64) NOT NULL
+);
+CREATE INDEX "USER_ROLES_RESOURCE" ON "USER_ROLES" ("RESOURCE_ID");
+CREATE INDEX "USER_ROLES_USER" ON "USER_ROLES" ("USER_ID");
+
+CREATE TABLE "PROPERTIES" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "PROP_KEY" VARCHAR(512) NOT NULL,
+  "RESOURCE_ID" INTEGER,
+  "USER_ID" INTEGER,
+  "IS_EMPTY" BOOLEAN NOT NULL,
+  "TEXT_VALUE" VARCHAR(4000),
+  "CLOB_VALUE" CLOB(2147483647),
+  "CREATED_AT" BIGINT
+);
+CREATE INDEX "PROPERTIES_KEY" ON "PROPERTIES" ("PROP_KEY");
index d1bf434a1fc20a614a321a8d0232bf9386f46298..49adcb22cedd7243f1b4c5d5a472a3610b0439dd 100644 (file)
@@ -112,6 +112,7 @@ public class ProjectDataLoaderTest {
         .setUuid(uuid)
         .setUuidPath(uuid + ".")
         .setRootUuid(uuid)
+        .setProjectUuid(uuid)
         .setScope(scope)
         .setQualifier(qualifier)
         .setKey(key));
index cfd721f03c8ed43c072d8f9a15632223c5c0522a..1906f71b5e4a557339475e6d00a3a82b16745b66 100644 (file)
@@ -385,7 +385,8 @@ public class PersistMeasuresStepTest extends BaseStepTest {
       .setKey(key)
       .setUuid(uuid)
       .setUuidPath(uuid + ".")
-      .setRootUuid(uuid);
+      .setRootUuid(uuid)
+      .setProjectUuid(uuid);
     dbClient.componentDao().insert(dbTester.getSession(), componentDto);
     return componentDto;
   }
index 7463d6bdb69a172b1334d7501c87c8dd12ec62c9..06d0a56041e7b2f333aae560bda7ec3109472e42 100644 (file)
@@ -154,7 +154,8 @@ public class DeleteActionTest {
       .setUuid(projectUuid)
       .setKey(projectKey)
       .setUuidPath("")
-      .setRootUuid(""));
+      .setRootUuid("")
+      .setProjectUuid(""));
   }
 
   private ComponentDto insertProject() {
index 0d5127a2166677733e259ddbb0bb4800b67d41c5..09c8dbd8eae55bc1a78a661d9d56019da7bd4a3b 100644 (file)
@@ -5,6 +5,7 @@
             uuid_path="NOT_USED"
             id="1"
             root_uuid="ABCD"
+            project_uuid="ABCD"
             kee="ROOT_KEY"/>
 
 </dataset>
index 74978f0071c737b3c250441ed484b69360b09143..96e2d645fb0cdf267ddaa011340b11ba04191b09 100644 (file)
@@ -11,6 +11,7 @@
             uuid="ABCD"
             uuid_path="NOT_USED"
             root_uuid="ABCD"
+            project_uuid="ABCD"
             id="1"
             kee="ROOT_KEY"
             name="project"/>
index afc4f39f650264b9526159c39d6d90ef6fa7b54e..e8c8a98f1d630ea80d10040ee3140799c39d77ff 100644 (file)
@@ -12,7 +12,8 @@
             kee="ROOT_KEY"
             uuid="ABCD"
             uuid_path="NOT_USED"
-            root_uuid="ABCD"/>
+            root_uuid="ABCD"
+            project_uuid="ABCD"/>
 
   <!-- 2008-11-11 -->
   <!-- Version 0.9 -->
index 78f7b2d2e4fbf12f1c3eb2eae2db0f5a3a04cbcf..a98ff3c3813ac09fd4c2c64dccf88843001450fd 100644 (file)
@@ -11,6 +11,7 @@
             uuid="ABCD"
             uuid_path="NOT_USED"
             root_uuid="ABCD"
+            project_uuid="ABCD"
             id="1"
             kee="ROOT_KEY"
             name="project"/>
index df806896d91fe496e2fb79c365f2502b50a709fd..5c8540038f24e3e972956478eeabce73d9950ba6 100644 (file)
@@ -13,7 +13,8 @@
             name="project"
             uuid="ABCD"
             uuid_path="NOT_USED"
-            root_uuid="ABCD"/>
+            root_uuid="ABCD"
+            project_uuid="ABCD"/>
 
   <!-- 2008-11-11 -->
   <!-- Version 0.9 -->
index 912630ef352aebe7111e2dcf6f99967cb636cc7e..646067a29abc9772225bb7c2f8a3a7f67f8efb21 100644 (file)
@@ -11,6 +11,7 @@
             uuid="ABCD"
             uuid_path="NOT_USED"
             root_uuid="ABCD"
+            project_uuid="ABCD"
             id="10"
             scope="PRJ"
             qualifier="TRK"
@@ -25,6 +26,7 @@
             uuid="BCDE"
             uuid_path="NOT_USED"
             root_uuid="ABCD"
+            project_uuid="ABCD"
             id="100"
             scope="FIL"
             qualifier="CLA"
index a2f644868a251e2cddb2b9d7b9aad150c4f9dcd3..fcba2ae688f70570d3af699fc469bb558716af2b 100644 (file)
             uuid_path="NOT_USED"
             id="1"
             kee="struts"
-            root_uuid="ABCD"/>
+            root_uuid="ABCD"
+            project_uuid="ABCD"/>
   <projects organization_uuid="org1"
             uuid="BCDE"
             uuid_path="NOT_USED"
             id="2"
             kee="struts:Action.java"
-            root_uuid="ABCD"/>
+            root_uuid="ABCD"
+            project_uuid="ABCD"/>
 
   <snapshots id="1"
              uuid="u1"
index 912630ef352aebe7111e2dcf6f99967cb636cc7e..646067a29abc9772225bb7c2f8a3a7f67f8efb21 100644 (file)
@@ -11,6 +11,7 @@
             uuid="ABCD"
             uuid_path="NOT_USED"
             root_uuid="ABCD"
+            project_uuid="ABCD"
             id="10"
             scope="PRJ"
             qualifier="TRK"
@@ -25,6 +26,7 @@
             uuid="BCDE"
             uuid_path="NOT_USED"
             root_uuid="ABCD"
+            project_uuid="ABCD"
             id="100"
             scope="FIL"
             qualifier="CLA"
index f5fd116300083394361110c577e9a8b8553409bf..00e7637b8dcb8ef7f1c8f5d593910a0696be112d 100644 (file)
@@ -11,6 +11,7 @@
             uuid="ABCD"
             uuid_path="NOT_USED"
             root_uuid="ABCD"
+            project_uuid="ABCD"
             id="10"
             scope="PRJ"
             qualifier="TRK"
@@ -25,6 +26,7 @@
             uuid="BCDE"
             uuid_path="NOT_USED"
             root_uuid="ABCD"
+            project_uuid="ABCD"
             id="100"
             scope="FIL"
             qualifier="CLA"
index d2b73d2647dafca144fc28ae78c1ed7277a8cf59..2307ecfe86fdafaa50ab8fc2cbbbe06e247b4ef2 100644 (file)
@@ -10,6 +10,7 @@
             uuid="THE_PROJECT"
             uuid_path="NOT_USED"
             root_uuid="THE_PROJECT"
+            project_uuid="THE_PROJECT"
             module_uuid="[null]"
             module_uuid_path="."
             path="[null]"
@@ -22,6 +23,7 @@
             uuid="THE_FILE"
             uuid_path="NOT_USED"
             root_uuid="THE_PROJECT"
+            project_uuid="THE_PROJECT"
             module_uuid="THE_PROJECT"
             module_uuid_path=".THE_PROJECT."
             path="src/main/java/TheFile.java"
index f3cb6776b5704ca006db695e5909090a8d27635b..b9a05b8e4ca643898bf6b2aafd998dc7cb0350c4 100644 (file)
@@ -11,6 +11,7 @@
             uuid="THE_PROJECT_1"
             uuid_path="NOT_USED"
             root_uuid="THE_PROJECT_1"
+            project_uuid="THE_PROJECT_1"
             module_uuid="[null]"
             module_uuid_path="."
             path="[null]"
@@ -23,6 +24,7 @@
             uuid="THE_FILE_1"
             uuid_path="NOT_USED"
             root_uuid="THE_PROJECT_1"
+            project_uuid="THE_PROJECT_1"
             module_uuid="THE_PROJECT_1"
             module_uuid_path=".THE_PROJECT_1."
             path="src/main/java/TheFile.java"
index ba40134ef9d5e98ff8af90f3e5f2b6cacf799685..8dac8110ecfb0cf0b887101bf97d724ec0fcd346 100644 (file)
@@ -10,6 +10,7 @@
             uuid="PROJECT"
             uuid_path="NOT_USED"
             root_uuid="MODULE"
+            project_uuid="MODULE"
             path="[null]"
             module_uuid_path=".PROJECT."
             id="10"
@@ -21,6 +22,7 @@
             uuid="MODULE"
             uuid_path="NOT_USED"
             root_uuid="PROJECT"
+            project_uuid="PROJECT"
             path="struts-core"
             module_uuid_path=".PROJECT.MODULE."
             id="11"
@@ -32,6 +34,7 @@
             uuid="FILE"
             uuid_path="NOT_USED"
             root_uuid="MODULE"
+            project_uuid="MODULE"
             path="src/main/java/Action.java"
             module_uuid_path=".PROJECT.MODULE."
             id="100"
@@ -43,6 +46,7 @@
             uuid="ROOT_FILE"
             uuid_path="NOT_USED"
             root_uuid="MODULE"
+            project_uuid="MODULE"
             path="pom.xml"
             module_uuid_path=".PROJECT.MODULE."
             id="101"
index b49c887546e176c84fe140c281cbd8d3809a55d5..740d4c92b476c417c858fc4b54d286c2c85614cc 100644 (file)
@@ -10,6 +10,7 @@
             uuid="PROJECT"
             uuid_path="NOT_USED"
             root_uuid="MODULE"
+            project_uuid="MODULE"
             path="[null]"
             module_uuid_path=".PROJECT."
             id="10"
@@ -21,6 +22,7 @@
             uuid="MODULE"
             uuid_path="NOT_USED"
             root_uuid="PROJECT"
+            project_uuid="PROJECT"
             path="struts-core"
             module_uuid_path=".PROJECT.MODULE."
             id="11"
@@ -32,6 +34,7 @@
             uuid="FILE"
             uuid_path="NOT_USED"
             root_uuid="MODULE"
+            project_uuid="MODULE"
             path="src/main/java/Action.java"
             module_uuid_path=".PROJECT.MODULE."
             id="100"
@@ -43,6 +46,7 @@
             uuid="ROOT_FILE"
             uuid_path="NOT_USED"
             root_uuid="MODULE"
+            project_uuid="MODULE"
             path="pom.xml"
             module_uuid_path=".PROJECT.MODULE."
             id="101"
index 6364fe7b66203614679ab8fe523e448dcf39f7ce..8f234e0ee696989276846071ffa8f37ed1de8962 100644 (file)
@@ -11,6 +11,7 @@
             uuid="THE_PROJECT_1"
             uuid_path="NOT_USED"
             root_uuid="THE_PROJECT_1"
+            project_uuid="THE_PROJECT_1"
             module_uuid="[null]"
             module_uuid_path="."
             path="[null]"
@@ -23,6 +24,7 @@
             uuid="THE_FILE_1"
             uuid_path="NOT_USED"
             root_uuid="THE_PROJECT_1"
+            project_uuid="THE_PROJECT_1"
             module_uuid="THE_PROJECT_1"
             module_uuid_path=".THE_PROJECT_1."
             path="src/main/java/TheFile.java"
@@ -94,6 +96,7 @@
             uuid="THE_PROJECT_2"
             uuid_path="NOT_USED"
             root_uuid="THE_PROJECT_2"
+            project_uuid="THE_PROJECT_2"
             module_uuid="[null]"
             module_uuid_path="."
             path="[null]"
             uuid="THE_FILE_2"
             uuid_path="NOT_USED"
             root_uuid="THE_PROJECT_2"
+            project_uuid="THE_PROJECT_2"
             module_uuid="THE_PROJECT_2"
             module_uuid_path=".THE_PROJECT_2."
             path="src/main/java/TheFile.java"
index 76fe1f7c612d4aaa91b2bd80629fba093f20e1d2..00b894b8f6dd05205ff8c7ce5998df8f3c5aca07 100644 (file)
@@ -10,6 +10,7 @@
             uuid="PROJECT1"
             uuid_path="NOT_USED"
             root_uuid="PROJECT1"
+            project_uuid="PROJECT1"
             path="[null]"
             module_uuid_path=".PROJECT1."
             id="10"
@@ -21,6 +22,7 @@
             uuid="MODULE1"
             uuid_path="NOT_USED"
             root_uuid="PROJECT1"
+            project_uuid="PROJECT1"
             path="[null]"
             module_uuid_path=".PROJECT1.MODULE1."
             id="50"
@@ -32,6 +34,7 @@
             uuid="DIR1"
             uuid_path="NOT_USED"
             root_uuid="MODULE1"
+            project_uuid="MODULE1"
             path="src/main/java"
             module_uuid_path=".PROJECT1.MODULE1."
             id="70"
@@ -43,6 +46,7 @@
             uuid="FILE1"
             uuid_path="NOT_USED"
             root_uuid="MODULE1"
+            project_uuid="MODULE1"
             path="src/main/java/Action.java"
             module_uuid_path=".PROJECT1."
             id="100"
index 173a7baf3c6415fb35af0b6d5b70d9d293e83417..1bc5d17855f09f656ca20602a66dd490dc090ce2 100644 (file)
@@ -10,6 +10,7 @@
             uuid="PROJECT1"
             uuid_path="NOT_USED"
             root_uuid="PROJECT1"
+            project_uuid="PROJECT1"
             path="[null]"
             module_uuid_path=".PROJECT1."
             id="10"
@@ -21,6 +22,7 @@
             uuid="MODULE1"
             uuid_path="NOT_USED"
             root_uuid="PROJECT1"
+            project_uuid="PROJECT1"
             path="[null]"
             module_uuid_path=".PROJECT1.MODULE1."
             id="50"
@@ -32,6 +34,7 @@
             uuid="DIR1"
             uuid_path="NOT_USED"
             root_uuid="MODULE1"
+            project_uuid="MODULE1"
             path="src/main/java"
             module_uuid_path=".PROJECT1.MODULE1."
             id="70"
@@ -43,6 +46,7 @@
             uuid="FILE1"
             uuid_path="NOT_USED"
             root_uuid="MODULE1"
+            project_uuid="MODULE1"
             path="src/main/java/Action.java"
             module_uuid_path=".PROJECT1."
             id="100"