import java.util.Collection;
import java.util.List;
import javax.annotation.Nullable;
+import org.sonar.core.util.UuidFactory;
import org.sonar.db.Dao;
import org.sonar.db.DbSession;
public class DuplicationDao implements Dao {
+ private final UuidFactory uuidFactory;
+
+ public DuplicationDao(UuidFactory uuidFactory) {
+ this.uuidFactory = uuidFactory;
+ }
+
/**
* @param analysisUuid snapshot id of the project from the previous analysis (islast=true)
*/
* Note that generated ids are not returned.
*/
public void insert(DbSession session, DuplicationUnitDto dto) {
+ dto.setUuid(uuidFactory.create());
session.getMapper(DuplicationMapper.class).batchInsert(dto);
}
-
+
public List<DuplicationUnitDto> selectComponent(DbSession session, String componentUuid, String analysisUuid) {
return session.getMapper(DuplicationMapper.class).selectComponent(componentUuid, analysisUuid);
}
public final class DuplicationUnitDto {
- private long id;
+ private String uuid;
private String analysisUuid;
private String componentUuid;
// Return by join
private String componentKey;
- public long getId() {
- return id;
+ public String getUuid() {
+ return uuid;
}
- public DuplicationUnitDto setId(long id) {
- this.id = id;
+ public DuplicationUnitDto setUuid(String uuid) {
+ this.uuid = uuid;
return this;
}
<select id="selectCandidates" parameterType="map" resultType="DuplicationUnit">
SELECT DISTINCT
- duplication_block.id as id,
+ duplication_block.uuid as uuid,
duplication_block.analysis_uuid as analysisUuid,
duplication_block.component_uuid as componentUuid,
duplication_block.hash as hash,
<select id="selectComponent" parameterType="map" resultType="DuplicationUnit">
SELECT DISTINCT
- dup.id as id,
+ dup.uuid as uuid,
dup.analysis_uuid as analysisUuid,
dup.component_uuid as componentUuid,
dup.hash as hash,
<insert id="batchInsert" parameterType="DuplicationUnit" useGeneratedKeys="false">
INSERT INTO duplications_index (
- analysis_uuid, component_uuid, hash,
+ uuid, analysis_uuid, component_uuid, hash,
index_in_file, start_line, end_line
)
VALUES (
- #{analysisUuid,jdbcType=VARCHAR}, #{componentUuid,jdbcType=VARCHAR}, #{hash,jdbcType=VARCHAR},
+ #{uuid,jdbcType=VARCHAR}, #{analysisUuid,jdbcType=VARCHAR}, #{componentUuid,jdbcType=VARCHAR}, #{hash,jdbcType=VARCHAR},
#{indexInFile,jdbcType=INTEGER}, #{startLine,jdbcType=INTEGER}, #{endLine,jdbcType=INTEGER}
)
</insert>
CREATE INDEX "RULE_ID_DEPRECATED_RULE_KEYS" ON "DEPRECATED_RULE_KEYS"("RULE_ID");
CREATE TABLE "DUPLICATIONS_INDEX"(
- "ID" BIGINT NOT NULL AUTO_INCREMENT (1,1),
"ANALYSIS_UUID" VARCHAR(50) NOT NULL,
"COMPONENT_UUID" VARCHAR(50) NOT NULL,
"HASH" VARCHAR(50) NOT NULL,
"INDEX_IN_FILE" INTEGER NOT NULL,
"START_LINE" INTEGER NOT NULL,
- "END_LINE" INTEGER NOT NULL
+ "END_LINE" INTEGER NOT NULL,
+ "UUID" VARCHAR(40) NOT NULL
);
-ALTER TABLE "DUPLICATIONS_INDEX" ADD CONSTRAINT "PK_DUPLICATIONS_INDEX" PRIMARY KEY("ID");
+ALTER TABLE "DUPLICATIONS_INDEX" ADD CONSTRAINT "PK_DUPLICATIONS_INDEX" PRIMARY KEY("UUID");
CREATE INDEX "DUPLICATIONS_INDEX_HASH" ON "DUPLICATIONS_INDEX"("HASH");
CREATE INDEX "DUPLICATION_ANALYSIS_COMPONENT" ON "DUPLICATIONS_INDEX"("ANALYSIS_UUID", "COMPONENT_UUID");
assertThat(blocks).hasSize(1);
DuplicationUnitDto block = blocks.get(0);
+ Assertions.assertThat(block.getUuid()).isNotNull();
Assertions.assertThat(block.getComponentKey()).isNull();
Assertions.assertThat(block.getComponentUuid()).isEqualTo(project3.uuid());
Assertions.assertThat(block.getHash()).isEqualTo("bb");
insert(project, analysis, "bb", 0, 1, 2);
List<Map<String, Object>> rows = db.select("select " +
- "analysis_uuid as \"ANALYSIS\", component_uuid as \"COMPONENT\", hash as \"HASH\", " +
+ "uuid as \"UUID\", analysis_uuid as \"ANALYSIS\", component_uuid as \"COMPONENT\", hash as \"HASH\", " +
"index_in_file as \"INDEX\", start_line as \"START\", end_line as \"END\"" +
" from duplications_index");
Assertions.assertThat(rows).hasSize(1);
Map<String, Object> row = rows.get(0);
+ Assertions.assertThat(row.get("UUID")).isNotNull();
Assertions.assertThat(row.get("ANALYSIS")).isEqualTo(analysis.getUuid());
Assertions.assertThat(row.get("COMPONENT")).isEqualTo(project.uuid());
Assertions.assertThat(row.get("HASH")).isEqualTo("bb");
import org.sonar.server.platform.db.migration.version.v83.cequeue.DropIdColumnOfCeQueueTable;
import org.sonar.server.platform.db.migration.version.v83.cequeue.DropPrimaryKeyOnIdColumnOfCeQueueTable;
import org.sonar.server.platform.db.migration.version.v83.cequeue.DropUniqueIndexOnUuidColumnOfCeQueueTable;
+import org.sonar.server.platform.db.migration.version.v83.duplicationsindex.AddPrimaryKeyOnUuidColumnOfDuplicationsIndexTable;
+import org.sonar.server.platform.db.migration.version.v83.duplicationsindex.AddUuidToDuplicationsIndexTable;
+import org.sonar.server.platform.db.migration.version.v83.duplicationsindex.DropIdColumnOfDuplicationsIndexTable;
+import org.sonar.server.platform.db.migration.version.v83.duplicationsindex.DropPrimaryKeyOnIdColumnOfDuplicationsIndexTable;
+import org.sonar.server.platform.db.migration.version.v83.duplicationsindex.MakeDuplicationsIndexUuidColumnNotNullable;
+import org.sonar.server.platform.db.migration.version.v83.duplicationsindex.PopulateDuplicationsIndexUuid;
import org.sonar.server.platform.db.migration.version.v83.events.AddPrimaryKeyOnUuidColumnOfEventsTable;
import org.sonar.server.platform.db.migration.version.v83.events.DropIdColumnOfEventsTable;
import org.sonar.server.platform.db.migration.version.v83.events.DropPrimaryKeyOnIdColumnOfEventsTable;
.add(3420, "Add primary key on 'UUID' column of 'CE_ACTIVITY' table", AddPrimaryKeyOnUuidColumnOfCeActivityTable.class)
.add(3421, "Drop column 'ID' of 'CE_ACTIVITY' table", DropIdColumnOfCeActivityTable.class)
+ // Migration of DUPLICATIONS_INDEX table
+ .add(3422, "Add 'uuid' columns for DUPLICATIONS_INDEX", AddUuidToDuplicationsIndexTable.class)
+ .add(3423, "Populate 'uuid' columns for DUPLICATIONS_INDEX", PopulateDuplicationsIndexUuid.class)
+ .add(3424, "Make 'uuid' column not nullable for DUPLICATIONS_INDEX", MakeDuplicationsIndexUuidColumnNotNullable.class)
+ .add(3425, "Drop primary key on 'ID' column of 'DUPLICATIONS_INDEX' table", DropPrimaryKeyOnIdColumnOfDuplicationsIndexTable.class)
+ .add(3426, "Add primary key on 'UUID' column of 'DUPLICATIONS_INDEX' table", AddPrimaryKeyOnUuidColumnOfDuplicationsIndexTable.class)
+ .add(3427, "Drop column 'ID' of 'DUPLICATIONS_INDEX' table", DropIdColumnOfDuplicationsIndexTable.class)
;
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.duplicationsindex;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+import org.sonar.server.platform.db.migration.version.v83.util.AddPrimaryKeyBuilder;
+
+public class AddPrimaryKeyOnUuidColumnOfDuplicationsIndexTable extends DdlChange {
+
+ public AddPrimaryKeyOnUuidColumnOfDuplicationsIndexTable(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(new AddPrimaryKeyBuilder("duplications_index", "uuid").build());
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.duplicationsindex;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public class AddUuidToDuplicationsIndexTable extends DdlChange {
+ private static final String TABLE = "duplications_index";
+
+ private static final VarcharColumnDef uuidColumnDefinition = newVarcharColumnDefBuilder()
+ .setColumnName("uuid")
+ .setIsNullable(true)
+ .setDefaultValue(null)
+ .setLimit(VarcharColumnDef.UUID_SIZE)
+ .build();
+
+ public AddUuidToDuplicationsIndexTable(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(new AddColumnsBuilder(getDialect(), TABLE)
+ .addColumn(uuidColumnDefinition)
+ .build());
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.duplicationsindex;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+public class DropIdColumnOfDuplicationsIndexTable extends DdlChange {
+
+ public DropIdColumnOfDuplicationsIndexTable(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(new DropColumnsBuilder(getDialect(), "duplications_index", "id").build());
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.duplicationsindex;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+import org.sonar.server.platform.db.migration.version.v83.util.DropPrimaryKeySqlGenerator;
+
+public class DropPrimaryKeyOnIdColumnOfDuplicationsIndexTable extends DdlChange {
+
+ private final DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator;
+
+ public DropPrimaryKeyOnIdColumnOfDuplicationsIndexTable(Database db, DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator) {
+ super(db);
+ this.dropPrimaryKeySqlGenerator = dropPrimaryKeySqlGenerator;
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(dropPrimaryKeySqlGenerator.generate("duplications_index", "duplications_index", "id"));
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.duplicationsindex;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public class MakeDuplicationsIndexUuidColumnNotNullable extends DdlChange {
+ private static final String TABLE = "duplications_index";
+
+ private static final VarcharColumnDef uuidColumnDefinition = newVarcharColumnDefBuilder()
+ .setColumnName("uuid")
+ .setIsNullable(false)
+ .setDefaultValue(null)
+ .setLimit(VarcharColumnDef.UUID_SIZE)
+ .build();
+
+ public MakeDuplicationsIndexUuidColumnNotNullable(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(new AlterColumnsBuilder(getDialect(), TABLE)
+ .updateColumn(uuidColumnDefinition)
+ .build());
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.duplicationsindex;
+
+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;
+
+public class PopulateDuplicationsIndexUuid extends DataChange {
+
+ private final UuidFactory uuidFactory;
+
+ public PopulateDuplicationsIndexUuid(Database db, UuidFactory uuidFactory) {
+ super(db);
+ this.uuidFactory = uuidFactory;
+ }
+
+ @Override
+ protected void execute(Context context) throws SQLException {
+ MassUpdate massUpdate = context.prepareMassUpdate();
+
+ massUpdate.select("select id from duplications_index where uuid is null order by id asc");
+ massUpdate.update("update duplications_index set uuid = ? where id = ?");
+
+ massUpdate.execute((row, update) -> {
+ update.setString(1, uuidFactory.create());
+ update.setLong(2, row.getLong(1));
+ return true;
+ });
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.duplicationsindex;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.MigrationStep;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+public class AddPrimaryKeyOnUuidColumnOfDuplicationsIndexTableTest {
+
+ @Rule
+ public CoreDbTester db = CoreDbTester.createForSchema(AddPrimaryKeyOnUuidColumnOfDuplicationsIndexTableTest.class, "schema.sql");
+
+ private MigrationStep underTest = new AddPrimaryKeyOnUuidColumnOfDuplicationsIndexTable(db.database());
+
+ @Test
+ public void execute() throws SQLException {
+ underTest.execute();
+
+ db.assertPrimaryKey("duplications_index", "pk_duplications_index", "uuid");
+ }
+
+ @Test
+ public void migration_is_not_re_entrant() throws SQLException {
+ underTest.execute();
+
+ assertThatThrownBy(() -> underTest.execute()).isInstanceOf(IllegalStateException.class);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.duplicationsindex;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.core.util.UuidFactoryFast;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class AddUuidToDuplicationsIndexTableTest {
+
+ @Rule
+ public CoreDbTester db = CoreDbTester.createForSchema(AddUuidToDuplicationsIndexTableTest.class, "schema.sql");
+
+ private DdlChange underTest = new AddUuidToDuplicationsIndexTable(db.database());
+
+ private UuidFactoryFast uuidFactory = UuidFactoryFast.getInstance();
+
+ @Before
+ public void setup() {
+ insertDuplicationsIndex(1L);
+ insertDuplicationsIndex(2L);
+ insertDuplicationsIndex(3L);
+ }
+
+ @Test
+ public void add_uuid_column_to_duplications_index() throws SQLException {
+ underTest.execute();
+
+ db.assertColumnDefinition("duplications_index", "uuid", Types.VARCHAR, 40, true);
+
+ assertThat(db.countRowsOfTable("duplications_index"))
+ .isEqualTo(3);
+ }
+
+ private void insertDuplicationsIndex(Long id) {
+ db.executeInsert("duplications_index",
+ "id", id,
+ "hash", uuidFactory.create(),
+ "index_in_file", id + 1,
+ "start_line", id + 2,
+ "end_line", id + 3,
+ "component_uuid", uuidFactory.create(),
+ "analysis_uuid", uuidFactory.create());
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.duplicationsindex;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.MigrationStep;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+public class DropIdColumnOfDuplicationsIndexTableTest {
+
+ @Rule
+ public CoreDbTester db = CoreDbTester.createForSchema(DropIdColumnOfDuplicationsIndexTableTest.class, "schema.sql");
+
+ private MigrationStep underTest = new DropIdColumnOfDuplicationsIndexTable(db.database());
+
+ @Test
+ public void execute() throws SQLException {
+ underTest.execute();
+
+ db.assertColumnDoesNotExist("duplications_index", "id");
+ }
+
+ @Test
+ public void migration_is_not_re_entrant() throws SQLException {
+ underTest.execute();
+
+ assertThatThrownBy(() -> underTest.execute()).isInstanceOf(IllegalStateException.class);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.duplicationsindex;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.MigrationStep;
+import org.sonar.server.platform.db.migration.version.v83.util.DropPrimaryKeySqlGenerator;
+import org.sonar.server.platform.db.migration.version.v83.util.GetConstraintHelper;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+public class DropPrimaryKeyOnIdColumnOfDuplicationsIndexTableTest {
+
+ private static final String TABLE_NAME = "duplications_index";
+ @Rule
+ public CoreDbTester db = CoreDbTester.createForSchema(DropPrimaryKeyOnIdColumnOfDuplicationsIndexTableTest.class, "schema.sql");
+
+ private DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator = new DropPrimaryKeySqlGenerator(db.database(), new GetConstraintHelper(db.database()));
+
+ private MigrationStep underTest = new DropPrimaryKeyOnIdColumnOfDuplicationsIndexTable(db.database(), dropPrimaryKeySqlGenerator);
+
+ @Test
+ public void execute() throws SQLException {
+ underTest.execute();
+
+ db.assertNoPrimaryKey(TABLE_NAME);
+ }
+
+ @Test
+ public void migration_is_not_re_entrant() throws SQLException {
+ underTest.execute();
+
+ assertThatThrownBy(() -> underTest.execute()).isInstanceOf(IllegalStateException.class);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.duplicationsindex;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.MigrationStep;
+
+import static java.sql.Types.VARCHAR;
+
+public class MakeDuplicationsIndexUuidColumnNotNullableTest {
+
+ @Rule
+ public CoreDbTester db = CoreDbTester.createForSchema(MakeDuplicationsIndexUuidColumnNotNullableTest.class, "schema.sql");
+
+ private MigrationStep underTest = new MakeDuplicationsIndexUuidColumnNotNullable(db.database());
+
+ @Test
+ public void created_at_and_uuid_columns_are_not_null() throws SQLException {
+ underTest.execute();
+
+ db.assertColumnDefinition("duplications_index", "uuid", VARCHAR, null, false);
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.duplicationsindex;
+
+import java.sql.SQLException;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.core.util.UuidFactoryFast;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.DataChange;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class PopulateDuplicationsIndexUuidTest {
+
+ @Rule
+ public CoreDbTester db = CoreDbTester.createForSchema(PopulateDuplicationsIndexUuidTest.class, "schema.sql");
+
+ private UuidFactory uuidFactory = UuidFactoryFast.getInstance();
+ private DataChange underTest = new PopulateDuplicationsIndexUuid(db.database(), uuidFactory);
+
+ @Test
+ public void populate_uuids() throws SQLException {
+ insertDuplicationsIndex(1L);
+ insertDuplicationsIndex(2L);
+ insertDuplicationsIndex(3L);
+
+ underTest.execute();
+
+ verifyUuidsAreNotNull();
+ }
+
+ @Test
+ public void migration_is_reentrant() throws SQLException {
+ insertDuplicationsIndex(1L);
+ insertDuplicationsIndex(2L);
+ insertDuplicationsIndex(3L);
+
+ underTest.execute();
+ // re-entrant
+ underTest.execute();
+
+ verifyUuidsAreNotNull();
+ }
+
+ private void verifyUuidsAreNotNull() {
+ assertThat(db.select("select uuid from duplications_index")
+ .stream()
+ .map(row -> row.get("UUID"))
+ .filter(Objects::isNull)
+ .collect(Collectors.toList())).isEmpty();
+ }
+
+ private void insertDuplicationsIndex(Long id) {
+ db.executeInsert("duplications_index",
+ "id", id,
+ "hash", uuidFactory.create(),
+ "index_in_file", id + 1,
+ "start_line", id + 2,
+ "end_line", id + 3,
+ "component_uuid", uuidFactory.create(),
+ "analysis_uuid", uuidFactory.create());
+ }
+
+}
--- /dev/null
+CREATE TABLE "DUPLICATIONS_INDEX"(
+ "ID" BIGINT NOT NULL AUTO_INCREMENT (1,1),
+ "ANALYSIS_UUID" VARCHAR(50) NOT NULL,
+ "COMPONENT_UUID" VARCHAR(50) NOT NULL,
+ "HASH" VARCHAR(50) NOT NULL,
+ "INDEX_IN_FILE" INTEGER NOT NULL,
+ "START_LINE" INTEGER NOT NULL,
+ "END_LINE" INTEGER NOT NULL,
+ "UUID" VARCHAR(40) NOT NULL
+);
+CREATE INDEX "DUPLICATIONS_INDEX_HASH" ON "DUPLICATIONS_INDEX"("HASH");
+CREATE INDEX "DUPLICATION_ANALYSIS_COMPONENT" ON "DUPLICATIONS_INDEX"("ANALYSIS_UUID", "COMPONENT_UUID");
--- /dev/null
+CREATE TABLE "DUPLICATIONS_INDEX"(
+ "ID" BIGINT NOT NULL AUTO_INCREMENT (1,1),
+ "ANALYSIS_UUID" VARCHAR(50) NOT NULL,
+ "COMPONENT_UUID" VARCHAR(50) NOT NULL,
+ "HASH" VARCHAR(50) NOT NULL,
+ "INDEX_IN_FILE" INTEGER NOT NULL,
+ "START_LINE" INTEGER NOT NULL,
+ "END_LINE" INTEGER NOT NULL
+);
+ALTER TABLE "DUPLICATIONS_INDEX" ADD CONSTRAINT "PK_DUPLICATIONS_INDEX" PRIMARY KEY("ID");
+CREATE INDEX "DUPLICATIONS_INDEX_HASH" ON "DUPLICATIONS_INDEX"("HASH");
+CREATE INDEX "DUPLICATION_ANALYSIS_COMPONENT" ON "DUPLICATIONS_INDEX"("ANALYSIS_UUID", "COMPONENT_UUID");
+
--- /dev/null
+CREATE TABLE "DUPLICATIONS_INDEX"(
+ "ID" BIGINT NOT NULL,
+ "ANALYSIS_UUID" VARCHAR(50) NOT NULL,
+ "COMPONENT_UUID" VARCHAR(50) NOT NULL,
+ "HASH" VARCHAR(50) NOT NULL,
+ "INDEX_IN_FILE" INTEGER NOT NULL,
+ "START_LINE" INTEGER NOT NULL,
+ "END_LINE" INTEGER NOT NULL,
+ "UUID" VARCHAR(40) NOT NULL,
+);
+ALTER TABLE "DUPLICATIONS_INDEX" ADD CONSTRAINT "PK_DUPLICATIONS_INDEX" PRIMARY KEY("UUID");
+CREATE INDEX "DUPLICATIONS_INDEX_HASH" ON "DUPLICATIONS_INDEX"("HASH");
+CREATE INDEX "DUPLICATION_ANALYSIS_COMPONENT" ON "DUPLICATIONS_INDEX"("ANALYSIS_UUID", "COMPONENT_UUID");
--- /dev/null
+CREATE TABLE "DUPLICATIONS_INDEX"(
+ "ID" BIGINT NOT NULL AUTO_INCREMENT (1,1),
+ "ANALYSIS_UUID" VARCHAR(50) NOT NULL,
+ "COMPONENT_UUID" VARCHAR(50) NOT NULL,
+ "HASH" VARCHAR(50) NOT NULL,
+ "INDEX_IN_FILE" INTEGER NOT NULL,
+ "START_LINE" INTEGER NOT NULL,
+ "END_LINE" INTEGER NOT NULL,
+ "UUID" VARCHAR(40) NOT NULL,
+);
+ALTER TABLE "DUPLICATIONS_INDEX" ADD CONSTRAINT "PK_DUPLICATIONS_INDEX" PRIMARY KEY("ID");
+CREATE INDEX "DUPLICATIONS_INDEX_HASH" ON "DUPLICATIONS_INDEX"("HASH");
+CREATE INDEX "DUPLICATION_ANALYSIS_COMPONENT" ON "DUPLICATIONS_INDEX"("ANALYSIS_UUID", "COMPONENT_UUID");
--- /dev/null
+CREATE TABLE "DUPLICATIONS_INDEX"(
+ "ID" BIGINT NOT NULL AUTO_INCREMENT (1,1),
+ "ANALYSIS_UUID" VARCHAR(50) NOT NULL,
+ "COMPONENT_UUID" VARCHAR(50) NOT NULL,
+ "HASH" VARCHAR(50) NOT NULL,
+ "INDEX_IN_FILE" INTEGER NOT NULL,
+ "START_LINE" INTEGER NOT NULL,
+ "END_LINE" INTEGER NOT NULL,
+ "UUID" VARCHAR(40)
+);
+ALTER TABLE "DUPLICATIONS_INDEX" ADD CONSTRAINT "PK_DUPLICATIONS_INDEX" PRIMARY KEY("ID");
+CREATE INDEX "DUPLICATIONS_INDEX_HASH" ON "DUPLICATIONS_INDEX"("HASH");
+CREATE INDEX "DUPLICATION_ANALYSIS_COMPONENT" ON "DUPLICATIONS_INDEX"("ANALYSIS_UUID", "COMPONENT_UUID");
--- /dev/null
+CREATE TABLE "DUPLICATIONS_INDEX"(
+ "ID" BIGINT NOT NULL AUTO_INCREMENT (1,1),
+ "ANALYSIS_UUID" VARCHAR(50) NOT NULL,
+ "COMPONENT_UUID" VARCHAR(50) NOT NULL,
+ "HASH" VARCHAR(50) NOT NULL,
+ "INDEX_IN_FILE" INTEGER NOT NULL,
+ "START_LINE" INTEGER NOT NULL,
+ "END_LINE" INTEGER NOT NULL,
+ "UUID" VARCHAR(40)
+);
+ALTER TABLE "DUPLICATIONS_INDEX" ADD CONSTRAINT "PK_DUPLICATIONS_INDEX" PRIMARY KEY("ID");
+CREATE INDEX "DUPLICATIONS_INDEX_HASH" ON "DUPLICATIONS_INDEX"("HASH");
+CREATE INDEX "DUPLICATION_ANALYSIS_COMPONENT" ON "DUPLICATIONS_INDEX"("ANALYSIS_UUID", "COMPONENT_UUID");