3 * Copyright (C) 2009-2018 SonarSource SA
4 * mailto:info AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package org.sonar.server.platform.db.migration.version.v75;
22 import java.sql.SQLException;
23 import java.util.concurrent.atomic.AtomicReference;
24 import org.sonar.api.utils.System2;
25 import org.sonar.db.Database;
26 import org.sonar.server.platform.db.migration.SupportsBlueGreen;
27 import org.sonar.server.platform.db.migration.step.DataChange;
28 import org.sonar.server.platform.db.migration.step.MassUpdate;
29 import org.sonar.server.platform.db.migration.step.Upsert;
32 public class MigrateModuleProperties extends DataChange {
34 private static final String NEW_PROPERTY_NAME = "sonar.subprojects.settings.removed";
36 private final System2 system2;
38 public MigrateModuleProperties(Database db, System2 system2) {
40 this.system2 = system2;
44 protected void execute(Context context) throws SQLException {
45 long now = system2.now();
46 moveModulePropertiesToProjectLevel(context, now);
47 removeModuleProperties(context);
50 private static void moveModulePropertiesToProjectLevel(Context context, long time) throws SQLException {
51 StringBuilder builder = new StringBuilder();
52 AtomicReference<Integer> currentProjectId = new AtomicReference<>();
53 AtomicReference<String> currentModuleUuid = new AtomicReference<>();
55 context.prepareSelect("select prop.prop_key, prop.text_value, prop.clob_value, mod.name, mod.uuid, root.id as project_id, root.name as project_name " +
56 "from properties prop " +
57 "left join projects mod on mod.id = prop.resource_id " +
58 "left join projects root on root.uuid = mod.project_uuid " +
59 "where mod.qualifier = 'BRC'" +
60 "order by root.uuid, mod.uuid, prop.prop_key")
62 String propertyKey = row.getString(1);
63 String propertyTextValue = row.getString(2);
64 String propertyClobValue = row.getString(3);
65 String moduleName = row.getString(4);
66 String moduleUuid = row.getString(5);
67 Integer projectId = row.getInt(6);
68 String projectName = row.getString(7);
70 if (!projectId.equals(currentProjectId.get())) {
71 if (currentProjectId.get() != null) {
72 insertProjectProperties(context, currentProjectId.get(), builder.toString(), time);
76 currentProjectId.set(projectId);
79 if (!moduleUuid.equals(currentModuleUuid.get())) {
80 if (currentModuleUuid.get() != null && builder.length() != 0) {
83 builder.append("# previous settings for sub-project ").append(projectName).append("::").append(moduleName).append("\n");
84 currentModuleUuid.set(moduleUuid);
87 String propertyValue = propertyTextValue == null ? propertyClobValue : propertyTextValue;
88 builder.append(propertyKey).append("=").append(propertyValue).append("\n");
91 if (builder.length() > 0) {
92 insertProjectProperties(context, currentProjectId.get(), builder.toString(), time);
96 private static void insertProjectProperties(Context context, int projectId, String content, long time) throws SQLException {
97 Upsert upsert = context.prepareUpsert("insert into properties (prop_key, resource_id, is_empty, clob_value, created_at) values (?, ?, ?, ?, ?)");
98 upsert.setString(1, NEW_PROPERTY_NAME)
100 .setBoolean(3, false)
101 .setString(4, content)
107 private static void removeModuleProperties(Context context) throws SQLException {
108 MassUpdate massUpdate = context.prepareMassUpdate().rowPluralName("remove module properties");
109 massUpdate.select("select prop.id as property_id " +
110 "from properties prop " +
111 "left join projects mod on mod.id = prop.resource_id " +
112 "where mod.qualifier = 'BRC'");
113 massUpdate.update("delete from properties where id=?");
114 massUpdate.execute((row, update) -> {
115 update.setInt(1, row.getInt(1));