aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-db-migration
diff options
context:
space:
mode:
authorEric Hartmann <hartmann.eric@gmail.com>2017-12-07 11:07:49 +0100
committerJulien Lancelot <julien.lancelot@sonarsource.com>2017-12-14 17:03:35 +0100
commit783c9a6466b8ccc26176cb206cb45bcfcd16eb50 (patch)
tree695b0de979a85ef641c2cb67fc4d33a283ae92b2 /server/sonar-db-migration
parente2d2765f41bfa4bea1d0f19e754acd0c70cf2d36 (diff)
downloadsonarqube-783c9a6466b8ccc26176cb206cb45bcfcd16eb50.tar.gz
sonarqube-783c9a6466b8ccc26176cb206cb45bcfcd16eb50.zip
SONAR-10145 Set built-in QG as default on existing organizations
Diffstat (limited to 'server/sonar-db-migration')
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/AssociateQualityGatesToDefaultOrganization.java61
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/CreateBuiltInQualityGate.java62
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/DbVersion70.java4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/PopulateDefaultQualityGate.java63
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/PopulateOrgQualityGates.java71
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/AssociateQualityGatesToDefaultOrganizationTest.java152
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/CreateBuiltInQualityGateTest.java86
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/DbVersion70Test.java2
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/PopulateDefaultQualityGateTest.java146
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/PopulateOrgQualityGatesTest.java145
-rw-r--r--server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/AssociateQualityGatesToDefaultOrganizationTest/org_quality_gates.sql46
-rw-r--r--server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/CreateBuiltInQualityGateTest/quality_gates.sql9
-rw-r--r--server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/PopulateDefaultQualityGateTest/organizations.sql29
-rw-r--r--server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/PopulateOrgQualityGates/org_quality_gates.sql37
14 files changed, 912 insertions, 1 deletions
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
index 00000000000..fea4be8ad4a
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/AssociateQualityGatesToDefaultOrganization.java
@@ -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
index 00000000000..d7e80c97de0
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/CreateBuiltInQualityGate.java
@@ -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();
+ }
+ }
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/DbVersion70.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/DbVersion70.java
index 2b86136c4cf..1f5217b79d6 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/DbVersion70.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/DbVersion70.java
@@ -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
index 00000000000..2bd54e9ed63
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/PopulateDefaultQualityGate.java
@@ -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
index 00000000000..7050bdc9ccf
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v70/PopulateOrgQualityGates.java
@@ -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
index 00000000000..087e45c451b
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/AssociateQualityGatesToDefaultOrganizationTest.java
@@ -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
index 00000000000..8c7c13ab751
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/CreateBuiltInQualityGateTest.java
@@ -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));
+ }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/DbVersion70Test.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/DbVersion70Test.java
index ef2fe5a9b1b..36bc0171a7f 100644
--- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/DbVersion70Test.java
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/DbVersion70Test.java
@@ -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
index 00000000000..f1a600e978a
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/PopulateDefaultQualityGateTest.java
@@ -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
index 00000000000..459c73e6dd1
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v70/PopulateOrgQualityGatesTest.java
@@ -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
index 00000000000..27a328ebe7d
--- /dev/null
+++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/AssociateQualityGatesToDefaultOrganizationTest/org_quality_gates.sql
@@ -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
index 00000000000..b90299a13c5
--- /dev/null
+++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/CreateBuiltInQualityGateTest/quality_gates.sql
@@ -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
index 00000000000..1adb6bbc747
--- /dev/null
+++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/PopulateDefaultQualityGateTest/organizations.sql
@@ -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
index 00000000000..2f6043beca0
--- /dev/null
+++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v70/PopulateOrgQualityGates/org_quality_gates.sql
@@ -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");