]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10145 Set built-in QG as default on existing organizations
authorEric Hartmann <hartmann.eric@gmail.com>
Thu, 7 Dec 2017 10:07:49 +0000 (11:07 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 14 Dec 2017 16:03:35 +0000 (17:03 +0100)
17 files changed:
server/sonar-db-core/src/main/resources/org/sonar/db/version/rows-h2.sql
server/sonar-db-dao/src/test/java/org/sonar/db/organization/OrganizationDaoTest.java
server/sonar-db-dao/src/test/java/org/sonar/db/qualitygate/QualityGateDbTester.java
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/AssociateQualityGatesToDefaultOrganization.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/CreateBuiltInQualityGate.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/DbVersion70.java
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/PopulateDefaultQualityGate.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/PopulateOrgQualityGates.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/AssociateQualityGatesToDefaultOrganizationTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/CreateBuiltInQualityGateTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/DbVersion70Test.java
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/PopulateDefaultQualityGateTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/PopulateOrgQualityGatesTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/AssociateQualityGatesToDefaultOrganizationTest/org_quality_gates.sql [new file with mode: 0644]
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/CreateBuiltInQualityGateTest/quality_gates.sql [new file with mode: 0644]
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/PopulateDefaultQualityGateTest/organizations.sql [new file with mode: 0644]
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/PopulateOrgQualityGates/org_quality_gates.sql [new file with mode: 0644]

index 4daf0dff72c5846ecbb5c2ec3a3f7232779be76a..46bf46c7fc1beb197a9114334febe96630e6f2d7 100644 (file)
@@ -5,9 +5,11 @@ INSERT INTO GROUPS(ID, ORGANIZATION_UUID, NAME, DESCRIPTION, CREATED_AT, UPDATED
 INSERT INTO GROUPS(ID, ORGANIZATION_UUID, NAME, DESCRIPTION, CREATED_AT, UPDATED_AT) VALUES (2, 'AVdqnciQUUs7Zd3KPvFD', 'sonar-users', 'Any new users created will automatically join this group', '2011-09-26 22:27:51.0', '2011-09-26 22:27:51.0');
 ALTER TABLE GROUPS ALTER COLUMN ID RESTART WITH 3;
 
-INSERT INTO QUALITY_GATES(ID, UUID, NAME, IS_BUILT_IN, CREATED_AT, UPDATED_AT) VALUES (1, 'AWASGWAKYOI_InFKS3UF', 'Sonar Way', true, '2011-09-26 22:27:51.0', '2011-09-26 22:27:51.0');
+INSERT INTO QUALITY_GATES(ID, UUID, NAME, IS_BUILT_IN, CREATED_AT, UPDATED_AT) VALUES (1, 'AWASGWAKYOI_InFKS3UF', 'Sonar way', true, '2011-09-26 22:27:51.0', '2011-09-26 22:27:51.0');
+
+INSERT INTO ORGANIZATIONS (UUID, KEE, NAME, GUARDED, NEW_PROJECT_PRIVATE, DEFAULT_GROUP_ID, DEFAULT_QUALITY_GATE_UUID, CREATED_AT, UPDATED_AT) VALUES ('AVdqnciQUUs7Zd3KPvFD', 'default-organization', 'Default Organization', true, false, 2, 'AWASGWAKYOI_InFKS3UF', '1474962596482', '1474962596482');
+INSERT INTO ORG_QUALITY_GATES (UUID, ORGANIZATION_UUID, QUALITY_GATE_UUID) VALUES ('AWAwlGzz-5zzlJtFU9G5', 'AVdqnciQUUs7Zd3KPvFD', 'AWASGWAKYOI_InFKS3UF');
 
-INSERT INTO ORGANIZATIONS (UUID, KEE, NAME, GUARDED, NEW_PROJECT_PRIVATE, DEFAULT_GROUP_ID, DEFAULT_QUALITY_GATE_UUID, CREATED_AT, UPDATED_AT) VALUES ('AVdqnciQUUs7Zd3KPvFD', 'default-organization', 'Default Organization', true, false, 2, 1, '1474962596482', '1474962596482');
 INSERT INTO INTERNAL_PROPERTIES (KEE, IS_EMPTY, TEXT_VALUE, CREATED_AT) VALUES ('organization.default', false, 'AVdqnciQUUs7Zd3KPvFD', '1474962596482');
 
 INSERT INTO GROUP_ROLES(ID, ORGANIZATION_UUID, GROUP_ID, RESOURCE_ID, ROLE) VALUES (1, 'AVdqnciQUUs7Zd3KPvFD', 1, null, 'admin');
index fc65f74dc38d8aec2a60f3939b84d2acbdff8951..e57971cf294b2d4cb5c7b9134448e22a9b6f9992 100644 (file)
@@ -1020,7 +1020,7 @@ public class OrganizationDaoTest {
       .setName(organizationDto.getName())
       .setDescription(organizationDto.getDescription())
       .setUrl(organizationDto.getUrl())
-      // TODO : .setDefaultQualityGateUuid(dbClient.qualityGateDao().selectBuiltIn(dbSession).getId().toString())
+      .setDefaultQualityGateUuid(organizationDto.getDefaultQualityGateUuid())
       .setAvatarUrl(organizationDto.getAvatarUrl());
   }
 
index 32cedd3599d1340f4409e07848ad4ce38a5ab6ec..77bc2d194629d60d8b87d0d8ea8d58c54d9e8d26 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.db.qualitygate;
 
 import java.util.Arrays;
+import java.util.Date;
 import java.util.function.Consumer;
 import org.sonar.core.util.Uuids;
 import org.sonar.db.DbClient;
@@ -49,6 +50,16 @@ public class QualityGateDbTester {
     return insertQualityGate(qualityGate -> qualityGate.setName(name));
   }
 
+  public QualityGateDto insertBuiltInQualityGate() {
+    QualityGateDto builtin = dbClient.qualityGateDao().insert(dbSession, new QualityGateDto()
+      .setName("Sonar way")
+      .setUuid(Uuids.createFast())
+      .setBuiltIn(true)
+      .setCreatedAt(new Date()));
+    dbSession.commit();
+    return builtin;
+  }
+
   @SafeVarargs
   public final QualityGateDto insertQualityGate(Consumer<QualityGateDto>... dtoPopulators) {
     return insertQualityGate(db.getDefaultOrganization(), dtoPopulators);
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/AssociateQualityGatesToDefaultOrganization.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/AssociateQualityGatesToDefaultOrganization.java
new file mode 100644 (file)
index 0000000..fea4be8
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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.v70;
+
+import java.sql.SQLException;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DataChange;
+import org.sonar.server.platform.db.migration.step.MassUpdate;
+
+import static com.google.common.base.Preconditions.checkState;
+
+public class AssociateQualityGatesToDefaultOrganization extends DataChange {
+
+  private final UuidFactory uuidFactory;
+
+  public AssociateQualityGatesToDefaultOrganization(Database db, UuidFactory uuidFactory) {
+    super(db);
+    this.uuidFactory = uuidFactory;
+  }
+
+  @Override
+  protected void execute(Context context) throws SQLException {
+    String defaultOrgUuid = context.prepareSelect("select text_value from internal_properties where kee = 'organization.default'")
+      .get(row -> row.getString(1));
+
+    checkState(defaultOrgUuid != null, "Default organization uuid is missing");
+
+    MassUpdate massUpdate = context.prepareMassUpdate();
+    massUpdate.select("SELECT qg.uuid from quality_gates qg " +
+      " WHERE qg.is_built_in = ? " +
+      " AND NOT EXISTS (SELECT 1 FROM org_quality_gates oqg WHERE oqg.quality_gate_uuid = qg.uuid AND oqg.organization_uuid = ?)")
+      .setBoolean(1, false)
+      .setString(2, defaultOrgUuid);
+    massUpdate.rowPluralName("quality gates");
+    massUpdate.update("insert into org_quality_gates (uuid, quality_gate_uuid, organization_uuid) values(?, ?, ?)");
+    massUpdate.execute((row, update) -> {
+      update.setString(1, uuidFactory.create());
+      update.setString(2, row.getString(1));
+      update.setString(3, defaultOrgUuid);
+      return true;
+    });
+  }
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/CreateBuiltInQualityGate.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/CreateBuiltInQualityGate.java
new file mode 100644 (file)
index 0000000..d7e80c9
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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.v70;
+
+import java.sql.SQLException;
+import java.util.Date;
+import org.sonar.api.utils.System2;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DataChange;
+
+public class CreateBuiltInQualityGate extends DataChange {
+
+  private static final String SONAR_WAY_QUALITY_GATE = "Sonar way";
+
+  private final System2 system2;
+  private final UuidFactory uuidFactory;
+
+  public CreateBuiltInQualityGate(Database db, System2 system2, UuidFactory uuidFactory) {
+    super(db);
+    this.system2 = system2;
+    this.uuidFactory = uuidFactory;
+  }
+
+
+  @Override
+  protected void execute(Context context) throws SQLException {
+    Long nbOfBuiltInQualityGates = context.prepareSelect("select count(uuid) from quality_gates where is_built_in = ?")
+      .setBoolean(1, true)
+      .get(row -> row.getLong(1));
+
+
+    if (nbOfBuiltInQualityGates == 0) {
+      final Date now = new Date(system2.now());
+
+      context.prepareUpsert("insert into quality_gates (uuid, name, is_built_in, created_at) values (?,?,?,?)")
+        .setString(1, uuidFactory.create())
+        .setString(2, SONAR_WAY_QUALITY_GATE)
+        .setBoolean(3, true)
+        .setDate(4, now)
+        .execute()
+        .commit();
+    }
+  }
+}
index 2b86136c4cf50f3c5ab3cd4e9f4f10e83223869b..1f5217b79d6d380a901d0188929924ad5fc779d3 100644 (file)
@@ -43,6 +43,10 @@ public class DbVersion70 implements DbVersion {
       .add(1913, "Populate QUALITY_GATES.UUID", PopulateUuidOnQualityGates.class)
       .add(1914, "Make QUALITY_GATES.UUID not nullable", MakeUuidNotNullableOnQualityGates.class)
       .add(1915, "Drop unique index on QUALITY_GATES.NAME", DropUniqueIndexOnQualityGatesName.class)
+      .add(1916, "Create builtin quality gate if required", CreateBuiltInQualityGate.class)
+      .add(1917, "Populate ORG_QUALITY_GATES table", PopulateOrgQualityGates.class)
+      .add(1918, "Populate default quality gate on organization", PopulateDefaultQualityGate.class)
+      .add(1919, "Associate existing quality gates to default organization", AssociateQualityGatesToDefaultOrganization.class)
     ;
   }
 }
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/PopulateDefaultQualityGate.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/PopulateDefaultQualityGate.java
new file mode 100644 (file)
index 0000000..2bd54e9
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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.v70;
+
+import java.sql.SQLException;
+import java.util.List;
+import org.sonar.api.utils.System2;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DataChange;
+import org.sonar.server.platform.db.migration.step.MassUpdate;
+
+import static com.google.common.base.Preconditions.checkState;
+
+public class PopulateDefaultQualityGate extends DataChange {
+
+  private final System2 system2;
+
+  public PopulateDefaultQualityGate(Database db, System2 system2) {
+    super(db);
+    this.system2 = system2;
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    List<String> builtInQGUuids = context.prepareSelect("select uuid from quality_gates where is_built_in = ?")
+      .setBoolean(1, true)
+      .list(row -> row.getString(1));
+
+    checkState(!builtInQGUuids.isEmpty(), "Unable to find the builtin quality gate");
+    checkState(builtInQGUuids.size() == 1, "There are too many built in quality gates, one and only one is expected");
+
+    final long now = system2.now();
+    MassUpdate massUpdate = context.prepareMassUpdate();
+    massUpdate.select("select uuid from organizations " +
+      " where default_quality_gate_uuid is null");
+    massUpdate.rowPluralName("organizations");
+    massUpdate.update("update organizations set default_quality_gate_uuid = ?, updated_at=? where uuid = ?");
+    massUpdate.execute((row, update) -> {
+      update.setString(1, builtInQGUuids.get(0));
+      update.setLong(2, now);
+      update.setString(3, row.getString(1));
+      return true;
+    });
+
+  }
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/PopulateOrgQualityGates.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/PopulateOrgQualityGates.java
new file mode 100644 (file)
index 0000000..7050bdc
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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.v70;
+
+import java.sql.SQLException;
+import java.util.List;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DataChange;
+import org.sonar.server.platform.db.migration.step.MassUpdate;
+
+import static com.google.common.base.Preconditions.checkState;
+
+public class PopulateOrgQualityGates extends DataChange {
+
+  private final UuidFactory uuidFactory;
+
+  public PopulateOrgQualityGates(Database db, UuidFactory uuidFactory) {
+    super(db);
+    this.uuidFactory = uuidFactory;
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    Long nbOfOrganizations = context.prepareSelect("select count(uuid) from organizations")
+      .get(row -> row.getLong(1));
+    if (nbOfOrganizations == 0) {
+      // No need for a migration
+      return;
+    }
+
+    List<String> builtInQGUuids = context.prepareSelect("select uuid from quality_gates where is_built_in = ?")
+      .setBoolean(1, true)
+      .list(row -> row.getString(1));
+
+    checkState(!builtInQGUuids.isEmpty(), "Unable to find the builtin quality gate");
+    checkState(builtInQGUuids.size() == 1, "There are too many built in quality gates, one and only one is expected");
+
+    MassUpdate massUpdate = context.prepareMassUpdate();
+    massUpdate.select("select uuid from organizations o " +
+      " where " +
+      "  not exists (select 1 from org_quality_gates oqg where oqg.quality_gate_uuid = ? and oqg.organization_uuid = o.uuid)")
+      .setString(1, builtInQGUuids.get(0));
+
+    massUpdate.rowPluralName("organizations");
+    massUpdate.update("insert into org_quality_gates (uuid, quality_gate_uuid, organization_uuid) values(?, ?, ?)");
+    massUpdate.execute((row, update) -> {
+      update.setString(1, uuidFactory.create());
+      update.setString(2, builtInQGUuids.get(0));
+      update.setString(3, row.getString(1));
+      return true;
+    });
+  }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/AssociateQualityGatesToDefaultOrganizationTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/AssociateQualityGatesToDefaultOrganizationTest.java
new file mode 100644 (file)
index 0000000..087e45c
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * 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.v70;
+
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.core.util.UuidFactoryFast;
+import org.sonar.db.CoreDbTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+
+public class AssociateQualityGatesToDefaultOrganizationTest {
+  private static final long PAST = 10_000_000_000L;
+  private static final String TABLE_ORGANIZATIONS = "organizations";
+  private static final String TABLE_QUALITY_GATES = "quality_gates";
+  private static final String TABLE_INTERNAL_PROPERTIES = "internal_properties";
+  private static final String DEFAULT_ORGANIZATION_KEE = "organization.default";
+
+  @Rule
+  public CoreDbTester db = CoreDbTester.createForSchema(AssociateQualityGatesToDefaultOrganizationTest.class, "org_quality_gates.sql");
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private final UuidFactory uuidFactory = UuidFactoryFast.getInstance();
+
+  private AssociateQualityGatesToDefaultOrganization underTest = new AssociateQualityGatesToDefaultOrganization(db.database(), uuidFactory);
+
+  @Test
+  public void should_throw_ISE_if_no_default_organization() throws SQLException {
+    insertOrganization(uuidFactory.create());
+    insertOrganization(uuidFactory.create());
+    insertQualityGate(uuidFactory.create(), "QualityGate1", false);
+    insertQualityGate(uuidFactory.create(), "QualityGate2", true);
+
+    expectedException.expect(IllegalStateException.class);
+    expectedException.expectMessage("Default organization uuid is missing");
+
+    underTest.execute();
+  }
+
+  @Test
+  public void should_associate_all_quality_gates_to_default_organization() throws SQLException {
+    String defaultOrgUuid = uuidFactory.create();
+    String anotherOrgUuid = uuidFactory.create();
+    insertOrganization(defaultOrgUuid);
+    insertOrganization(anotherOrgUuid);
+
+    String qgUuid1 = uuidFactory.create();
+    String qgUuid2 = uuidFactory.create();
+    String qgUuid3 = uuidFactory.create();
+    insertQualityGate(qgUuid1, "QualityGate1", false);
+    insertQualityGate(qgUuid2, "QualityGate2", false);
+    insertQualityGate(qgUuid3, "QualityGate3", true);
+
+    insertDefaultOrgProperty(defaultOrgUuid);
+
+    underTest.execute();
+
+    assertThat(selectAllOrgQualityGates())
+      .extracting(map -> map.get("ORGANIZATION_UUID"), map -> map.get("QUALITY_GATE_UUID"))
+      .containsExactlyInAnyOrder(
+        tuple(defaultOrgUuid, qgUuid1),
+        tuple(defaultOrgUuid, qgUuid2)
+      );
+  }
+
+  @Test
+  public void is_reentrant() throws SQLException {
+    String orgUuid1 = uuidFactory.create();
+    String orgUuid2 = uuidFactory.create();
+    insertOrganization(orgUuid1);
+    insertOrganization(orgUuid2);
+
+    String qgUuid1 = uuidFactory.create();
+    String qgUuid2 = uuidFactory.create();
+    String qgUuid3 = uuidFactory.create();
+    insertQualityGate(qgUuid1, "QualityGate1", false);
+    insertQualityGate(qgUuid2, "QualityGate2", false);
+    insertQualityGate(qgUuid3, "QualityGate3", true);
+
+    insertDefaultOrgProperty(orgUuid1);
+
+    underTest.execute();
+    underTest.execute();
+
+    assertThat(selectAllOrgQualityGates())
+      .extracting(map -> map.get("ORGANIZATION_UUID"), map -> map.get("QUALITY_GATE_UUID"))
+      .containsExactlyInAnyOrder(
+        tuple(orgUuid1, qgUuid1),
+        tuple(orgUuid1, qgUuid2)
+      );
+  }
+
+  private List<Map<String, Object>> selectAllOrgQualityGates() {
+    return db.select("select organization_uuid, quality_gate_uuid from org_quality_gates");
+  }
+
+  private void insertDefaultOrgProperty(String uuid) {
+    db.executeInsert(
+      TABLE_INTERNAL_PROPERTIES,
+      "KEE", DEFAULT_ORGANIZATION_KEE,
+      "IS_EMPTY", String.valueOf(false),
+      "TEXT_VALUE", uuid,
+      "CREATED_AT", PAST);
+  }
+
+  private void insertOrganization(String uuid) {
+    db.executeInsert(
+      TABLE_ORGANIZATIONS,
+      "UUID", uuid,
+      "KEE", uuid,
+      "NAME", uuid,
+      "GUARDED", String.valueOf(false),
+      "NEW_PROJECT_PRIVATE", String.valueOf(true),
+      "CREATED_AT", PAST,
+      "UPDATED_AT", PAST);
+  }
+
+  private void insertQualityGate(String uuid, String name, Boolean builtIn) {
+    db.executeInsert(
+      TABLE_QUALITY_GATES,
+      "UUID", uuid,
+      "NAME", name,
+      "IS_BUILT_IN", builtIn.toString(),
+      "CREATED_AT", new Date(PAST),
+      "UPDATED_AT", new Date(PAST));
+  }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/CreateBuiltInQualityGateTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/CreateBuiltInQualityGateTest.java
new file mode 100644 (file)
index 0000000..8c7c13a
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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.v70;
+
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.api.utils.internal.TestSystem2;
+import org.sonar.core.util.UuidFactoryFast;
+import org.sonar.core.util.Uuids;
+import org.sonar.db.CoreDbTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.groups.Tuple.tuple;
+
+public class CreateBuiltInQualityGateTest {
+  private final static long PAST = 10_000_000_000L;
+  private final static long NOW = 50_000_000_000L;
+
+  private System2 system2 = new TestSystem2().setNow(NOW);
+
+  @Rule
+  public CoreDbTester db = CoreDbTester.createForSchema(CreateBuiltInQualityGateTest.class, "quality_gates.sql");
+
+  private CreateBuiltInQualityGate underTest = new CreateBuiltInQualityGate(db.database(), system2, UuidFactoryFast.getInstance());
+
+  @Test
+  public void should_create_builtin_quality_gate() throws SQLException {
+    underTest.execute();
+
+    assertThat(selectAllQualityGates())
+      .extracting(map -> map.get("NAME"), map -> map.get("IS_BUILT_IN"), map -> map.get("CREATED_AT"))
+      .containsExactlyInAnyOrder(
+        tuple("Sonar way", true, new Date(NOW))
+      );
+  }
+
+  @Test
+  public void should_not_create_builtin_quality_gate_if_existing() throws SQLException {
+    insertQualityGate("Whatever", true);
+
+    underTest.execute();
+
+    assertThat(selectAllQualityGates())
+      .extracting(map -> map.get("NAME"), map -> map.get("IS_BUILT_IN"), map -> map.get("CREATED_AT"))
+      .containsExactlyInAnyOrder(
+        tuple("Whatever", true, new Date(PAST))
+      );
+  }
+
+
+  private List<Map<String, Object>> selectAllQualityGates() {
+    return db.select("select id, uuid, name, is_built_in, created_at, updated_at from quality_gates");
+  }
+
+  private void insertQualityGate(String name, boolean builtIn) {
+    db.executeInsert(
+      "QUALITY_GATES",
+      "UUID", Uuids.createFast(),
+      "NAME", name,
+      "IS_BUILT_IN", String.valueOf(builtIn),
+      "CREATED_AT", new Date(PAST),
+      "UPDATED_AT", new Date(PAST));
+  }
+}
index ef2fe5a9b1b5ecbe2f27c974742f9bd56422fe16..36bc0171a7f782b0e759ea94e69d2aa54e679d70 100644 (file)
@@ -35,7 +35,7 @@ public class DbVersion70Test {
 
   @Test
   public void verify_migration_count() {
-    verifyMigrationCount(underTest, 16);
+    verifyMigrationCount(underTest, 20);
   }
 
 }
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/PopulateDefaultQualityGateTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/PopulateDefaultQualityGateTest.java
new file mode 100644 (file)
index 0000000..f1a600e
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * 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.v70;
+
+import java.sql.SQLException;
+import java.util.Date;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.System2;
+import org.sonar.api.utils.internal.TestSystem2;
+import org.sonar.core.util.Uuids;
+import org.sonar.db.CoreDbTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class PopulateDefaultQualityGateTest {
+  private final static long PAST = 10_000_000_000L;
+  private static final long NOW = 50_000_000_000L;
+  private static final String TABLE_ORGANIZATIONS = "organizations";
+  private static final String TABLE_QUALITY_GATES = "quality_gates";
+
+  private System2 system2 = new TestSystem2().setNow(NOW);
+
+  @Rule
+  public CoreDbTester db = CoreDbTester.createForSchema(PopulateDefaultQualityGateTest.class, "organizations.sql");
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private PopulateDefaultQualityGate underTest = new PopulateDefaultQualityGate(db.database(), system2);
+
+
+  @Test
+  public void has_no_effect_if_table_is_empty() throws SQLException {
+    insertQualityGate(Uuids.createFast(), "Sonar way", true);
+
+    underTest.execute();
+
+    assertThat(db.countRowsOfTable("organizations")).isEqualTo(0);
+  }
+
+  @Test
+  public void should_populate_defaultQualityGate_column() throws SQLException {
+    String builtInQGUuid = Uuids.createFast();
+    insertQualityGate(builtInQGUuid, "Sonar way", true);
+    String orgUuid1 = Uuids.createFast();
+    String orgUuid2 = Uuids.createFast();
+    insertOrganization(orgUuid1);
+    insertOrganization(orgUuid2);
+
+    underTest.execute();
+
+    // all organizations have the builtIn quality gate
+    assertThat(
+      db.countSql("select count(uuid) from organizations where default_quality_gate_uuid != '" + builtInQGUuid + "'")
+    ).isEqualTo(0);
+    assertThat(
+      db.countSql("select count(uuid) from organizations where default_quality_gate_uuid = '" + builtInQGUuid + "'")
+    ).isEqualTo(2);
+
+    // updated_at must have been updated
+    assertThat(
+      db.countSql("select count(uuid) from organizations where updated_at = " + NOW )
+    ).isEqualTo(2);
+  }
+
+  @Test
+  public void is_reentrant() throws SQLException {
+    String builtInQGUuid = Uuids.createFast();
+    insertQualityGate(builtInQGUuid, "Sonar way", true);
+    insertOrganization(Uuids.createFast());
+    insertOrganization(Uuids.createFast());
+
+    underTest.execute();
+    underTest.execute();
+
+    assertThat(
+      db.countSql("select count(uuid) from organizations where default_quality_gate_uuid != '" + builtInQGUuid + "'")
+    ).isEqualTo(0);
+
+    assertThat(
+      db.countSql("select count(uuid) from organizations where default_quality_gate_uuid = '" + builtInQGUuid + "'")
+    ).isEqualTo(2);
+  }
+
+  @Test
+  public void should_fail_with_ISE_when_no_builtIn() throws SQLException {
+    insertOrganization(Uuids.createFast());
+
+    expectedException.expect(IllegalStateException.class);
+    expectedException.expectMessage("Unable to find the builtin quality gate");
+
+    underTest.execute();
+  }
+
+  @Test
+  public void should_fail_if_there_is_multiple_builtin_qualitygates() throws SQLException {
+    insertQualityGate(Uuids.createFast(), "Sonar way", true);
+    insertQualityGate(Uuids.createFast(), "Sonar way2", true);
+    insertOrganization(Uuids.createFast());
+
+    expectedException.expect(IllegalStateException.class);
+    expectedException.expectMessage("There are too many built in quality gates, one and only one is expected");
+
+    underTest.execute();
+  }
+
+  private void insertOrganization(String uuid) {
+    db.executeInsert(
+      TABLE_ORGANIZATIONS,
+      "UUID", uuid,
+      "KEE", uuid,
+      "NAME", uuid,
+      "GUARDED", String.valueOf(false),
+      "NEW_PROJECT_PRIVATE", String.valueOf(true),
+      "CREATED_AT", "1000",
+      "UPDATED_AT", "1000");
+  }
+
+  private void insertQualityGate(String uuid, String name, Boolean builtIn) {
+    db.executeInsert(
+      TABLE_QUALITY_GATES,
+      "UUID", uuid,
+      "NAME", name,
+      "IS_BUILT_IN", builtIn.toString(),
+      "CREATED_AT", new Date(PAST),
+      "UPDATED_AT", new Date(PAST));
+  }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/PopulateOrgQualityGatesTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/PopulateOrgQualityGatesTest.java
new file mode 100644 (file)
index 0000000..459c73e
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * 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.v70;
+
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.core.util.UuidFactoryFast;
+import org.sonar.core.util.Uuids;
+import org.sonar.db.CoreDbTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.groups.Tuple.tuple;
+
+public class PopulateOrgQualityGatesTest {
+
+  private static final long PAST = 10_000_000_000L;
+  private static final String TABLE_ORGANIZATIONS = "organizations";
+  private static final String TABLE_QUALITY_GATES = "quality_gates";
+
+  @Rule
+  public CoreDbTester db = CoreDbTester.createForSchema(PopulateOrgQualityGates.class, "org_quality_gates.sql");
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private PopulateOrgQualityGates underTest = new PopulateOrgQualityGates(db.database(), UuidFactoryFast.getInstance());
+
+  @Test
+  public void has_no_effect_if_table_is_empty() throws SQLException {
+    underTest.execute();
+
+    assertThat(db.countRowsOfTable("org_quality_gates")).isEqualTo(0);
+  }
+
+  @Test
+  public void should_associate_builtin_to_all_organizations() throws SQLException {
+    String orgUuid1 = Uuids.createFast();
+    String orgUuid2 = Uuids.createFast();
+    String qgUuid = Uuids.createFast();
+    insertOrganization(orgUuid1);
+    insertOrganization(orgUuid2);
+    insertQualityGate(qgUuid, "Sonar way", true);
+
+    underTest.execute();
+
+    assertThat(selectAllOrgQualityGates())
+      .extracting(map -> map.get("ORGANIZATION_UUID"), map -> map.get("QUALITY_GATE_UUID"))
+      .containsExactlyInAnyOrder(
+        tuple(orgUuid1, qgUuid),
+        tuple(orgUuid2, qgUuid));
+  }
+
+  @Test
+  public void is_reentrant() throws SQLException {
+    String orgUuid1 = Uuids.createFast();
+    String orgUuid2 = Uuids.createFast();
+    String qgUuid = Uuids.createFast();
+    insertOrganization(orgUuid1);
+    insertOrganization(orgUuid2);
+    insertQualityGate(qgUuid, "Sonar way", true);
+
+    underTest.execute();
+    underTest.execute();
+
+    assertThat(selectAllOrgQualityGates())
+      .extracting(map -> map.get("ORGANIZATION_UUID"), map -> map.get("QUALITY_GATE_UUID"))
+      .containsExactlyInAnyOrder(
+        tuple(orgUuid1, qgUuid),
+        tuple(orgUuid2, qgUuid));
+  }
+
+  @Test
+  public void should_fail_with_ISE_when_no_builtIn() throws SQLException {
+    insertOrganization(Uuids.createFast());
+
+    expectedException.expect(IllegalStateException.class);
+    expectedException.expectMessage("Unable to find the builtin quality gate");
+
+    underTest.execute();
+  }
+
+  @Test
+  public void should_fail_if_there_are_two_builtin_qg() throws SQLException {
+    String orgUuid1 = Uuids.createFast();
+    String orgUuid2 = Uuids.createFast();
+    String qgUuid1 = Uuids.createFast();
+    String qgUuid2 = Uuids.createFast();
+    insertOrganization(orgUuid1);
+    insertOrganization(orgUuid2);
+    insertQualityGate(qgUuid1, "Sonar way", true);
+    insertQualityGate(qgUuid2, "Sonar way 2", true);
+
+    expectedException.expect(IllegalStateException.class);
+    expectedException.expectMessage("There are too many built in quality gates, one and only one is expected");
+
+    underTest.execute();
+  }
+
+  private List<Map<String, Object>> selectAllOrgQualityGates() {
+    return db.select("select organization_uuid, quality_gate_uuid from org_quality_gates");
+  }
+
+  private void insertOrganization(String uuid) {
+    db.executeInsert(
+      TABLE_ORGANIZATIONS,
+      "UUID", uuid,
+      "KEE", uuid,
+      "NAME", uuid,
+      "GUARDED", String.valueOf(false),
+      "NEW_PROJECT_PRIVATE", String.valueOf(true),
+      "CREATED_AT", "1000",
+      "UPDATED_AT", "1000");
+  }
+
+  private void insertQualityGate(String uuid, String name, Boolean builtIn) {
+    db.executeInsert(
+      TABLE_QUALITY_GATES,
+      "UUID", uuid,
+      "NAME", name,
+      "IS_BUILT_IN", builtIn.toString(),
+      "CREATED_AT", new Date(PAST),
+      "UPDATED_AT", new Date(PAST));
+  }
+}
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/AssociateQualityGatesToDefaultOrganizationTest/org_quality_gates.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/AssociateQualityGatesToDefaultOrganizationTest/org_quality_gates.sql
new file mode 100644 (file)
index 0000000..27a328e
--- /dev/null
@@ -0,0 +1,46 @@
+CREATE TABLE "ORGANIZATIONS" (
+  "UUID" VARCHAR(40) NOT NULL PRIMARY KEY,
+  "KEE" VARCHAR(32) NOT NULL,
+  "NAME" VARCHAR(64) NOT NULL,
+  "DESCRIPTION" VARCHAR(256),
+  "URL" VARCHAR(256),
+  "AVATAR_URL" VARCHAR(256),
+  "GUARDED" BOOLEAN NOT NULL,
+  "USER_ID" INTEGER,
+  "DEFAULT_PERM_TEMPLATE_PROJECT" VARCHAR(40),
+  "DEFAULT_PERM_TEMPLATE_VIEW" VARCHAR(40),
+  "DEFAULT_GROUP_ID" INTEGER,
+  "DEFAULT_QUALITY_GATE_UUID" VARCHAR(40),
+  "NEW_PROJECT_PRIVATE" BOOLEAN NOT NULL,
+  "CREATED_AT" BIGINT NOT NULL,
+  "UPDATED_AT" BIGINT NOT NULL
+);
+CREATE UNIQUE INDEX "PK_ORGANIZATIONS" ON "ORGANIZATIONS" ("UUID");
+CREATE UNIQUE INDEX "ORGANIZATION_KEY" ON "ORGANIZATIONS" ("KEE");
+
+CREATE TABLE "ORG_QUALITY_GATES" (
+  "UUID" VARCHAR(40) NOT NULL PRIMARY KEY,
+  "ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
+  "QUALITY_GATE_UUID" VARCHAR(40) NOT NULL
+);
+CREATE UNIQUE INDEX "UNIQ_ORG_QUALITY_GATES" ON "ORG_QUALITY_GATES" ("ORGANIZATION_UUID","QUALITY_GATE_UUID");
+
+
+CREATE TABLE "QUALITY_GATES" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "UUID" VARCHAR(40) NOT NULL,
+  "NAME" VARCHAR(100) NOT NULL,
+  "IS_BUILT_IN" BOOLEAN NOT NULL,
+  "CREATED_AT" TIMESTAMP,
+  "UPDATED_AT" TIMESTAMP,
+);
+CREATE UNIQUE INDEX "UNIQ_QUALITY_GATES_UUID" ON "QUALITY_GATES" ("UUID");
+
+CREATE TABLE "INTERNAL_PROPERTIES" (
+  "KEE" VARCHAR(20) NOT NULL PRIMARY KEY,
+  "IS_EMPTY" BOOLEAN NOT NULL,
+  "TEXT_VALUE" VARCHAR(4000),
+  "CLOB_VALUE" CLOB,
+  "CREATED_AT" BIGINT
+);
+CREATE UNIQUE INDEX "UNIQ_INTERNAL_PROPERTIES" ON "INTERNAL_PROPERTIES" ("KEE");
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/CreateBuiltInQualityGateTest/quality_gates.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/CreateBuiltInQualityGateTest/quality_gates.sql
new file mode 100644 (file)
index 0000000..b90299a
--- /dev/null
@@ -0,0 +1,9 @@
+CREATE TABLE "QUALITY_GATES" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "UUID" VARCHAR(40) NOT NULL,
+  "NAME" VARCHAR(100) NOT NULL,
+  "IS_BUILT_IN" BOOLEAN NOT NULL,
+  "CREATED_AT" TIMESTAMP,
+  "UPDATED_AT" TIMESTAMP,
+);
+CREATE UNIQUE INDEX "UNIQ_QUALITY_GATES_UUID" ON "QUALITY_GATES" ("UUID");
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/PopulateDefaultQualityGateTest/organizations.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/PopulateDefaultQualityGateTest/organizations.sql
new file mode 100644 (file)
index 0000000..1adb6bb
--- /dev/null
@@ -0,0 +1,29 @@
+CREATE TABLE "ORGANIZATIONS" (
+  "UUID" VARCHAR(40) NOT NULL PRIMARY KEY,
+  "KEE" VARCHAR(32) NOT NULL,
+  "NAME" VARCHAR(64) NOT NULL,
+  "DESCRIPTION" VARCHAR(256),
+  "URL" VARCHAR(256),
+  "AVATAR_URL" VARCHAR(256),
+  "GUARDED" BOOLEAN NOT NULL,
+  "USER_ID" INTEGER,
+  "DEFAULT_PERM_TEMPLATE_PROJECT" VARCHAR(40),
+  "DEFAULT_PERM_TEMPLATE_VIEW" VARCHAR(40),
+  "DEFAULT_GROUP_ID" INTEGER,
+  "DEFAULT_QUALITY_GATE_UUID" VARCHAR(40),
+  "NEW_PROJECT_PRIVATE" BOOLEAN NOT NULL,
+  "CREATED_AT" BIGINT NOT NULL,
+  "UPDATED_AT" BIGINT NOT NULL
+);
+CREATE UNIQUE INDEX "PK_ORGANIZATIONS" ON "ORGANIZATIONS" ("UUID");
+CREATE UNIQUE INDEX "ORGANIZATION_KEY" ON "ORGANIZATIONS" ("KEE");
+
+CREATE TABLE "QUALITY_GATES" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "UUID" VARCHAR(40) NOT NULL,
+  "NAME" VARCHAR(100) NOT NULL,
+  "IS_BUILT_IN" BOOLEAN NOT NULL,
+  "CREATED_AT" TIMESTAMP,
+  "UPDATED_AT" TIMESTAMP,
+);
+CREATE UNIQUE INDEX "UNIQ_QUALITY_GATES_UUID" ON "QUALITY_GATES" ("UUID");
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/PopulateOrgQualityGates/org_quality_gates.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/PopulateOrgQualityGates/org_quality_gates.sql
new file mode 100644 (file)
index 0000000..2f6043b
--- /dev/null
@@ -0,0 +1,37 @@
+CREATE TABLE "ORGANIZATIONS" (
+  "UUID" VARCHAR(40) NOT NULL PRIMARY KEY,
+  "KEE" VARCHAR(32) NOT NULL,
+  "NAME" VARCHAR(64) NOT NULL,
+  "DESCRIPTION" VARCHAR(256),
+  "URL" VARCHAR(256),
+  "AVATAR_URL" VARCHAR(256),
+  "GUARDED" BOOLEAN NOT NULL,
+  "USER_ID" INTEGER,
+  "DEFAULT_PERM_TEMPLATE_PROJECT" VARCHAR(40),
+  "DEFAULT_PERM_TEMPLATE_VIEW" VARCHAR(40),
+  "DEFAULT_GROUP_ID" INTEGER,
+  "DEFAULT_QUALITY_GATE_UUID" VARCHAR(40),
+  "NEW_PROJECT_PRIVATE" BOOLEAN NOT NULL,
+  "CREATED_AT" BIGINT NOT NULL,
+  "UPDATED_AT" BIGINT NOT NULL
+);
+CREATE UNIQUE INDEX "PK_ORGANIZATIONS" ON "ORGANIZATIONS" ("UUID");
+CREATE UNIQUE INDEX "ORGANIZATION_KEY" ON "ORGANIZATIONS" ("KEE");
+
+CREATE TABLE "ORG_QUALITY_GATES" (
+  "UUID" VARCHAR(40) NOT NULL PRIMARY KEY,
+  "ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
+  "QUALITY_GATE_UUID" VARCHAR(40) NOT NULL
+);
+CREATE UNIQUE INDEX "UNIQ_ORG_QUALITY_GATES" ON "ORG_QUALITY_GATES" ("ORGANIZATION_UUID","QUALITY_GATE_UUID");
+
+
+CREATE TABLE "QUALITY_GATES" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "UUID" VARCHAR(40) NOT NULL,
+  "NAME" VARCHAR(100) NOT NULL,
+  "IS_BUILT_IN" BOOLEAN NOT NULL,
+  "CREATED_AT" TIMESTAMP,
+  "UPDATED_AT" TIMESTAMP,
+);
+CREATE UNIQUE INDEX "UNIQ_QUALITY_GATES_UUID" ON "QUALITY_GATES" ("UUID");