diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2015-07-17 10:38:17 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2015-07-17 12:38:17 +0200 |
commit | bdcfb7eeb7caaeb9019ff0d3946153c33bc6c5e9 (patch) | |
tree | 8e0bc944f83d81a003061543f9db9139966ba985 /sonar-db/src | |
parent | 48697451f2b0ba517c7d1861af3897b4ace896f9 (diff) | |
download | sonarqube-bdcfb7eeb7caaeb9019ff0d3946153c33bc6c5e9.tar.gz sonarqube-bdcfb7eeb7caaeb9019ff0d3946153c33bc6c5e9.zip |
Move Java db migrations from sonar-server to sonar-db
Diffstat (limited to 'sonar-db/src')
228 files changed, 13122 insertions, 0 deletions
diff --git a/sonar-db/src/main/java/org/sonar/db/version/AddColumnsBuilder.java b/sonar-db/src/main/java/org/sonar/db/version/AddColumnsBuilder.java new file mode 100644 index 00000000000..ab6543fffe7 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/AddColumnsBuilder.java @@ -0,0 +1,146 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import com.google.common.base.CharMatcher; +import com.google.common.base.Preconditions; +import java.util.List; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import org.sonar.db.dialect.Dialect; +import org.sonar.db.dialect.MsSql; +import org.sonar.db.dialect.Oracle; +import org.sonar.db.dialect.PostgreSql; + +import static com.google.common.collect.Lists.newArrayList; + +public class AddColumnsBuilder { + + private final Dialect dialect; + private final String tableName; + private List<ColumnDef> columnDefs = newArrayList(); + + public AddColumnsBuilder(Dialect dialect, String tableName) { + this.tableName = tableName; + this.dialect = dialect; + } + + public AddColumnsBuilder addColumn(ColumnDef columnDef) { + columnDefs.add(columnDef); + return this; + } + + public String build() { + StringBuilder sql = new StringBuilder().append("ALTER TABLE ").append(tableName).append(" "); + switch (dialect.getId()) { + case PostgreSql.ID: + addColumns(sql, "ADD COLUMN "); + break; + case MsSql.ID: + sql.append("ADD "); + addColumns(sql, ""); + break; + default: + sql.append("ADD ("); + addColumns(sql, ""); + sql.append(")"); + } + return sql.toString(); + } + + private void addColumns(StringBuilder sql, String columnPrefix) { + for (int i = 0; i < columnDefs.size(); i++) { + sql.append(columnPrefix); + addColumn(sql, columnDefs.get(i)); + if (i < columnDefs.size() - 1) { + sql.append(", "); + } + } + } + + private void addColumn(StringBuilder sql, ColumnDef columnDef) { + sql.append(columnDef.getName()).append(" ").append(typeToSql(columnDef)); + Integer limit = columnDef.getLimit(); + if (limit != null) { + sql.append(" (").append(Integer.toString(limit)).append(")"); + } + sql.append(columnDef.isNullable() ? " NULL" : " NOT NULL"); + } + + private String typeToSql(ColumnDef columnDef) { + switch (columnDef.getType()) { + case STRING: + return "VARCHAR"; + case BIG_INTEGER: + return !dialect.getId().equals(Oracle.ID) ? "BIGINT" : "NUMBER (38)"; + default: + throw new IllegalArgumentException("Unsupported type : " + columnDef.getType()); + } + } + + public static class ColumnDef { + private String name; + private Type type; + private boolean isNullable; + private Integer limit; + + public enum Type { + STRING, BIG_INTEGER + } + + public ColumnDef setNullable(boolean isNullable) { + this.isNullable = isNullable; + return this; + } + + public ColumnDef setLimit(@Nullable Integer limit) { + this.limit = limit; + return this; + } + + public ColumnDef setName(String name) { + Preconditions.checkArgument(CharMatcher.JAVA_LOWER_CASE.or(CharMatcher.anyOf("_")).matchesAllOf(name), "Column name should only contains lowercase and _ characters"); + this.name = name; + return this; + } + + public ColumnDef setType(Type type) { + this.type = type; + return this; + } + + public boolean isNullable() { + return isNullable; + } + + @CheckForNull + public Integer getLimit() { + return limit; + } + + public String getName() { + return name; + } + + public Type getType() { + return type; + } + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/BaseDataChange.java b/sonar-db/src/main/java/org/sonar/db/version/BaseDataChange.java new file mode 100644 index 00000000000..800e66a7e34 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/BaseDataChange.java @@ -0,0 +1,65 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import java.sql.Connection; +import java.sql.SQLException; +import org.apache.commons.dbutils.DbUtils; +import org.sonar.db.Database; + +public abstract class BaseDataChange implements DataChange, MigrationStep { + + private final Database db; + + public BaseDataChange(Database db) { + this.db = db; + } + + @Override + public final void execute() throws SQLException { + Connection readConnection = null; + Connection writeConnection = null; + try { + readConnection = openConnection(); + + writeConnection = db.getDataSource().getConnection(); + writeConnection.setAutoCommit(false); + Context context = new Context(db, readConnection, writeConnection); + execute(context); + + } finally { + DbUtils.closeQuietly(readConnection); + DbUtils.closeQuietly(writeConnection); + } + } + + /** + * Do not forget to close it ! + */ + protected Connection openConnection() throws SQLException { + Connection connection = db.getDataSource().getConnection(); + connection.setAutoCommit(false); + if (connection.getMetaData().supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_UNCOMMITTED)) { + connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED); + } + return connection; + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/BaseSqlStatement.java b/sonar-db/src/main/java/org/sonar/db/version/BaseSqlStatement.java new file mode 100644 index 00000000000..f302311bb2d --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/BaseSqlStatement.java @@ -0,0 +1,105 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.sql.Types; +import java.util.Date; +import javax.annotation.Nullable; +import org.apache.commons.dbutils.DbUtils; + +class BaseSqlStatement<CHILD extends SqlStatement> implements SqlStatement<CHILD> { + protected PreparedStatement pstmt; + + protected BaseSqlStatement(PreparedStatement pstmt) { + this.pstmt = pstmt; + } + + @Override + public CHILD close() { + DbUtils.closeQuietly(pstmt); + pstmt = null; + return (CHILD) this; + } + + @Override + public CHILD setString(int columnIndex, @Nullable String value) throws SQLException { + pstmt.setString(columnIndex, value); + return (CHILD) this; + } + + @Override + public CHILD setBytes(int columnIndex, @Nullable byte[] value) throws SQLException { + pstmt.setBytes(columnIndex, value); + return (CHILD) this; + } + + @Override + public CHILD setInt(int columnIndex, @Nullable Integer value) throws SQLException { + if (value == null) { + pstmt.setNull(columnIndex, Types.INTEGER); + } else { + pstmt.setInt(columnIndex, value); + } + return (CHILD) this; + } + + @Override + public CHILD setLong(int columnIndex, @Nullable Long value) throws SQLException { + if (value == null) { + pstmt.setNull(columnIndex, Types.BIGINT); + } else { + pstmt.setLong(columnIndex, value); + } + return (CHILD) this; + } + + @Override + public CHILD setBoolean(int columnIndex, @Nullable Boolean value) throws SQLException { + if (value == null) { + pstmt.setNull(columnIndex, Types.BOOLEAN); + } else { + pstmt.setBoolean(columnIndex, value); + } + return (CHILD) this; + } + + @Override + public CHILD setDouble(int columnIndex, @Nullable Double value) throws SQLException { + if (value == null) { + pstmt.setNull(columnIndex, Types.DECIMAL); + } else { + pstmt.setDouble(columnIndex, value); + } + return (CHILD) this; + } + + @Override + public CHILD setDate(int columnIndex, @Nullable Date value) throws SQLException { + if (value == null) { + pstmt.setNull(columnIndex, Types.TIMESTAMP); + } else { + pstmt.setTimestamp(columnIndex, new Timestamp(value.getTime())); + } + return (CHILD) this; + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/DataChange.java b/sonar-db/src/main/java/org/sonar/db/version/DataChange.java new file mode 100644 index 00000000000..d06e4d7b093 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/DataChange.java @@ -0,0 +1,53 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import java.sql.Connection; +import java.sql.SQLException; +import org.sonar.db.Database; + +public interface DataChange { + + class Context { + private final Database db; + private final Connection readConnection; + private final Connection writeConnection; + + public Context(Database db, Connection readConnection, Connection writeConnection) { + this.db = db; + this.readConnection = readConnection; + this.writeConnection = writeConnection; + } + + public Select prepareSelect(String sql) throws SQLException { + return SelectImpl.create(db, readConnection, sql); + } + + public Upsert prepareUpsert(String sql) throws SQLException { + return UpsertImpl.create(writeConnection, sql); + } + + public MassUpdate prepareMassUpdate() throws SQLException { + return new MassUpdate(db, readConnection, writeConnection); + } + } + + void execute(Context context) throws SQLException; +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/DatabaseMigration.java b/sonar-db/src/main/java/org/sonar/db/version/DatabaseMigration.java new file mode 100644 index 00000000000..1d00155e13b --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/DatabaseMigration.java @@ -0,0 +1,70 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import java.util.Date; +import javax.annotation.CheckForNull; + +public interface DatabaseMigration { + enum Status { + NONE, RUNNING, FAILED, SUCCEEDED + } + + /** + * Starts the migration status and returns immediately. + * <p> + * Migration can not be started twice but calling this method wont raise an error. + * On the other hand, calling this method when no migration is needed will start the process anyway. + * </p> + * <p> + * <strong>This method should be named {@code start} but it can not be because it will be called by the pico container + * and this will cause unwanted behavior</strong> + * </p> + */ + void startIt(); + + /** + * The time and day the last migration was started. + * <p> + * If no migration was ever started, the returned date is {@code null}. This value is reset when {@link #startIt()} is + * called. + * </p> + * + * @return a {@link Date} or {@code null} + */ + @CheckForNull + Date startedAt(); + + /** + * Current status of the migration. + */ + Status status(); + + /** + * The error of the last migration if it failed. + * <p> + * This value is reset when {@link #startIt()} is called. + * </p> + * @return a {@link Throwable} or {@code null} + */ + @CheckForNull + Throwable failureError(); + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/DdlChange.java b/sonar-db/src/main/java/org/sonar/db/version/DdlChange.java new file mode 100644 index 00000000000..1e2bcb47582 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/DdlChange.java @@ -0,0 +1,67 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import java.sql.Connection; +import java.sql.SQLException; +import org.apache.commons.dbutils.DbUtils; +import org.sonar.db.Database; + +public abstract class DdlChange implements MigrationStep { + + private final Database db; + + public DdlChange(Database db) { + this.db = db; + } + + @Override + public final void execute() throws SQLException { + Connection writeConnection = null; + try { + writeConnection = db.getDataSource().getConnection(); + writeConnection.setAutoCommit(false); + Context context = new Context(writeConnection); + execute(context); + + } finally { + DbUtils.closeQuietly(writeConnection); + } + } + + public static class Context { + private final Connection writeConnection; + + public Context(Connection writeConnection) { + this.writeConnection = writeConnection; + } + + public void execute(String sql) throws SQLException { + try { + UpsertImpl.create(writeConnection, sql).execute().commit(); + } catch (Exception e) { + throw new IllegalStateException(String.format("Fail to execute %s", sql), e); + } + } + } + + public abstract void execute(Context context) throws SQLException; + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/DropColumnsBuilder.java b/sonar-db/src/main/java/org/sonar/db/version/DropColumnsBuilder.java new file mode 100644 index 00000000000..61a0fbc45c8 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/DropColumnsBuilder.java @@ -0,0 +1,72 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import org.sonar.db.dialect.Dialect; +import org.sonar.db.dialect.MsSql; +import org.sonar.db.dialect.MySql; +import org.sonar.db.dialect.Oracle; +import org.sonar.db.dialect.PostgreSql; + +public class DropColumnsBuilder { + + private final Dialect dialect; + private final String tableName; + private final String[] columns; + + public DropColumnsBuilder(Dialect dialect, String tableName, String... columns) { + this.tableName = tableName; + this.dialect = dialect; + this.columns = columns; + } + + public String build() { + StringBuilder sql = new StringBuilder().append("ALTER TABLE ").append(tableName).append(" "); + switch (dialect.getId()) { + case PostgreSql.ID: + case MySql.ID: + dropColumns(sql, "DROP COLUMN "); + break; + case MsSql.ID: + sql.append("DROP COLUMN "); + dropColumns(sql, ""); + break; + case Oracle.ID: + sql.append("DROP ("); + dropColumns(sql, ""); + sql.append(")"); + break; + default: + throw new IllegalStateException(String.format("Unsupported database '%s'", dialect.getId())); + } + return sql.toString(); + } + + private void dropColumns(StringBuilder sql, String columnPrefix) { + for (int i = 0; i < columns.length; i++) { + sql.append(columnPrefix); + sql.append(columns[i]); + if (i < columns.length - 1) { + sql.append(", "); + } + } + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/MassUpdate.java b/sonar-db/src/main/java/org/sonar/db/version/MassUpdate.java new file mode 100644 index 00000000000..a09ed828a5c --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/MassUpdate.java @@ -0,0 +1,97 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.concurrent.atomic.AtomicLong; +import org.sonar.core.util.ProgressLogger; +import org.sonar.db.Database; + +public class MassUpdate { + + public interface Handler { + /** + * Convert some column values of a given row. + * + * @return true if the row must be updated, else false. If false, then the update parameter must not be touched. + */ + boolean handle(Select.Row row, SqlStatement update) throws SQLException; + } + + private final Database db; + private final Connection readConnection; + private final Connection writeConnection; + private final AtomicLong counter = new AtomicLong(0L); + private final ProgressLogger progress = ProgressLogger.create(getClass(), counter); + + private Select select; + private Upsert update; + + MassUpdate(Database db, Connection readConnection, Connection writeConnection) { + this.db = db; + this.readConnection = readConnection; + this.writeConnection = writeConnection; + } + + public SqlStatement select(String sql) throws SQLException { + this.select = SelectImpl.create(db, readConnection, sql); + return this.select; + } + + public MassUpdate update(String sql) throws SQLException { + this.update = UpsertImpl.create(writeConnection, sql); + return this; + } + + public MassUpdate rowPluralName(String s) { + this.progress.setPluralLabel(s); + return this; + } + + public void execute(final Handler handler) throws SQLException { + if (select == null || update == null) { + throw new IllegalStateException("SELECT or UPDATE requests are not defined"); + } + + progress.start(); + try { + select.scroll(new Select.RowHandler() { + @Override + public void handle(Select.Row row) throws SQLException { + if (handler.handle(row, update)) { + update.addBatch(); + } + counter.getAndIncrement(); + } + }); + if (((UpsertImpl) update).getBatchCount() > 0L) { + update.execute().commit(); + } + update.close(); + + // log the total number of processed rows + progress.log(); + } finally { + progress.stop(); + } + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/MigrationStep.java b/sonar-db/src/main/java/org/sonar/db/version/MigrationStep.java new file mode 100644 index 00000000000..f34fdcffcd8 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/MigrationStep.java @@ -0,0 +1,32 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import java.sql.SQLException; + +/** + * Java alternative of ActiveRecord::Migration. Do not forget to declare implementation classes in {@link MigrationStepModule} + * @since 3.7 + */ +public interface MigrationStep { + + void execute() throws SQLException; + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java b/sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java new file mode 100644 index 00000000000..4e1ea5cd811 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java @@ -0,0 +1,108 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import org.sonar.core.platform.Module; +import org.sonar.db.version.v451.AddMissingCustomRuleParametersMigrationStep; +import org.sonar.db.version.v451.DeleteUnescapedActivities; +import org.sonar.db.version.v50.FeedFileSources; +import org.sonar.db.version.v50.FeedIssueLongDates; +import org.sonar.db.version.v50.FeedSnapshotSourcesUpdatedAt; +import org.sonar.db.version.v50.InsertProjectsAuthorizationUpdatedAtMigrationStep; +import org.sonar.db.version.v50.PopulateProjectsUuidColumnsMigrationStep; +import org.sonar.db.version.v50.RemoveSortFieldFromIssueFiltersMigrationStep; +import org.sonar.db.version.v50.ReplaceIssueFiltersProjectKeyByUuid; +import org.sonar.db.version.v51.AddIssuesColumns; +import org.sonar.db.version.v51.AddNewCharacteristics; +import org.sonar.db.version.v51.CopyScmAccountsFromAuthorsToUsers; +import org.sonar.db.version.v51.DropIssuesColumns; +import org.sonar.db.version.v51.FeedAnalysisReportsLongDates; +import org.sonar.db.version.v51.FeedEventsLongDates; +import org.sonar.db.version.v51.FeedFileSourcesBinaryData; +import org.sonar.db.version.v51.FeedIssueChangesLongDates; +import org.sonar.db.version.v51.FeedIssueComponentUuids; +import org.sonar.db.version.v51.FeedIssueTags; +import org.sonar.db.version.v51.FeedIssuesLongDates; +import org.sonar.db.version.v51.FeedManualMeasuresLongDates; +import org.sonar.db.version.v51.FeedSnapshotsLongDates; +import org.sonar.db.version.v51.FeedUsersLongDates; +import org.sonar.db.version.v51.RemovePermissionsOnModulesMigrationStep; +import org.sonar.db.version.v51.RenameComponentRelatedParamsInIssueFilters; +import org.sonar.db.version.v51.UpdateProjectsModuleUuidPath; +import org.sonar.db.version.v52.AddManualMeasuresComponentUuidColumn; +import org.sonar.db.version.v52.FeedEventsComponentUuid; +import org.sonar.db.version.v52.FeedFileSourcesDataType; +import org.sonar.db.version.v52.FeedManualMeasuresComponentUuid; +import org.sonar.db.version.v52.FeedMetricsBooleans; +import org.sonar.db.version.v52.FeedProjectLinksComponentUuid; +import org.sonar.db.version.v52.MoveProjectProfileAssociation; +import org.sonar.db.version.v52.RemoveComponentLibraries; +import org.sonar.db.version.v52.RemoveDuplicatedComponentKeys; +import org.sonar.db.version.v52.RemoveSnapshotLibraries; + +public class MigrationStepModule extends Module { + @Override + protected void configureModule() { + add( + // 4.5.1 + AddMissingCustomRuleParametersMigrationStep.class, + DeleteUnescapedActivities.class, + + // 5.0 + InsertProjectsAuthorizationUpdatedAtMigrationStep.class, + PopulateProjectsUuidColumnsMigrationStep.class, + ReplaceIssueFiltersProjectKeyByUuid.class, + FeedSnapshotSourcesUpdatedAt.class, + FeedFileSources.class, + FeedIssueLongDates.class, + RemoveSortFieldFromIssueFiltersMigrationStep.class, + + // 5.1 + FeedIssueTags.class, + FeedUsersLongDates.class, + RenameComponentRelatedParamsInIssueFilters.class, + CopyScmAccountsFromAuthorsToUsers.class, + FeedIssueChangesLongDates.class, + FeedAnalysisReportsLongDates.class, + UpdateProjectsModuleUuidPath.class, + FeedIssueComponentUuids.class, + FeedSnapshotsLongDates.class, + FeedIssuesLongDates.class, + FeedFileSourcesBinaryData.class, + FeedManualMeasuresLongDates.class, + FeedEventsLongDates.class, + AddNewCharacteristics.class, + RemovePermissionsOnModulesMigrationStep.class, + AddIssuesColumns.class, + DropIssuesColumns.class, + + // 5.2 + FeedProjectLinksComponentUuid.class, + FeedEventsComponentUuid.class, + MoveProjectProfileAssociation.class, + FeedFileSourcesDataType.class, + FeedMetricsBooleans.class, + AddManualMeasuresComponentUuidColumn.class, + FeedManualMeasuresComponentUuid.class, + RemoveSnapshotLibraries.class, + RemoveComponentLibraries.class, + RemoveDuplicatedComponentKeys.class); + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/Select.java b/sonar-db/src/main/java/org/sonar/db/version/Select.java new file mode 100644 index 00000000000..ab9433d25e6 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/Select.java @@ -0,0 +1,167 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.Date; +import java.util.List; +import javax.annotation.CheckForNull; + +public interface Select extends SqlStatement<Select> { + + class Row { + private final ResultSet rs; + + Row(ResultSet rs) { + this.rs = rs; + } + + @CheckForNull + public Long getNullableLong(int columnIndex) throws SQLException { + long l = rs.getLong(columnIndex); + return rs.wasNull() ? null : l; + } + + public long getLong(int columnIndex) throws SQLException { + return rs.getLong(columnIndex); + } + + @CheckForNull + public Double getNullableDouble(int columnIndex) throws SQLException { + double d = rs.getDouble(columnIndex); + return rs.wasNull() ? null : d; + } + + public double getDouble(int columnIndex) throws SQLException { + return rs.getDouble(columnIndex); + } + + @CheckForNull + public Integer getNullableInt(int columnIndex) throws SQLException { + int i = rs.getInt(columnIndex); + return rs.wasNull() ? null : i; + } + + public int getInt(int columnIndex) throws SQLException { + return rs.getInt(columnIndex); + } + + @CheckForNull + public Boolean getNullableBoolean(int columnIndex) throws SQLException { + boolean b = rs.getBoolean(columnIndex); + return rs.wasNull() ? null : b; + } + + public boolean getBoolean(int columnIndex) throws SQLException { + return rs.getBoolean(columnIndex); + } + + @CheckForNull + public String getNullableString(int columnIndex) throws SQLException { + String s = rs.getString(columnIndex); + return rs.wasNull() ? null : s; + } + + public String getString(int columnIndex) throws SQLException { + return rs.getString(columnIndex); + } + + @CheckForNull + public Date getNullableDate(int columnIndex) throws SQLException { + Timestamp t = rs.getTimestamp(columnIndex); + return rs.wasNull() ? null : t; + } + + public Date getDate(int columnIndex) throws SQLException { + return rs.getTimestamp(columnIndex); + } + + @CheckForNull + public byte[] getNullableBytes(int columnIndex) throws SQLException { + byte[] b = rs.getBytes(columnIndex); + return rs.wasNull() ? null : b; + } + + public byte[] getBytes(int columnIndex) throws SQLException { + return rs.getBytes(columnIndex); + } + + @Override + public String toString() { + try { + ResultSetMetaData rsMetaData = rs.getMetaData(); + StringBuilder sb = new StringBuilder(); + for (int i = 1; i <= rsMetaData.getColumnCount(); i++) { + if (i > 1) { + sb.append(","); + } + sb.append(rsMetaData.getColumnLabel(i).toLowerCase()); + sb.append("="); + sb.append(rs.getObject(i)); + } + return sb.toString(); + } catch (Exception e) { + return "Unavailable: " + e.getMessage(); + } + } + } + + interface RowReader<T> { + T read(Row row) throws SQLException; + } + + class LongReader implements RowReader<Long> { + private LongReader() { + } + + @Override + public Long read(Row row) throws SQLException { + return row.getNullableLong(1); + } + } + + RowReader<Long> LONG_READER = new LongReader(); + + class StringReader implements RowReader<String> { + private StringReader() { + } + + @Override + public String read(Row row) throws SQLException { + return row.getNullableString(1); + } + } + + RowReader<String> STRING_READER = new StringReader(); + + interface RowHandler { + void handle(Row row) throws SQLException; + } + + <T> List<T> list(RowReader<T> reader) throws SQLException; + + @CheckForNull + <T> T get(RowReader<T> reader) throws SQLException; + + void scroll(RowHandler handler) throws SQLException; +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/SelectImpl.java b/sonar-db/src/main/java/org/sonar/db/version/SelectImpl.java new file mode 100644 index 00000000000..90031326979 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/SelectImpl.java @@ -0,0 +1,98 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.dbutils.DbUtils; +import org.sonar.db.Database; + +class SelectImpl extends BaseSqlStatement<Select> implements Select { + + private SelectImpl(PreparedStatement pstmt) { + super(pstmt); + } + + @Override + public <T> List<T> list(Select.RowReader<T> reader) throws SQLException { + ResultSet rs = pstmt.executeQuery(); + Select.Row row = new Select.Row(rs); + try { + List<T> rows = new ArrayList<>(); + while (rs.next()) { + rows.add(reader.read(row)); + } + return rows; + } catch (Exception e) { + throw newExceptionWithRowDetails(row, e); + } finally { + DbUtils.closeQuietly(rs); + close(); + } + } + + @Override + public <T> T get(Select.RowReader<T> reader) throws SQLException { + ResultSet rs = pstmt.executeQuery(); + Select.Row row = new Select.Row(rs); + try { + if (rs.next()) { + return reader.read(row); + } + return null; + } catch (Exception e) { + throw newExceptionWithRowDetails(row, e); + } finally { + DbUtils.closeQuietly(rs); + close(); + } + } + + @Override + public void scroll(Select.RowHandler handler) throws SQLException { + ResultSet rs = pstmt.executeQuery(); + Select.Row row = new Select.Row(rs); + try { + while (rs.next()) { + handler.handle(row); + } + } catch (Exception e) { + throw newExceptionWithRowDetails(row, e); + } finally { + DbUtils.closeQuietly(rs); + close(); + } + } + + private IllegalStateException newExceptionWithRowDetails(Select.Row row, Exception e) { + return new IllegalStateException("Error during processing of row: [" + row + "]", e); + } + + static SelectImpl create(Database db, Connection connection, String sql) throws SQLException { + // TODO use DbClient#newScrollingSelectStatement() + PreparedStatement pstmt = connection.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); + pstmt.setFetchSize(db.getDialect().getScrollDefaultFetchSize()); + return new SelectImpl(pstmt); + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/SqlStatement.java b/sonar-db/src/main/java/org/sonar/db/version/SqlStatement.java new file mode 100644 index 00000000000..4418f659b16 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/SqlStatement.java @@ -0,0 +1,42 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import java.sql.SQLException; +import java.util.Date; +import javax.annotation.Nullable; + +public interface SqlStatement<CHILD extends SqlStatement> { + CHILD setBoolean(int columnIndex, @Nullable Boolean value) throws SQLException; + + CHILD setDate(int columnIndex, @Nullable Date value) throws SQLException; + + CHILD setDouble(int columnIndex, @Nullable Double value) throws SQLException; + + CHILD setInt(int columnIndex, @Nullable Integer value) throws SQLException; + + CHILD setLong(int columnIndex, @Nullable Long value) throws SQLException; + + CHILD setString(int columnIndex, @Nullable String value) throws SQLException; + + CHILD setBytes(int columnIndex, @Nullable byte[] data) throws SQLException; + + CHILD close(); +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/Upsert.java b/sonar-db/src/main/java/org/sonar/db/version/Upsert.java new file mode 100644 index 00000000000..31068959a1b --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/Upsert.java @@ -0,0 +1,33 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import java.sql.SQLException; + +/** + * INSERT, UPDATE or DELETE + */ +public interface Upsert extends SqlStatement<Upsert> { + Upsert addBatch() throws SQLException; + + Upsert execute() throws SQLException; + + Upsert commit() throws SQLException; +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/UpsertImpl.java b/sonar-db/src/main/java/org/sonar/db/version/UpsertImpl.java new file mode 100644 index 00000000000..7f58429fac3 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/UpsertImpl.java @@ -0,0 +1,70 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import org.sonar.db.BatchSession; + +public class UpsertImpl extends BaseSqlStatement<Upsert> implements Upsert { + + private long batchCount = 0L; + + private UpsertImpl(PreparedStatement pstmt) { + super(pstmt); + } + + @Override + public Upsert addBatch() throws SQLException { + pstmt.addBatch(); + pstmt.clearParameters(); + batchCount++; + if (batchCount % BatchSession.MAX_BATCH_SIZE == 0L) { + pstmt.executeBatch(); + pstmt.getConnection().commit(); + } + return this; + } + + @Override + public Upsert execute() throws SQLException { + if (batchCount == 0L) { + pstmt.execute(); + } else { + pstmt.executeBatch(); + } + return this; + } + + public long getBatchCount() { + return batchCount; + } + + @Override + public Upsert commit() throws SQLException { + pstmt.getConnection().commit(); + return this; + } + + static UpsertImpl create(Connection connection, String sql) throws SQLException { + return new UpsertImpl(connection.prepareStatement(sql)); + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationStep.java b/sonar-db/src/main/java/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationStep.java new file mode 100644 index 00000000000..ec8aa9cdbe6 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationStep.java @@ -0,0 +1,143 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v451; + +import com.google.common.base.Predicate; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Iterables; +import com.google.common.collect.Multimap; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.concurrent.atomic.AtomicLong; +import javax.annotation.Nullable; +import org.sonar.api.utils.System2; +import org.sonar.core.util.ProgressLogger; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.version.MigrationStep; +import org.sonar.db.version.v45.Migration45Mapper; +import org.sonar.db.version.v45.Rule; +import org.sonar.db.version.v45.RuleParameter; + +/** + * See http://jira.sonarsource.com/browse/SONAR-5575 + * + * Add missing parameters (with no value) on each custom rules + * + * @since 4.5.1 + */ +public class AddMissingCustomRuleParametersMigrationStep implements MigrationStep { + + private final DbClient db; + private final System2 system; + private final AtomicLong counter = new AtomicLong(0L); + + public AddMissingCustomRuleParametersMigrationStep(DbClient db, System2 system) { + this.db = db; + this.system = system; + } + + @Override + public void execute() { + ProgressLogger progress = ProgressLogger.create(getClass(), counter); + progress.start(); + + DbSession session = db.openSession(false); + try { + Migration45Mapper mapper = session.getMapper(Migration45Mapper.class); + + List<RuleParameter> templateRuleParams = mapper.selectAllTemplateRuleParameters(); + Multimap<Integer, RuleParameter> templateRuleParamsByRuleId = ArrayListMultimap.create(); + for (RuleParameter templateRuleParam : templateRuleParams) { + templateRuleParamsByRuleId.put(templateRuleParam.getRuleId(), templateRuleParam); + } + + List<Rule> customRules = mapper.selectAllCustomRules(); + Multimap<Integer, Integer> customRuleIdsByTemplateRuleId = HashMultimap.create(); + for (Rule customRule : customRules) { + customRuleIdsByTemplateRuleId.put(customRule.getTemplateId(), customRule.getId()); + } + + List<RuleParameter> customRuleParams = mapper.selectAllCustomRuleParameters(); + Multimap<Integer, RuleParameter> customRuleParamsByRuleId = ArrayListMultimap.create(); + for (RuleParameter customRuleParam : customRuleParams) { + customRuleParamsByRuleId.put(customRuleParam.getRuleId(), customRuleParam); + } + + // For each parameters of template rules, verify that each custom rules has the parameter + for (Integer templateRuleId : templateRuleParamsByRuleId.keySet()) { + for (RuleParameter templateRuleParam : templateRuleParamsByRuleId.get(templateRuleId)) { + // Each custom rule should have this parameter + insertCustomRuleParameterIfNotAlreadyExisting(templateRuleParam, templateRuleId, customRuleIdsByTemplateRuleId, customRuleParamsByRuleId, session); + } + } + + session.commit(); + + // log the total number of process rows + progress.log(); + } finally { + session.close(); + progress.stop(); + } + } + + private void insertCustomRuleParameterIfNotAlreadyExisting(RuleParameter templateRuleParam, Integer templateRuleId, + Multimap<Integer, Integer> customRuleIdsByTemplateRuleId, + Multimap<Integer, RuleParameter> customRuleParamsByRuleId, + DbSession session) { + for (Integer customRuleId : customRuleIdsByTemplateRuleId.get(templateRuleId)) { + if (!hasParameter(templateRuleParam.getName(), customRuleParamsByRuleId.get(customRuleId))) { + // Insert new custom rule parameter + session.getMapper(Migration45Mapper.class).insertRuleParameter(new RuleParameter() + .setRuleId(customRuleId) + .setRuleTemplateId(templateRuleId) + .setName(templateRuleParam.getName()) + .setDescription(templateRuleParam.getDescription()) + .setType(templateRuleParam.getType()) + ); + + // Update updated at date of custom rule in order to allow E/S indexation + session.getMapper(Migration45Mapper.class).updateRuleUpdateAt(customRuleId, new Date(system.now())); + + counter.getAndIncrement(); + } + } + } + + private boolean hasParameter(String parameter, Collection<RuleParameter> customRuleParams) { + return Iterables.any(customRuleParams, new MatchParameter(parameter)); + } + + private static class MatchParameter implements Predicate<RuleParameter> { + private final String parameter; + + public MatchParameter(String parameter) { + this.parameter = parameter; + } + + @Override + public boolean apply(@Nullable RuleParameter input) { + return input != null && input.getName().equals(parameter); + } + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v451/DeleteUnescapedActivities.java b/sonar-db/src/main/java/org/sonar/db/version/v451/DeleteUnescapedActivities.java new file mode 100644 index 00000000000..d22ba822f47 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v451/DeleteUnescapedActivities.java @@ -0,0 +1,71 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v451; + +import java.sql.SQLException; +import javax.annotation.Nullable; +import org.apache.commons.lang.StringUtils; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +/** + * See http://jira.sonarsource.com/browse/SONAR-5758 + * + * @since 4.5.1 + */ +public class DeleteUnescapedActivities extends BaseDataChange { + + public DeleteUnescapedActivities(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("select id,data_field from activities where log_type='QPROFILE'"); + massUpdate.update("delete from activities where id=?"); + massUpdate.execute(new MassUpdate.Handler() { + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + String csv = row.getNullableString(2); + if (isUnescaped(csv)) { + update.setLong(1, row.getNullableLong(1)); + return true; + } + return false; + } + }); + } + + static boolean isUnescaped(@Nullable String csv) { + if (csv != null) { + String[] splits = StringUtils.split(csv, ';'); + for (String split : splits) { + if (StringUtils.countMatches(split, "=") != 1) { + return true; + } + } + } + return false; + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v50/FeedFileSources.java b/sonar-db/src/main/java/org/sonar/db/version/v50/FeedFileSources.java new file mode 100644 index 00000000000..5a4c3921bf5 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v50/FeedFileSources.java @@ -0,0 +1,283 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v50; + +import java.nio.charset.StandardCharsets; +import java.sql.SQLException; +import java.util.Date; +import javax.annotation.Nullable; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.utils.System2; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select.Row; +import org.sonar.db.version.Select.RowReader; +import org.sonar.db.version.SqlStatement; + +/** + * Used in the Active Record Migration 714 + * + * @since 5.0 + */ +public class FeedFileSources extends BaseDataChange { + + private static final String SELECT_FILES_AND_MEASURES_SQL = "SELECT " + + "p.uuid, " + + "f.uuid, " + + "ss.data, " + + "ss.updated_at, " + + + // revisions_by_line + "m1.text_value, " + + "m1.measure_data, " + + + // authors_by_line + "m2.text_value, " + + "m2.measure_data, " + + + // dates_by_line + "m3.text_value, " + + "m3.measure_data, " + + + // hits_by_line + "m4.text_value, " + + "m4.measure_data, " + + + // cond_by_line + "m5.text_value, " + + "m5.measure_data, " + + + // cover_cond_by_line + "m6.text_value, " + + "m6.measure_data, " + + + // it_hits_by_line + "m7.text_value, " + + "m7.measure_data, " + + + // it_cond_by_line + "m8.text_value, " + + "m8.measure_data, " + + + // it_cover_cond_by_line + "m9.text_value, " + + "m9.measure_data, " + + + // overall_hits_by_line + "m10.text_value, " + + "m10.measure_data, " + + + // overall_cond_by_line + "m11.text_value, " + + "m11.measure_data, " + + + // overall_cover_cond_by_line + "m12.text_value, " + + "m12.measure_data, " + + + // duplication_data + "m13.text_value, " + + "m13.measure_data " + + + "FROM snapshots s " + + "JOIN snapshot_sources ss " + + "ON s.id = ss.snapshot_id AND s.islast = ? " + + "JOIN projects p " + + "ON s.root_project_id = p.id " + + "JOIN projects f " + + "ON s.project_id = f.id " + + "LEFT JOIN file_sources fs " + + "ON fs.file_uuid = f.uuid " + + "LEFT JOIN project_measures m1 " + + "ON m1.snapshot_id = s.id AND m1.metric_id = ? " + + "LEFT JOIN project_measures m2 " + + "ON m2.snapshot_id = s.id AND m2.metric_id = ? " + + "LEFT JOIN project_measures m3 " + + "ON m3.snapshot_id = s.id AND m3.metric_id = ? " + + "LEFT JOIN project_measures m4 " + + "ON m4.snapshot_id = s.id AND m4.metric_id = ? " + + "LEFT JOIN project_measures m5 " + + "ON m5.snapshot_id = s.id AND m5.metric_id = ? " + + "LEFT JOIN project_measures m6 " + + "ON m6.snapshot_id = s.id AND m6.metric_id = ? " + + "LEFT JOIN project_measures m7 " + + "ON m7.snapshot_id = s.id AND m7.metric_id = ? " + + "LEFT JOIN project_measures m8 " + + "ON m8.snapshot_id = s.id AND m8.metric_id = ? " + + "LEFT JOIN project_measures m9 " + + "ON m9.snapshot_id = s.id AND m9.metric_id = ? " + + "LEFT JOIN project_measures m10 " + + "ON m10.snapshot_id = s.id AND m10.metric_id = ? " + + "LEFT JOIN project_measures m11 " + + "ON m11.snapshot_id = s.id AND m11.metric_id = ? " + + "LEFT JOIN project_measures m12 " + + "ON m12.snapshot_id = s.id AND m12.metric_id = ? " + + "LEFT JOIN project_measures m13 " + + "ON m13.snapshot_id = s.id AND m13.metric_id = ? " + + "WHERE " + + "f.enabled = ? " + + "AND f.scope = 'FIL' " + + "AND p.scope = 'PRJ' AND p.qualifier = 'TRK' " + + "AND fs.file_uuid IS NULL"; + + private static final class FileSourceBuilder implements MassUpdate.Handler { + private final long now; + + public FileSourceBuilder(System2 system) { + now = system.now(); + } + + @Override + public boolean handle(Row row, SqlStatement update) throws SQLException { + String projectUuid = row.getNullableString(1); + String fileUuid = row.getNullableString(2); + String source = StringUtils.defaultIfBlank(row.getNullableString(3), ""); + Date updatedAt = row.getNullableDate(4); + byte[] shortRevisions = row.getNullableBytes(5); + byte[] longRevisions = row.getNullableBytes(6); + byte[] shortAuthors = row.getNullableBytes(7); + byte[] longAuthors = row.getNullableBytes(8); + byte[] shortDates = row.getNullableBytes(9); + byte[] longDates = row.getNullableBytes(10); + byte[] shortUtHits = row.getNullableBytes(11); + byte[] longUtHits = row.getNullableBytes(12); + byte[] shortUtCond = row.getNullableBytes(13); + byte[] longUtCond = row.getNullableBytes(14); + byte[] shortUtCovCond = row.getNullableBytes(15); + byte[] longUtCovCond = row.getNullableBytes(16); + byte[] shortItHits = row.getNullableBytes(17); + byte[] longItHits = row.getNullableBytes(18); + byte[] shortItCond = row.getNullableBytes(19); + byte[] longItCond = row.getNullableBytes(20); + byte[] shortItCovCond = row.getNullableBytes(21); + byte[] longItCovCond = row.getNullableBytes(22); + byte[] shortOverallHits = row.getNullableBytes(23); + byte[] longOverallHits = row.getNullableBytes(24); + byte[] shortOverallCond = row.getNullableBytes(25); + byte[] longOverallCond = row.getNullableBytes(26); + byte[] shortOverallCovCond = row.getNullableBytes(27); + byte[] longOverallCovCond = row.getNullableBytes(28); + byte[] shortDuplicationData = row.getNullableBytes(29); + byte[] longDuplicationData = row.getNullableBytes(30); + + String[] sourceData = new FileSourceDto(source, + ofNullableBytes(shortRevisions, longRevisions), + ofNullableBytes(shortAuthors, longAuthors), + ofNullableBytes(shortDates, longDates), + ofNullableBytes(shortUtHits, longUtHits), + ofNullableBytes(shortUtCond, longUtCond), + ofNullableBytes(shortUtCovCond, longUtCovCond), + ofNullableBytes(shortItHits, longItHits), + ofNullableBytes(shortItCond, longItCond), + ofNullableBytes(shortItCovCond, longItCovCond), + ofNullableBytes(shortOverallHits, longOverallHits), + ofNullableBytes(shortOverallCond, longOverallCond), + ofNullableBytes(shortOverallCovCond, longOverallCovCond), + ofNullableBytes(shortDuplicationData, longDuplicationData) + ).getSourceData(); + + update.setString(1, projectUuid) + .setString(2, fileUuid) + .setLong(3, now) + .setLong(4, updatedAt == null ? now : updatedAt.getTime()) + .setString(5, sourceData[0]) + .setString(6, sourceData[1]) + .setString(7, ""); + + return true; + } + } + + private static String ofNullableBytes(@Nullable byte[] shortBytes, @Nullable byte[] longBytes) { + byte[] result; + if (shortBytes == null) { + if (longBytes == null) { + return ""; + } else { + result = longBytes; + } + } else { + result = shortBytes; + } + return new String(result, StandardCharsets.UTF_8); + } + + private final System2 system; + + public FeedFileSources(Database db, System2 system) { + super(db); + this.system = system; + } + + @Override + public void execute(Context context) throws SQLException { + RowReader<Long> simpleLongReader = new RowReader<Long>() { + @Override + public Long read(Row row) throws SQLException { + Long longValue = row.getNullableLong(1); + return longValue == null ? Long.valueOf(0L) : longValue; + } + }; + Long revisionMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'revisions_by_line'").get(simpleLongReader); + Long authorMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'authors_by_line'").get(simpleLongReader); + Long datesMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'last_commit_datetimes_by_line'").get(simpleLongReader); + Long utCoverageHitsByLineMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'coverage_line_hits_data'").get(simpleLongReader); + Long utConditionsByLineMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'conditions_by_line'").get(simpleLongReader); + Long utCoveredConditionsByLineMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'covered_conditions_by_line'").get(simpleLongReader); + Long itCoverageHitsByLineMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'it_coverage_line_hits_data'").get(simpleLongReader); + Long itConditionsByLineMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'it_conditions_by_line'").get(simpleLongReader); + Long itCoveredConditionsByLineMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'it_covered_conditions_by_line'").get(simpleLongReader); + Long overallCoverageHitsByLineMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'overall_coverage_line_hits_data'").get(simpleLongReader); + Long overallConditionsByLineMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'overall_conditions_by_line'").get(simpleLongReader); + Long overallCoveredConditionsByLineMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'overall_covered_conditions_by_line'").get(simpleLongReader); + Long duplicationDataMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'duplications_data'").get(simpleLongReader); + + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select(SELECT_FILES_AND_MEASURES_SQL) + .setBoolean(1, true) + .setLong(2, zeroIfNull(revisionMetricId)) + .setLong(3, zeroIfNull(authorMetricId)) + .setLong(4, zeroIfNull(datesMetricId)) + .setLong(5, zeroIfNull(utCoverageHitsByLineMetricId)) + .setLong(6, zeroIfNull(utConditionsByLineMetricId)) + .setLong(7, zeroIfNull(utCoveredConditionsByLineMetricId)) + .setLong(8, zeroIfNull(itCoverageHitsByLineMetricId)) + .setLong(9, zeroIfNull(itConditionsByLineMetricId)) + .setLong(10, zeroIfNull(itCoveredConditionsByLineMetricId)) + .setLong(11, zeroIfNull(overallCoverageHitsByLineMetricId)) + .setLong(12, zeroIfNull(overallConditionsByLineMetricId)) + .setLong(13, zeroIfNull(overallCoveredConditionsByLineMetricId)) + .setLong(14, zeroIfNull(duplicationDataMetricId)) + .setBoolean(15, true); + + massUpdate.update("INSERT INTO file_sources" + + "(project_uuid, file_uuid, created_at, updated_at, data, line_hashes, data_hash)" + + "VALUES " + + "(?, ?, ?, ?, ?, ?, ?)"); + massUpdate.rowPluralName("files"); + + massUpdate.execute(new FileSourceBuilder(system)); + } + + private static long zeroIfNull(@Nullable Long value) { + return value == null ? 0L : value.longValue(); + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v50/FeedIssueLongDates.java b/sonar-db/src/main/java/org/sonar/db/version/v50/FeedIssueLongDates.java new file mode 100644 index 00000000000..c9fd8cfbebe --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v50/FeedIssueLongDates.java @@ -0,0 +1,71 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v50; + +import java.sql.SQLException; +import java.util.Date; +import org.sonar.api.utils.System2; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +public class FeedIssueLongDates extends BaseDataChange { + + private final System2 system; + + public FeedIssueLongDates(Database db, System2 system) { + super(db); + this.system = system; + } + + @Override + public void execute(Context context) throws SQLException { + final long now = system.now(); + + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("SELECT i.id, i.created_at, i.updated_at FROM issues i WHERE created_at_ms IS NULL"); + massUpdate.update("UPDATE issues SET created_at_ms=?, updated_at_ms=? WHERE id=?"); + massUpdate.rowPluralName("issues"); + massUpdate.execute(new MassUpdate.Handler() { + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + Long id = row.getNullableLong(1); + Date createdAt = row.getNullableDate(2); + Date updatedAt = row.getNullableDate(3); + + if (createdAt == null) { + update.setLong(1, now); + } else { + update.setLong(1, Math.min(now, createdAt.getTime())); + } + if (updatedAt == null) { + update.setLong(2, now); + } else { + update.setLong(2, Math.min(now, updatedAt.getTime())); + } + update.setLong(3, id); + return true; + } + }); + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v50/FeedSnapshotSourcesUpdatedAt.java b/sonar-db/src/main/java/org/sonar/db/version/v50/FeedSnapshotSourcesUpdatedAt.java new file mode 100644 index 00000000000..cc1e6859b5f --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v50/FeedSnapshotSourcesUpdatedAt.java @@ -0,0 +1,60 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v50; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +/** + * Used in the Active Record Migration 712 + * + * @since 5.0 + */ +public class FeedSnapshotSourcesUpdatedAt extends BaseDataChange { + + public FeedSnapshotSourcesUpdatedAt(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("SELECT ss.id, s.build_date " + + "FROM snapshot_sources ss " + + "INNER JOIN snapshots s ON s.id = ss.snapshot_id " + + "WHERE ss.updated_at IS NULL"); + massUpdate.update("UPDATE snapshot_sources " + + "SET updated_at=? " + + "WHERE id=?"); + massUpdate.execute(new MassUpdate.Handler() { + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + update.setDate(1, row.getNullableDate(2)); + update.setLong(2, row.getNullableLong(1)); + return true; + } + }); + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v50/FileSourceDto.java b/sonar-db/src/main/java/org/sonar/db/version/v50/FileSourceDto.java new file mode 100644 index 00000000000..ca1683ffa2d --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v50/FileSourceDto.java @@ -0,0 +1,212 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v50; + +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableList; +import java.io.ByteArrayOutputStream; +import java.io.OutputStreamWriter; +import java.io.StringReader; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang.StringUtils; +import org.codehaus.stax2.XMLInputFactory2; +import org.codehaus.staxmate.SMInputFactory; +import org.codehaus.staxmate.in.SMHierarchicCursor; +import org.codehaus.staxmate.in.SMInputCursor; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.utils.KeyValueFormat; +import org.sonar.api.utils.text.CsvWriter; + +import static java.nio.charset.StandardCharsets.UTF_8; + +class FileSourceDto { + + private static final String SPACE_CHARS = "\t\n\r "; + + private Iterator<String> sourceSplitter; + + private final Map<Integer, String> revisions; + private final Map<Integer, String> authors; + private final Map<Integer, String> dates; + private final Map<Integer, String> utHits; + private final Map<Integer, String> utConditions; + private final Map<Integer, String> utCoveredConditions; + private final Map<Integer, String> itHits; + private final Map<Integer, String> itConditions; + private final Map<Integer, String> itCoveredConditions; + private final Map<Integer, String> overallHits; + private final Map<Integer, String> overallConditions; + private final Map<Integer, String> overallCoveredConditions; + private final List<List<Block>> duplicationGroups; + + FileSourceDto(String source, String revisions, String authors, String dates, + String utHits, String utConditions, String utCoveredConditions, + String itHits, String itConditions, String itCoveredConditions, + String overallHits, String overallConditions, String overallCoveredConditions, String duplicationData) { + sourceSplitter = Splitter.onPattern("\r?\n|\r").split(source).iterator(); + this.revisions = KeyValueFormat.parseIntString(revisions); + this.authors = KeyValueFormat.parseIntString(authors); + this.dates = KeyValueFormat.parseIntString(dates); + this.utHits = KeyValueFormat.parseIntString(utHits); + this.utConditions = KeyValueFormat.parseIntString(utConditions); + this.utCoveredConditions = KeyValueFormat.parseIntString(utCoveredConditions); + this.itHits = KeyValueFormat.parseIntString(itHits); + this.itConditions = KeyValueFormat.parseIntString(itConditions); + this.itCoveredConditions = KeyValueFormat.parseIntString(itCoveredConditions); + this.overallHits = KeyValueFormat.parseIntString(overallHits); + this.overallConditions = KeyValueFormat.parseIntString(overallConditions); + this.overallCoveredConditions = KeyValueFormat.parseIntString(overallCoveredConditions); + this.duplicationGroups = StringUtils.isNotBlank(duplicationData) ? parseDuplicationData(duplicationData) : Collections.<List<Block>>emptyList(); + } + + String[] getSourceData() { + String highlighting = ""; + String symbolRefs = ""; + Map<Integer, String> duplicationsPerLine = computeDuplicationsPerLine(duplicationGroups); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + int line = 0; + String sourceLine = null; + CsvWriter csv = CsvWriter.of(new OutputStreamWriter(output, UTF_8)); + StringBuilder lineHashes = new StringBuilder(); + while (sourceSplitter.hasNext()) { + line++; + sourceLine = sourceSplitter.next(); + lineHashes.append(lineChecksum(sourceLine)).append("\n"); + csv.values(revisions.get(line), authors.get(line), dates.get(line), + utHits.get(line), utConditions.get(line), utCoveredConditions.get(line), + itHits.get(line), itConditions.get(line), itCoveredConditions.get(line), + overallHits.get(line), overallConditions.get(line), overallCoveredConditions.get(line), + highlighting, symbolRefs, duplicationsPerLine.get(line), sourceLine); + } + csv.close(); + return new String[] {new String(output.toByteArray(), UTF_8), lineHashes.toString()}; + } + + public static String lineChecksum(String line) { + String reducedLine = StringUtils.replaceChars(line, SPACE_CHARS, ""); + if (reducedLine.isEmpty()) { + return ""; + } + return DigestUtils.md5Hex(reducedLine); + } + + private Map<Integer, String> computeDuplicationsPerLine(List<List<Block>> duplicationGroups) { + Map<Integer, String> result = new HashMap<>(); + if (duplicationGroups.isEmpty()) { + return result; + } + Map<Integer, StringBuilder> dupPerLine = new HashMap<>(); + int blockId = 1; + for (List<Block> group : duplicationGroups) { + Block originBlock = group.get(0); + addBlock(blockId, originBlock, dupPerLine); + blockId++; + for (int i = 1; i < group.size(); i++) { + Block duplicate = group.get(i); + if (duplicate.resourceKey.equals(originBlock.resourceKey)) { + addBlock(blockId, duplicate, dupPerLine); + blockId++; + } + } + } + for (Map.Entry<Integer, StringBuilder> entry : dupPerLine.entrySet()) { + result.put(entry.getKey(), entry.getValue().toString()); + } + return result; + } + + private void addBlock(int blockId, Block block, Map<Integer, StringBuilder> dupPerLine) { + int currentLine = block.start; + for (int i = 0; i < block.length; i++) { + if (dupPerLine.get(currentLine) == null) { + dupPerLine.put(currentLine, new StringBuilder()); + } + if (dupPerLine.get(currentLine).length() > 0) { + dupPerLine.get(currentLine).append(','); + } + dupPerLine.get(currentLine).append(blockId); + currentLine++; + } + + } + + /** + * Parses data of {@link CoreMetrics#DUPLICATIONS_DATA}. + */ + private static List<List<Block>> parseDuplicationData(String data) { + ImmutableList.Builder<List<Block>> groups = ImmutableList.builder(); + try { + StringReader reader = new StringReader(data); + SMInputFactory inputFactory = initStax(); + SMHierarchicCursor rootC = inputFactory.rootElementCursor(reader); + // <duplications> + rootC.advance(); + SMInputCursor groupsCursor = rootC.childElementCursor("g"); + while (groupsCursor.getNext() != null) { + // <g> + SMInputCursor blocksCursor = groupsCursor.childElementCursor("b"); + ImmutableList.Builder<Block> group = ImmutableList.builder(); + while (blocksCursor.getNext() != null) { + // <b> + String resourceKey = blocksCursor.getAttrValue("r"); + int firstLine = getAttrIntValue(blocksCursor, "s"); + int numberOfLines = getAttrIntValue(blocksCursor, "l"); + + group.add(new Block(resourceKey, firstLine, numberOfLines)); + } + groups.add(group.build()); + } + } catch (Exception e) { + // SONAR-6174 Ignore any issue while parsing duplication measure. There is nothing user can do and things will get solved after + // next analysis anyway + } + return groups.build(); + } + + private static int getAttrIntValue(SMInputCursor cursor, String attrName) throws XMLStreamException { + return cursor.getAttrIntValue(cursor.findAttrIndex(null, attrName)); + } + + private static SMInputFactory initStax() { + XMLInputFactory xmlFactory = XMLInputFactory2.newInstance(); + return new SMInputFactory(xmlFactory); + } + + private static class Block { + + final String resourceKey; + final int start; + final int length; + + public Block(String resourceKey, int s, int l) { + this.resourceKey = resourceKey; + this.start = s; + this.length = l; + } + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationStep.java b/sonar-db/src/main/java/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationStep.java new file mode 100644 index 00000000000..d088be4f190 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationStep.java @@ -0,0 +1,63 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v50; + +import java.sql.SQLException; +import org.sonar.api.utils.System2; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +/** + * Used in the Active Record Migration 716 + * + * @since 5.0 + */ +public class InsertProjectsAuthorizationUpdatedAtMigrationStep extends BaseDataChange { + + private final System2 system; + + public InsertProjectsAuthorizationUpdatedAtMigrationStep(Database db, System2 system) { + super(db); + this.system = system; + } + + @Override + public void execute(Context context) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("SELECT p.id FROM projects p WHERE p.scope=? AND p.enabled=? and p.authorization_updated_at IS NULL").setString(1, "PRJ").setBoolean(2, true); + massUpdate.update("UPDATE projects SET authorization_updated_at=? WHERE id=?"); + massUpdate.rowPluralName("projects"); + massUpdate.execute(new MigrationHandler()); + } + + private class MigrationHandler implements MassUpdate.Handler { + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + Long id = row.getNullableLong(1); + update.setLong(1, system.now()); + update.setLong(2, id); + return true; + } + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationStep.java b/sonar-db/src/main/java/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationStep.java new file mode 100644 index 00000000000..181d0aeebf3 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationStep.java @@ -0,0 +1,194 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v50; + +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; +import org.apache.ibatis.session.ResultContext; +import org.apache.ibatis.session.ResultHandler; +import org.sonar.api.resources.Scopes; +import org.sonar.api.utils.internal.Uuids; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; +import org.sonar.core.util.ProgressLogger; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.version.MigrationStep; + +import static com.google.common.collect.Lists.newArrayList; +import static com.google.common.collect.Maps.newHashMap; + +/** + * Used in the Active Record Migration 705 + * + * @since 5.0 + */ +public class PopulateProjectsUuidColumnsMigrationStep implements MigrationStep { + + private static final Logger LOG = Loggers.get(PopulateProjectsUuidColumnsMigrationStep.class); + + private final DbClient db; + private final AtomicLong counter = new AtomicLong(0L); + + public PopulateProjectsUuidColumnsMigrationStep(DbClient db) { + this.db = db; + } + + @Override + public void execute() { + ProgressLogger progress = ProgressLogger.create(getClass(), counter); + progress.start(); + + final DbSession readSession = db.openSession(false); + final DbSession writeSession = db.openSession(true); + try { + readSession.select("org.sonar.db.version.v50.Migration50Mapper.selectRootProjects", new ResultHandler() { + @Override + public void handleResult(ResultContext context) { + Component project = (Component) context.getResultObject(); + List<Component> components = readSession.getMapper(Migration50Mapper.class).selectComponentChildrenForProjects(project.getId()); + MigrationContext migrationContext = new MigrationContext(readSession, writeSession, project, components); + migrateEnabledComponents(migrationContext); + migrateDisabledComponents(migrationContext); + } + }); + writeSession.commit(true); + readSession.commit(true); + + migrateComponentsWithoutUuid(readSession, writeSession); + writeSession.commit(true); + + // log the total number of process rows + progress.log(); + } finally { + readSession.close(); + writeSession.close(); + progress.stop(); + } + } + + private void migrateEnabledComponents(MigrationContext migrationContext) { + saveComponent(migrationContext.writeSession, migrationContext.project); + for (Component component : migrationContext.componentsToMigrate) { + migrationContext.updateComponent(component); + if (Strings.isNullOrEmpty(component.getModuleUuidPath())) { + LOG.warn(String.format("Ignoring component id '%s' because the module uuid path could not be created", component.getId())); + } else { + migrationContext.updateComponent(component); + saveComponent(migrationContext.writeSession, component); + } + } + } + + private void migrateDisabledComponents(MigrationContext migrationContext) { + for (Component component : migrationContext.readSession.getMapper(Migration50Mapper.class).selectDisabledDirectComponentChildrenForProjects(migrationContext.project.getId())) { + migrationContext.updateComponent(component); + saveComponent(migrationContext.writeSession, component); + } + for (Component component : migrationContext.readSession.getMapper(Migration50Mapper.class).selectDisabledNoneDirectComponentChildrenForProjects( + migrationContext.project.getId())) { + migrationContext.updateComponent(component); + saveComponent(migrationContext.writeSession, component); + } + } + + private void migrateComponentsWithoutUuid(DbSession readSession, DbSession writeSession) { + for (Component component : readSession.getMapper(Migration50Mapper.class).selectComponentsWithoutUuid()) { + String uuid = Uuids.create(); + component.setUuid(uuid); + component.setProjectUuid(uuid); + saveComponent(writeSession, component); + } + } + + private void saveComponent(DbSession writeSession, Component component) { + writeSession.getMapper(Migration50Mapper.class).updateComponentUuids(component); + counter.getAndIncrement(); + } + + private static class MigrationContext { + private final DbSession readSession; + private final DbSession writeSession; + private final Component project; + private final Map<Long, Component> componentsBySnapshotId = newHashMap(); + private final Map<Long, String> uuidByComponentId = newHashMap(); + private final List<Component> componentsToMigrate = newArrayList(); + + private MigrationContext(DbSession readSession, DbSession writeSession, Component project, List<Component> components) { + this.readSession = readSession; + this.writeSession = writeSession; + this.project = project; + + project.setUuid(getOrCreateUuid(project)); + project.setProjectUuid(project.getUuid()); + + componentsBySnapshotId.put(project.getSnapshotId(), project); + for (Component component : components) { + componentsBySnapshotId.put(component.getSnapshotId(), component); + if (component.getUuid() == null) { + componentsToMigrate.add(component); + } + } + } + + public void updateComponent(Component component) { + component.setUuid(getOrCreateUuid(component)); + component.setProjectUuid(getOrCreateUuid(project)); + + String snapshotPath = component.getSnapshotPath(); + StringBuilder moduleUuidPath = new StringBuilder(); + String lastModuleUuid = null; + if (!Strings.isNullOrEmpty(snapshotPath)) { + for (String s : Splitter.on(".").omitEmptyStrings().split(snapshotPath)) { + Long snapshotId = Long.valueOf(s); + Component currentComponent = componentsBySnapshotId.get(snapshotId); + if (currentComponent != null && currentComponent.getScope().equals(Scopes.PROJECT)) { + lastModuleUuid = getOrCreateUuid(currentComponent); + moduleUuidPath.append(lastModuleUuid).append("."); + } + } + } + + if (moduleUuidPath.length() > 0 && lastModuleUuid != null) { + // Remove last '.' + moduleUuidPath.deleteCharAt(moduleUuidPath.length() - 1); + + component.setModuleUuidPath(moduleUuidPath.toString()); + component.setModuleUuid(lastModuleUuid); + } + } + + private String getOrCreateUuid(Component component) { + String existingUuid = component.getUuid(); + String uuid = existingUuid == null ? uuidByComponentId.get(component.getId()) : existingUuid; + if (uuid == null) { + String newUuid = Uuids.create(); + uuidByComponentId.put(component.getId(), newUuid); + return newUuid; + } + return uuid; + } + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationStep.java b/sonar-db/src/main/java/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationStep.java new file mode 100644 index 00000000000..50b1bd4c445 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationStep.java @@ -0,0 +1,88 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v50; + +import com.google.common.collect.Lists; +import java.sql.SQLException; +import java.util.Date; +import java.util.List; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.utils.System2; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +// TODO could be refactored to benefit from existing code of ReplaceIssueFiltersProjectKeyByUuid +// -> make any change of issue_filters easier +public class RemoveSortFieldFromIssueFiltersMigrationStep extends BaseDataChange { + + private static final char FIELD_SEPARATOR = '|'; + private static final String SORT_KEY = "sort="; + private static final String ASC_KEY = "asc="; + + private final System2 system; + + public RemoveSortFieldFromIssueFiltersMigrationStep(Database db, System2 system) { + super(db); + this.system = system; + } + + @Override + public void execute(Context context) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("select id,data from issue_filters where data like '%" + SORT_KEY + "%' or data like '%" + ASC_KEY + "%'"); + massUpdate.update("update issue_filters set data=?, updated_at=? where id=?"); + massUpdate.rowPluralName("issue filters"); + massUpdate.execute(new FilterHandler(new Date(system.now()))); + } + + private static class FilterHandler implements MassUpdate.Handler { + private final Date now; + + private FilterHandler(Date now) { + this.now = now; + } + + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + String data = row.getNullableString(2); + String[] fields = StringUtils.split(data, FIELD_SEPARATOR); + + boolean found = false; + List<String> fieldsToKeep = Lists.newArrayList(); + for (String field : fields) { + if (field.startsWith(SORT_KEY) || field.startsWith(ASC_KEY)) { + found = true; + } else { + fieldsToKeep.add(field); + } + } + if (found) { + // data without 'sort' field + update.setString(1, StringUtils.join(fieldsToKeep, FIELD_SEPARATOR)); + update.setDate(2, now); + update.setLong(3, row.getNullableLong(1)); + } + return found; + } + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuid.java b/sonar-db/src/main/java/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuid.java new file mode 100644 index 00000000000..16e2ca6a2f3 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuid.java @@ -0,0 +1,122 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v50; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Date; +import javax.annotation.Nullable; +import org.apache.commons.dbutils.DbUtils; +import org.sonar.api.utils.System2; +import org.sonar.db.Database; +import org.sonar.db.DatabaseUtils; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +/** + * Used in the Active Record Migration 710 + * + * @since 5.0 + */ +public class ReplaceIssueFiltersProjectKeyByUuid extends BaseDataChange { + + private final System2 system; + + public ReplaceIssueFiltersProjectKeyByUuid(Database db, System2 system) { + super(db); + this.system = system; + } + + @Override + public void execute(final Context context) throws SQLException { + final Date now = new Date(system.now()); + + Connection connection = null; + PreparedStatement pstmt = null; + try { + connection = openConnection(); + pstmt = connection.prepareStatement("SELECT p.uuid as uuid FROM projects p WHERE p.kee=?"); + + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("SELECT f.id, f.data FROM issue_filters f WHERE f.data like '%componentRoots=%'"); + massUpdate.update("UPDATE issue_filters SET data=?, updated_at=? WHERE id=?"); + final PreparedStatement finalPstmt = pstmt; + massUpdate.execute(new MassUpdate.Handler() { + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + Long id = row.getNullableLong(1); + String data = row.getNullableString(2); + if (data == null) { + return false; + } + update.setString(1, convertData(finalPstmt, data)); + update.setDate(2, now); + update.setLong(3, id); + return true; + } + }); + } finally { + DbUtils.closeQuietly(connection); + DbUtils.closeQuietly(pstmt); + } + } + + private String convertData(PreparedStatement pstmt, String data) throws SQLException { + StringBuilder newFields = new StringBuilder(); + String[] fields = data.split("\\|"); + for (int i = 0; i < fields.length; i++) { + String field = fields[i]; + if (field.contains("componentRoots")) { + String[] componentRootValues = field.split("="); + append(pstmt, newFields, componentRootValues.length == 2 ? componentRootValues[1] : null); + } else { + newFields.append(field); + } + if (i < fields.length - 1) { + newFields.append("|"); + } + } + return newFields.toString(); + } + + private static void append(PreparedStatement pstmt, StringBuilder newFields, @Nullable String projectKey) throws SQLException { + if (projectKey != null) { + pstmt.setString(1, projectKey); + ResultSet rs = null; + try { + rs = pstmt.executeQuery(); + if (rs.next()) { + String projectUuid = DatabaseUtils.getString(rs, "uuid"); + if (projectUuid != null) { + newFields.append("projectUuids=").append(projectUuid); + } + } + } finally { + DbUtils.closeQuietly(rs); + } + } + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v51/AddIssuesColumns.java b/sonar-db/src/main/java/org/sonar/db/version/v51/AddIssuesColumns.java new file mode 100644 index 00000000000..09ffbdb94a8 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v51/AddIssuesColumns.java @@ -0,0 +1,92 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.version.AddColumnsBuilder; +import org.sonar.db.version.DdlChange; + +/** + * Add the following columns to the issues table : + * - issue_creation_date_ms + * - issue_update_date_ms + * - issue_close_date_ms + * - tags + * - component_uuid + * - project_uuid + */ +public class AddIssuesColumns extends DdlChange { + + private final Database db; + + public AddIssuesColumns(Database db) { + super(db); + this.db = db; + } + + @Override + public void execute(DdlChange.Context context) throws SQLException { + context.execute(generateSql()); + } + + private String generateSql() { + return new AddColumnsBuilder(db.getDialect(), "issues") + .addColumn( + new AddColumnsBuilder.ColumnDef() + .setName("issue_creation_date_ms") + .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER) + .setNullable(true) + ) + .addColumn( + new AddColumnsBuilder.ColumnDef() + .setName("issue_update_date_ms") + .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER) + .setNullable(true) + ) + .addColumn( + new AddColumnsBuilder.ColumnDef() + .setName("issue_close_date_ms") + .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER) + .setNullable(true) + ) + .addColumn( + new AddColumnsBuilder.ColumnDef() + .setName("tags") + .setType(AddColumnsBuilder.ColumnDef.Type.STRING) + .setLimit(4000) + .setNullable(true)) + .addColumn( + new AddColumnsBuilder.ColumnDef() + .setName("component_uuid") + .setType(AddColumnsBuilder.ColumnDef.Type.STRING) + .setLimit(50) + .setNullable(true)) + .addColumn( + new AddColumnsBuilder.ColumnDef() + .setName("project_uuid") + .setType(AddColumnsBuilder.ColumnDef.Type.STRING) + .setLimit(50) + .setNullable(true)) + .build(); + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v51/AddNewCharacteristics.java b/sonar-db/src/main/java/org/sonar/db/version/v51/AddNewCharacteristics.java new file mode 100644 index 00000000000..2623dcb75e0 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v51/AddNewCharacteristics.java @@ -0,0 +1,330 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import java.sql.SQLException; +import java.util.Date; +import java.util.List; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import org.sonar.api.utils.MessageException; +import org.sonar.api.utils.System2; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.Select; + +/** + * See http://jira.sonarsource.com/browse/SONAR-6187 + * + * Add a new Characteristic 'Usability' with 2 sub-characteristics 'Accessibility' and 'Ease of Use' + * and add a new sub-characteristic 'Compliance' for all characteristics. + * + * Nothing will be done if there's no characteristics in db, as they're all gonna be created by {@link org.sonar.server.startup.RegisterDebtModel} + * + * Before 4.3 the characteristics table contains requirements, then when selecting characteristics we should not forget to exclude them (with a filter on rule_id IS NULL) + * + */ +public class AddNewCharacteristics extends BaseDataChange { + + private static final Logger LOGGER = Loggers.get(AddNewCharacteristics.class); + + private static final String COMPLIANCE_NAME = "Compliance"; + private static final String COMPLIANCE_KEY_SUFFIX = "_COMPLIANCE"; + + private static final String SECURITY_KEY = "SECURITY"; + private static final String USABILITY_KEY = "USABILITY"; + + private static final String ERROR_SUFFIX = "Please restore your DB backup, start the previous version of SonarQube " + + "and update your SQALE model to fix this issue before trying again to run the migration."; + + private final System2 system; + + public AddNewCharacteristics(Database db, System2 system) { + super(db); + this.system = system; + } + + @Override + public void execute(Context context) throws SQLException { + CharacteristicsContext characteristicsContext = new CharacteristicsContext(context, system); + + // On an empty DB, there are no characteristics, they're all gonna be created after in RegisterDebtModel + if (!characteristicsContext.characteristics().isEmpty()) { + int usabilityOder = moveCharacteristicsDownToBeAbleToInsertUsability(characteristicsContext); + createOrUpdateUsabilityCharacteristicAndItsSubCharacteristic(characteristicsContext, usabilityOder); + + createSubCharacteristic(characteristicsContext, "REUSABILITY" + COMPLIANCE_KEY_SUFFIX, "Reusability " + COMPLIANCE_NAME, "REUSABILITY"); + createSubCharacteristic(characteristicsContext, "PORTABILITY" + COMPLIANCE_KEY_SUFFIX, "Portability " + COMPLIANCE_NAME, "PORTABILITY"); + createSubCharacteristic(characteristicsContext, "MAINTAINABILITY" + COMPLIANCE_KEY_SUFFIX, "Maintainability " + COMPLIANCE_NAME, "MAINTAINABILITY"); + createSubCharacteristic(characteristicsContext, SECURITY_KEY + COMPLIANCE_KEY_SUFFIX, "Security " + COMPLIANCE_NAME, SECURITY_KEY); + createSubCharacteristic(characteristicsContext, "EFFICIENCY" + COMPLIANCE_KEY_SUFFIX, "Efficiency " + COMPLIANCE_NAME, "EFFICIENCY"); + createSubCharacteristic(characteristicsContext, "CHANGEABILITY" + COMPLIANCE_KEY_SUFFIX, "Changeability " + COMPLIANCE_NAME, "CHANGEABILITY"); + createSubCharacteristic(characteristicsContext, "RELIABILITY" + COMPLIANCE_KEY_SUFFIX, "Reliability " + COMPLIANCE_NAME, "RELIABILITY"); + createSubCharacteristic(characteristicsContext, "TESTABILITY" + COMPLIANCE_KEY_SUFFIX, "Testability " + COMPLIANCE_NAME, "TESTABILITY"); + } + } + + /** + * If the characteristic 'Security' exists, the new characteristic 'Usability' should be inserted just below it, + * so every existing characteristics below Security should move down. + * + * If the characteristic 'Security' does not exists, the new characteristic 'Usability' should be the first one, + * so every existing characteristics should move down. + * + * If the characteristic 'Usability' is already at the right place, nothing will be done. + */ + private static int moveCharacteristicsDownToBeAbleToInsertUsability(CharacteristicsContext characteristicsContext) throws SQLException { + Characteristic security = characteristicsContext.findCharacteristicByKey(SECURITY_KEY); + Characteristic usability = characteristicsContext.findCharacteristicByKey(USABILITY_KEY); + + int usabilityOder = 1; + int indexToStart = 0; + if (security != null) { + indexToStart = characteristicsContext.characteristics().indexOf(security) + 1; + usabilityOder = security.getOrder() + 1; + } + + if (usability == null || usability.getOrder() != usabilityOder) { + // Move root characteristics one step lower + for (int i = indexToStart; i < characteristicsContext.characteristics().size(); i++) { + Characteristic characteristic = characteristicsContext.characteristics().get(i); + if (characteristic.getParentId() == null) { + characteristicsContext.updateCharacteristicOrder(characteristic.getKey(), characteristic.getOrder() + 1); + } + } + } + return usabilityOder; + } + + private void createOrUpdateUsabilityCharacteristicAndItsSubCharacteristic(CharacteristicsContext characteristicsContext, int newUsabilityOrder) + throws SQLException { + String usabilityKey = USABILITY_KEY; + Characteristic usability = characteristicsContext.findCharacteristicByKey(usabilityKey); + if (usability != null) { + if (usability.getOrder() != newUsabilityOrder) { + usability.setOrder(newUsabilityOrder); + characteristicsContext.updateCharacteristicOrder(usability.getKey(), usability.getOrder()); + } + } else { + usability = new Characteristic().setKey(usabilityKey).setName("Usability").setOrder(newUsabilityOrder); + characteristicsContext.insertCharacteristic(usability); + } + + createSubCharacteristic(characteristicsContext, "USABILITY_ACCESSIBILITY", "Accessibility", usabilityKey); + createSubCharacteristic(characteristicsContext, "USABILITY_EASE_OF_USE", "Ease of Use", usabilityKey); + createSubCharacteristic(characteristicsContext, USABILITY_KEY + COMPLIANCE_KEY_SUFFIX, "Usability " + COMPLIANCE_NAME, usabilityKey); + } + + private void createSubCharacteristic(CharacteristicsContext characteristicsContext, + String subCharacteristicKey, String subCharacteristicName, String parentKey) throws SQLException { + Characteristic parent = characteristicsContext.findCharacteristicByKey(parentKey); + if (parent != null) { + Characteristic subCharacteristic = characteristicsContext.findSubCharacteristicByKey(subCharacteristicKey, parent); + if (subCharacteristic == null) { + characteristicsContext.insertCharacteristic(new Characteristic().setKey(subCharacteristicKey).setName(subCharacteristicName).setParentId(parent.getId())); + } + } + // If the characteristic parent does not exits, the sub-characteristic is not added + } + + private static class Characteristic { + private Integer id; + private String key; + private String name; + private Integer order; + private Integer parentId; + + public Integer getId() { + return id; + } + + public Characteristic setId(Integer id) { + this.id = id; + return this; + } + + public String getKey() { + return key; + } + + public Characteristic setKey(String key) { + this.key = key; + return this; + } + + public String getName() { + return name; + } + + public Characteristic setName(String name) { + this.name = name; + return this; + } + + /** + * On a characteristic, the order can never be null + */ + public Integer getOrder() { + return parentId == null && order != null ? order : null; + } + + public Characteristic setOrder(@Nullable Integer order) { + this.order = order; + return this; + } + + @CheckForNull + public Integer getParentId() { + return parentId; + } + + public Characteristic setParentId(@Nullable Integer parentId) { + this.parentId = parentId; + return this; + } + } + + private static class CharacteristicsContext { + private final System2 system; + Context context; + Date now; + List<Characteristic> characteristics; + + public CharacteristicsContext(Context context, System2 system) throws SQLException { + this.context = context; + this.system = system; + init(); + } + + private void init() throws SQLException { + now = new Date(system.now()); + characteristics = selectEnabledCharacteristics(); + } + + public List<Characteristic> characteristics() { + return characteristics; + } + + @CheckForNull + public Characteristic findCharacteristicByKey(final String key) { + Characteristic characteristic = Iterables.find(characteristics, new CharacteristicKey(key), null); + if (characteristic != null && characteristic.getParentId() != null) { + throw MessageException.of(String.format("'%s' must be a characteristic. " + ERROR_SUFFIX, characteristic.getName())); + } + return characteristic; + } + + @CheckForNull + public Characteristic findSubCharacteristicByKey(final String key, Characteristic parent) { + Characteristic characteristic = Iterables.find(characteristics, new CharacteristicKey(key), null); + if (characteristic != null) { + Integer parentId = characteristic.getParentId(); + if (parentId == null) { + throw MessageException.of(String.format("'%s' must be a sub-characteristic. " + ERROR_SUFFIX, characteristic.getName())); + } else if (!parentId.equals(parent.getId())) { + throw MessageException.of(String.format("'%s' must be defined under '%s'. " + ERROR_SUFFIX, characteristic.getName(), parent.getName())); + } + } + return characteristic; + } + + private List<Characteristic> selectEnabledCharacteristics() throws SQLException { + return context.prepareSelect( + // Exclude requirements (to not fail when coming from a version older than 4.3) + "SELECT c.id, c.kee, c.name, c.characteristic_order, c.parent_id FROM characteristics c WHERE c.enabled=? AND c.rule_id IS NULL ORDER BY c.characteristic_order") + .setBoolean(1, true) + .list(new CharacteristicReader()); + } + + private int selectCharacteristicId(String key) throws SQLException { + Long id = context.prepareSelect( + "SELECT c.id FROM characteristics c WHERE c.kee = ? AND c.enabled=?") + .setString(1, key) + .setBoolean(2, true) + .get(Select.LONG_READER); + if (id != null) { + return id.intValue(); + } else { + throw new IllegalStateException(String.format("Characteristic '%s' could not be inserted", key)); + } + } + + public void insertCharacteristic(Characteristic characteristic) throws SQLException { + if (characteristic.getParentId() == null) { + LOGGER.info("Insert new characteristic '{}'", characteristic.getKey()); + } else { + LOGGER.info("Insert new sub characteristic '{}'", characteristic.getKey()); + } + + context.prepareUpsert("INSERT INTO characteristics (kee, name, parent_id, characteristic_order, enabled, created_at) VALUES (?, ?, ?, ?, ?, ?)") + .setString(1, characteristic.getKey()) + .setString(2, characteristic.getName()) + .setInt(3, characteristic.getParentId()) + .setInt(4, characteristic.getOrder()) + .setBoolean(5, true) + .setDate(6, now) + .execute() + .commit(); + characteristic.setId(selectCharacteristicId(characteristic.getKey())); + + characteristics.add(characteristic); + } + + public void updateCharacteristicOrder(String key, Integer order) throws SQLException { + LOGGER.info("Update characteristic '{}' order to {}", key, order); + + context.prepareUpsert("UPDATE characteristics SET characteristic_order=?, updated_at=? WHERE kee=?") + .setInt(1, order) + .setDate(2, now) + .setString(3, key) + .execute() + .commit(); + } + + private static class CharacteristicReader implements Select.RowReader<Characteristic> { + @Override + public Characteristic read(Select.Row row) throws SQLException { + return new Characteristic() + .setId(row.getInt(1)) + .setKey(row.getString(2)) + .setName(row.getString(3)) + .setOrder(row.getNullableInt(4)) + .setParentId(row.getNullableInt(5)); + } + } + } + + private static class CharacteristicKey implements Predicate<Characteristic> { + private final String key; + + public CharacteristicKey(String key) { + this.key = key; + } + + @Override + public boolean apply(@Nullable Characteristic input) { + return input != null && input.key.equals(key); + } + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsers.java b/sonar-db/src/main/java/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsers.java new file mode 100644 index 00000000000..0ae65deb79f --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsers.java @@ -0,0 +1,172 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import com.google.common.base.Joiner; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import java.sql.SQLException; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.atomic.AtomicLong; +import javax.annotation.CheckForNull; +import org.sonar.api.utils.System2; +import org.sonar.core.util.ProgressLogger; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.Select; +import org.sonar.db.version.Upsert; +import org.sonar.db.version.UpsertImpl; + +import static com.google.common.collect.Lists.newArrayList; + +public class CopyScmAccountsFromAuthorsToUsers extends BaseDataChange { + + private static final char SCM_ACCOUNTS_SEPARATOR = '\n'; + + private final System2 system; + private final AtomicLong counter = new AtomicLong(0L); + + public CopyScmAccountsFromAuthorsToUsers(Database db, System2 system) { + super(db); + this.system = system; + } + + @Override + public void execute(final Context context) throws SQLException { + ProgressLogger progress = ProgressLogger.create(getClass(), counter); + progress.start(); + final Long now = system.now(); + + try { + final Multimap<Long, String> authorsByPersonId = ArrayListMultimap.create(); + context.prepareSelect("SELECT a.person_id, a.login FROM authors a," + + " (SELECT person_id, COUNT(*) AS nb FROM authors GROUP BY person_id HAVING COUNT(*) > 1) group_by_person" + + " WHERE a.person_id = group_by_person.person_id " + ).scroll(new AuthorsByPersonIdHandler(authorsByPersonId)); + + Upsert update = context.prepareUpsert("UPDATE users SET scm_accounts = ?, updated_at = ? WHERE id = ?"); + for (Long personId : authorsByPersonId.keySet()) { + List<String> authors = newArrayList(authorsByPersonId.get(personId)); + List<User> users = selectUsersFromLoginOrEmail(context, authors); + if (users.size() == 1) { + User user = users.get(0); + if (authors.contains(user.login)) { + authors.remove(user.login); + } + if (authors.contains(user.email)) { + authors.remove(user.email); + } + if (!authors.isEmpty()) { + update + .setString(1, encodeScmAccounts(authors)) + .setLong(2, now) + .setLong(3, user.id) + .addBatch(); + counter.getAndIncrement(); + } + } + } + if (((UpsertImpl) update).getBatchCount() > 0L) { + update.execute().commit(); + } + update.close(); + + progress.log(); + } finally { + progress.stop(); + } + } + + private List<User> selectUsersFromLoginOrEmail(Context context, Collection<String> authors) throws SQLException { + final List<User> users = newArrayList(); + StringBuilder sql = new StringBuilder("SELECT u.id, u.login, u.email, u.scm_accounts FROM users u WHERE u.active=? AND ("); + for (int i = 0; i < authors.size(); i++) { + if (i < authors.size() - 1) { + sql.append("u.login=? OR u.email=? OR "); + } else { + sql.append("u.login=? OR u.email=?)"); + } + } + Select select = context.prepareSelect(sql.toString()); + select.setBoolean(1, true); + int currentIndex = 1; + for (String author : authors) { + currentIndex++; + select.setString(currentIndex, author); + currentIndex++; + select.setString(currentIndex, author); + } + + select.scroll(new UsersHandler(users)); + return users; + } + + @CheckForNull + private static String encodeScmAccounts(List<String> scmAccounts) { + if (scmAccounts.isEmpty()) { + return null; + } + return SCM_ACCOUNTS_SEPARATOR + Joiner.on(SCM_ACCOUNTS_SEPARATOR).join(scmAccounts) + SCM_ACCOUNTS_SEPARATOR; + } + + private static class User { + Long id; + String login; + String email; + String scmAccounts; + + User(Long id, String login, String email, String scmAccounts) { + this.id = id; + this.login = login; + this.email = email; + this.scmAccounts = scmAccounts; + } + } + + private static class AuthorsByPersonIdHandler implements Select.RowHandler { + + private final Multimap<Long, String> authorsByPersonId; + + private AuthorsByPersonIdHandler(Multimap<Long, String> authorsByPersonId) { + this.authorsByPersonId = authorsByPersonId; + } + + @Override + public void handle(Select.Row row) throws SQLException { + authorsByPersonId.put(row.getNullableLong(1), row.getNullableString(2)); + } + } + + private static class UsersHandler implements Select.RowHandler { + + private final List<User> users; + + private UsersHandler(List<User> users) { + this.users = users; + } + + @Override + public void handle(Select.Row row) throws SQLException { + users.add(new User(row.getNullableLong(1), row.getNullableString(2), row.getNullableString(3), row.getNullableString(4))); + } + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v51/DropIssuesColumns.java b/sonar-db/src/main/java/org/sonar/db/version/v51/DropIssuesColumns.java new file mode 100644 index 00000000000..a8a0557e6a8 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v51/DropIssuesColumns.java @@ -0,0 +1,58 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import com.google.common.annotations.VisibleForTesting; +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.version.DdlChange; +import org.sonar.db.version.DropColumnsBuilder; + +/** + * Drop the following columns from the issues table : + * - issue_creation_date + * - issue_update_date + * - issue_close_date + * - component_id + * - root_component_id + */ +public class DropIssuesColumns extends DdlChange { + + private final Database db; + + public DropIssuesColumns(Database db) { + super(db); + this.db = db; + } + + @Override + public void execute(Context context) throws SQLException { + context.execute(generateSql()); + } + + @VisibleForTesting + String generateSql() { + return new DropColumnsBuilder(db.getDialect(), "issues", + "issue_creation_date", "issue_update_date", "issue_close_date", "component_id", "root_component_id") + .build(); + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v51/FeedAnalysisReportsLongDates.java b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedAnalysisReportsLongDates.java new file mode 100644 index 00000000000..42434d8d727 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedAnalysisReportsLongDates.java @@ -0,0 +1,68 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import java.sql.SQLException; +import java.util.Date; +import org.sonar.api.utils.System2; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +public class FeedAnalysisReportsLongDates extends BaseDataChange { + + private final System2 system; + + public FeedAnalysisReportsLongDates(Database db, System2 system) { + super(db); + this.system = system; + } + + @Override + public void execute(Context context) throws SQLException { + final long now = system.now(); + + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("SELECT a.created_at, a.updated_at, a.started_at, a.finished_at, a.id FROM analysis_reports a WHERE created_at_ms IS NULL"); + massUpdate.update("UPDATE analysis_reports SET created_at_ms=?, updated_at_ms=?, started_at_ms=?, finished_at_ms=? WHERE id=?"); + massUpdate.rowPluralName("analysis_reports"); + massUpdate.execute(new MassUpdate.Handler() { + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + Date createdAt = row.getNullableDate(1); + Date updatedAt = row.getNullableDate(2); + Date startedAt = row.getNullableDate(3); + Date finishedAt = row.getNullableDate(4); + Long id = row.getNullableLong(5); + + update.setLong(1, createdAt == null ? now : Math.min(now, createdAt.getTime())); + update.setLong(2, updatedAt == null ? now : Math.min(now, updatedAt.getTime())); + update.setLong(3, startedAt == null ? null : startedAt.getTime()); + update.setLong(4, finishedAt == null ? null : finishedAt.getTime()); + update.setLong(5, id); + return true; + } + }); + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v51/FeedEventsLongDates.java b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedEventsLongDates.java new file mode 100644 index 00000000000..151fa7c9cff --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedEventsLongDates.java @@ -0,0 +1,75 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import java.sql.SQLException; +import java.util.Date; +import org.sonar.api.utils.System2; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +public class FeedEventsLongDates extends BaseDataChange { + + private final System2 system2; + + public FeedEventsLongDates(Database db, System2 system2) { + super(db); + this.system2 = system2; + } + + @Override + public void execute(Context context) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate + .select("SELECT e.event_date, e.created_at, e.id FROM events e WHERE event_date_ms IS NULL"); + massUpdate + .update("UPDATE events SET event_date_ms=?, created_at_ms=? WHERE id=?"); + massUpdate.rowPluralName("events"); + massUpdate.execute(new EventDateHandler(system2.now())); + } + + private static class EventDateHandler implements MassUpdate.Handler { + + private final long now; + + public EventDateHandler(long now) { + this.now = now; + } + + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + Date eventDate = row.getNullableDate(1); + long eventTime = eventDate == null ? now : Math.min(now, eventDate.getTime()); + update.setLong(1, eventTime); + Date createdAt = row.getNullableDate(2); + update.setLong(2, createdAt == null ? eventTime : Math.min(now, createdAt.getTime())); + + Long id = row.getNullableLong(3); + update.setLong(3, id); + + return true; + } + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v51/FeedFileSourcesBinaryData.java b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedFileSourcesBinaryData.java new file mode 100644 index 00000000000..7e3d5e5ef74 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedFileSourcesBinaryData.java @@ -0,0 +1,163 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import com.google.common.base.Function; +import com.google.common.base.Splitter; +import com.google.common.collect.Iterables; +import java.sql.SQLException; +import java.util.Iterator; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVParser; +import org.apache.commons.csv.CSVRecord; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.utils.DateUtils; +import org.sonar.db.Database; +import org.sonar.db.source.FileSourceDto; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; +import org.sonar.server.source.db.FileSourceDb; + +public class FeedFileSourcesBinaryData extends BaseDataChange { + + public FeedFileSourcesBinaryData(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + MassUpdate update = context.prepareMassUpdate().rowPluralName("issues"); + update.select("SELECT id,data FROM file_sources WHERE binary_data is null"); + update.update("UPDATE file_sources SET binary_data=? WHERE id=?"); + update.execute(new MassUpdate.Handler() { + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + Long fileSourceId = row.getNullableLong(1); + update.setBytes(1, toBinary(fileSourceId, row.getNullableString(2))); + update.setLong(2, fileSourceId); + return true; + } + }); + } + + private byte[] toBinary(Long fileSourceId, @Nullable String data) { + FileSourceDb.Data.Builder dataBuilder = FileSourceDb.Data.newBuilder(); + CSVParser parser = null; + try { + if (data != null) { + parser = CSVParser.parse(data, CSVFormat.DEFAULT); + Iterator<CSVRecord> rows = parser.iterator(); + int line = 1; + while (rows.hasNext()) { + CSVRecord row = rows.next(); + if (row.size() == 16) { + + FileSourceDb.Line.Builder lineBuilder = dataBuilder.addLinesBuilder(); + lineBuilder.setLine(line); + String s = row.get(0); + if (StringUtils.isNotEmpty(s)) { + lineBuilder.setScmRevision(s); + } + s = row.get(1); + if (StringUtils.isNotEmpty(s)) { + lineBuilder.setScmAuthor(s); + } + s = row.get(2); + if (StringUtils.isNotEmpty(s)) { + lineBuilder.setScmDate(DateUtils.parseDateTimeQuietly(s).getTime()); + } + s = row.get(3); + if (StringUtils.isNotEmpty(s)) { + lineBuilder.setUtLineHits(Integer.parseInt(s)); + } + s = row.get(4); + if (StringUtils.isNotEmpty(s)) { + lineBuilder.setUtConditions(Integer.parseInt(s)); + } + s = row.get(5); + if (StringUtils.isNotEmpty(s)) { + lineBuilder.setUtCoveredConditions(Integer.parseInt(s)); + } + s = row.get(6); + if (StringUtils.isNotEmpty(s)) { + lineBuilder.setItLineHits(Integer.parseInt(s)); + } + s = row.get(7); + if (StringUtils.isNotEmpty(s)) { + lineBuilder.setItConditions(Integer.parseInt(s)); + } + s = row.get(8); + if (StringUtils.isNotEmpty(s)) { + lineBuilder.setItCoveredConditions(Integer.parseInt(s)); + } + s = row.get(9); + if (StringUtils.isNotEmpty(s)) { + lineBuilder.setOverallLineHits(Integer.parseInt(s)); + } + s = row.get(10); + if (StringUtils.isNotEmpty(s)) { + lineBuilder.setOverallConditions(Integer.parseInt(s)); + } + s = row.get(11); + if (StringUtils.isNotEmpty(s)) { + lineBuilder.setOverallCoveredConditions(Integer.parseInt(s)); + } + s = row.get(12); + if (StringUtils.isNotEmpty(s)) { + lineBuilder.setHighlighting(s); + } + s = row.get(13); + if (StringUtils.isNotEmpty(s)) { + lineBuilder.setSymbols(s); + } + s = row.get(14); + if (StringUtils.isNotEmpty(s)) { + lineBuilder.addAllDuplication(splitIntegers(s)); + } + s = row.get(15); + if (s != null) { + lineBuilder.setSource(s); + } + } + line++; + } + } + return FileSourceDto.encodeSourceData(dataBuilder.build()); + } catch (Exception e) { + throw new IllegalStateException("Invalid FILE_SOURCES.DATA on row with ID " + fileSourceId + ": " + data, e); + } finally { + IOUtils.closeQuietly(parser); + } + } + + private static Iterable<Integer> splitIntegers(String s) { + return Iterables.transform(Splitter.on(',').omitEmptyStrings().trimResults().split(s), new Function<String, Integer>() { + @Override + public Integer apply(@Nonnull String input) { + return Integer.parseInt(input); + } + }); + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v51/FeedIssueChangesLongDates.java b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedIssueChangesLongDates.java new file mode 100644 index 00000000000..78c6a81b334 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedIssueChangesLongDates.java @@ -0,0 +1,66 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import java.sql.SQLException; +import java.util.Date; +import org.sonar.api.utils.System2; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +public class FeedIssueChangesLongDates extends BaseDataChange { + + private final System2 system; + + public FeedIssueChangesLongDates(Database db, System2 system) { + super(db); + this.system = system; + } + + @Override + public void execute(Context context) throws SQLException { + final long now = system.now(); + + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("SELECT i.created_at, i.updated_at, i.issue_change_creation_date, i.id FROM issue_changes i WHERE created_at_ms IS NULL"); + massUpdate.update("UPDATE issue_changes SET created_at_ms=?, updated_at_ms=?, issue_change_creation_date_ms=? WHERE id=?"); + massUpdate.rowPluralName("issue_changes"); + massUpdate.execute(new MassUpdate.Handler() { + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + Date createdAt = row.getNullableDate(1); + Date updatedAt = row.getNullableDate(2); + Date functionalCreatedAt = row.getNullableDate(3); + Long id = row.getNullableLong(4); + + update.setLong(1, createdAt == null ? now : Math.min(now, createdAt.getTime())); + update.setLong(2, updatedAt == null ? now : Math.min(now, updatedAt.getTime())); + update.setLong(3, functionalCreatedAt == null ? null : functionalCreatedAt.getTime()); + update.setLong(4, id); + return true; + } + }); + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v51/FeedIssueComponentUuids.java b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedIssueComponentUuids.java new file mode 100644 index 00000000000..0bfe58afd52 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedIssueComponentUuids.java @@ -0,0 +1,59 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.MassUpdate.Handler; +import org.sonar.db.version.Select.Row; +import org.sonar.db.version.SqlStatement; + +public class FeedIssueComponentUuids extends BaseDataChange { + + public FeedIssueComponentUuids(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + MassUpdate update = context.prepareMassUpdate().rowPluralName("issues"); + update.select( + "SELECT c.uuid, c.project_uuid, i.id " + + "FROM issues i " + + "INNER JOIN projects c ON i.component_id=c.id " + + "WHERE i.component_uuid is null"); + update.update("UPDATE issues SET component_uuid=?, project_uuid=? WHERE id=?"); + update.execute(new SqlRowHandler()); + } + + private static class SqlRowHandler implements Handler { + @Override + public boolean handle(Row row, SqlStatement update) throws SQLException { + update.setString(1, row.getNullableString(1)); + update.setString(2, row.getNullableString(2)); + update.setLong(3, row.getNullableLong(3)); + + return true; + } + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v51/FeedIssueTags.java b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedIssueTags.java new file mode 100644 index 00000000000..f84dd6b3688 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedIssueTags.java @@ -0,0 +1,84 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import com.google.common.base.Joiner; +import com.google.common.collect.Maps; +import java.sql.SQLException; +import java.util.Map; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.utils.System2; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.MassUpdate.Handler; +import org.sonar.db.version.Select.Row; +import org.sonar.db.version.Select.RowHandler; +import org.sonar.db.version.SqlStatement; + +/** + * SONAR-5897 + */ +public class FeedIssueTags extends BaseDataChange { + + private static final Joiner TAG_JOINER = Joiner.on(',').skipNulls(); + + private final long now; + + public FeedIssueTags(Database db, System2 system) { + super(db); + this.now = system.now(); + } + + @Override + public void execute(Context context) throws SQLException { + + final Map<Integer, String> tagsByRuleId = Maps.newHashMap(); + context.prepareSelect("SELECT id, system_tags, tags FROM rules").scroll(new RowHandler() { + @Override + public void handle(Row row) throws SQLException { + Integer id = row.getNullableInt(1); + tagsByRuleId.put(id, StringUtils.trimToNull(TAG_JOINER.join( + StringUtils.trimToNull(row.getNullableString(2)), + StringUtils.trimToNull(row.getNullableString(3))))); + } + }); + + MassUpdate update = context.prepareMassUpdate().rowPluralName("issues"); + update.select("SELECT id, rule_id FROM issues WHERE tags IS NULL"); + update.update("UPDATE issues SET tags = ?, updated_at = ? WHERE id = ?"); + update.execute(new Handler() { + @Override + public boolean handle(Row row, SqlStatement update) throws SQLException { + Long id = row.getNullableLong(1); + Integer ruleId = row.getNullableInt(2); + boolean updated = false; + if (tagsByRuleId.get(ruleId) != null) { + updated = true; + update.setString(1, tagsByRuleId.get(ruleId)); + update.setLong(2, now); + update.setLong(3, id); + } + return updated; + } + }); + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v51/FeedIssuesLongDates.java b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedIssuesLongDates.java new file mode 100644 index 00000000000..66ba13b9248 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedIssuesLongDates.java @@ -0,0 +1,66 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import java.sql.SQLException; +import java.util.Date; +import org.sonar.api.utils.System2; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +public class FeedIssuesLongDates extends BaseDataChange { + + private final System2 system2; + + public FeedIssuesLongDates(Database db, System2 system2) { + super(db); + this.system2 = system2; + } + + @Override + public void execute(Context context) throws SQLException { + final long now = system2.now(); + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate + .select("SELECT i.issue_creation_date, i.issue_update_date, i.issue_close_date, i.id FROM issues i WHERE issue_creation_date_ms IS NULL"); + massUpdate + .update("UPDATE issues SET issue_creation_date_ms=?, issue_update_date_ms=?, issue_close_date_ms=? WHERE id=?"); + massUpdate.rowPluralName("issues"); + massUpdate.execute(new MassUpdate.Handler() { + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + for (int i = 1; i <= 3; i++) { + Date date = row.getNullableDate(i); + update.setLong(i, date == null ? null : Math.min(now, date.getTime())); + } + + Long id = row.getNullableLong(4); + update.setLong(4, id); + + return true; + } + }); + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v51/FeedManualMeasuresLongDates.java b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedManualMeasuresLongDates.java new file mode 100644 index 00000000000..cb250c840d0 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedManualMeasuresLongDates.java @@ -0,0 +1,66 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import java.sql.SQLException; +import java.util.Date; +import org.sonar.api.utils.System2; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +public class FeedManualMeasuresLongDates extends BaseDataChange { + + private final System2 system2; + + public FeedManualMeasuresLongDates(Database db, System2 system2) { + super(db); + this.system2 = system2; + } + + @Override + public void execute(Context context) throws SQLException { + final long now = system2.now(); + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate + .select("SELECT m.created_at, m.updated_at, m.id FROM manual_measures m WHERE created_at_ms IS NULL"); + massUpdate + .update("UPDATE manual_measures SET created_at_ms=?, updated_at_ms=? WHERE id=?"); + massUpdate.rowPluralName("manual measures"); + massUpdate.execute(new MassUpdate.Handler() { + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + for (int i = 1; i <= 2; i++) { + Date date = row.getNullableDate(i); + update.setLong(i, date == null ? null : Math.min(now, date.getTime())); + } + + Long id = row.getNullableLong(3); + update.setLong(3, id); + + return true; + } + }); + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v51/FeedSnapshotsLongDates.java b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedSnapshotsLongDates.java new file mode 100644 index 00000000000..5e5ae4f149b --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedSnapshotsLongDates.java @@ -0,0 +1,66 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import java.sql.SQLException; +import java.util.Date; +import org.sonar.api.utils.System2; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +public class FeedSnapshotsLongDates extends BaseDataChange { + + private final System2 system2; + + public FeedSnapshotsLongDates(Database db, System2 system2) { + super(db); + this.system2 = system2; + } + + @Override + public void execute(Context context) throws SQLException { + final long now = system2.now(); + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate + .select("SELECT s.created_at, s.build_date, s.period1_date, s.period2_date, s.period3_date, s.period4_date, s.period5_date, s.id FROM snapshots s WHERE created_at_ms IS NULL"); + massUpdate + .update("UPDATE snapshots SET created_at_ms=?, build_date_ms=?, period1_date_ms=?, period2_date_ms=?, period3_date_ms=?, period4_date_ms=?, period5_date_ms=? WHERE id=?"); + massUpdate.rowPluralName("snapshots"); + massUpdate.execute(new MassUpdate.Handler() { + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + for (int i = 1; i <= 7; i++) { + Date date = row.getNullableDate(i); + update.setLong(i, date == null ? null : Math.min(now, date.getTime())); + } + + Long id = row.getNullableLong(8); + update.setLong(8, id); + + return true; + } + }); + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v51/FeedUsersLongDates.java b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedUsersLongDates.java new file mode 100644 index 00000000000..0196e62fc57 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v51/FeedUsersLongDates.java @@ -0,0 +1,78 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import java.sql.SQLException; +import java.util.Date; +import org.sonar.api.utils.System2; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +public class FeedUsersLongDates extends BaseDataChange { + + private final System2 system; + + public FeedUsersLongDates(Database db, System2 system) { + super(db); + this.system = system; + } + + @Override + public void execute(Context context) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("SELECT u.id, u.created_at, u.updated_at FROM users u WHERE created_at_ms IS NULL"); + massUpdate.update("UPDATE users SET created_at_ms=?, updated_at_ms=? WHERE id=?"); + massUpdate.rowPluralName("users"); + massUpdate.execute(new RowHandler(system.now())); + } + + private static class RowHandler implements MassUpdate.Handler { + + private final long now; + + private RowHandler(long now) { + this.now = now; + } + + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + Long id = row.getNullableLong(1); + Date createdAt = row.getNullableDate(2); + Date updatedAt = row.getNullableDate(3); + + if (createdAt == null) { + update.setLong(1, now); + } else { + update.setLong(1, Math.min(now, createdAt.getTime())); + } + if (updatedAt == null) { + update.setLong(2, now); + } else { + update.setLong(2, Math.min(now, updatedAt.getTime())); + } + update.setLong(3, id); + return true; + } + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationStep.java b/sonar-db/src/main/java/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationStep.java new file mode 100644 index 00000000000..bb70c544e89 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationStep.java @@ -0,0 +1,70 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +/** + * See http://jira.sonarsource.com/browse/SONAR-5596 + * + * It's no possible to set permission on a module or a sub-view, but the batch was setting default permission on it on their creation. + * As now it's no more the case, we need to purge this useless data. + * + * @since 5.1 + */ +public class RemovePermissionsOnModulesMigrationStep extends BaseDataChange { + + public RemovePermissionsOnModulesMigrationStep(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + removeUserRolePermissions(context, "user_roles", "user roles"); + removeUserRolePermissions(context, "group_roles", "group roles"); + } + + private void removeUserRolePermissions(Context context, String tableName, String pluralName) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("SELECT r.id " + + "FROM " + tableName + " r " + + " INNER JOIN projects ON projects.id = r.resource_id " + + "WHERE projects.module_uuid IS NOT NULL"); + massUpdate.update("DELETE FROM " + tableName + " WHERE id=?"); + massUpdate.rowPluralName(pluralName); + massUpdate.execute(MigrationHandler.INSTANCE); + } + + private enum MigrationHandler implements MassUpdate.Handler { + INSTANCE; + + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + update.setLong(1, row.getLong(1)); + return true; + } + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFilters.java b/sonar-db/src/main/java/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFilters.java new file mode 100644 index 00000000000..73e8e8b9a79 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFilters.java @@ -0,0 +1,89 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import com.google.common.collect.Lists; +import java.sql.SQLException; +import java.util.Date; +import java.util.List; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.utils.System2; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +public class RenameComponentRelatedParamsInIssueFilters extends BaseDataChange { + + private static final char FIELD_SEPARATOR = '|'; + private static final String LIKE_PREFIX = "data like '%"; + private static final String LIKE_SUFFIX = "%' or "; + private static final String COMPONENT_UUIDS = "componentUuids="; + private static final String COMPONENT_ROOT_UUIDS = "componentRootUuids="; + + private final System2 system; + + public RenameComponentRelatedParamsInIssueFilters(Database db, System2 system) { + super(db); + this.system = system; + } + + @Override + public void execute(Context context) throws SQLException { + final Date now = new Date(system.now()); + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("select id,data from issue_filters where " + + LIKE_PREFIX + COMPONENT_UUIDS + LIKE_SUFFIX + + LIKE_PREFIX + COMPONENT_ROOT_UUIDS + "%'"); + massUpdate.update("update issue_filters set data=?, updated_at=? where id=?"); + massUpdate.rowPluralName("issue filters"); + massUpdate.execute(new RenameComponentRelatedParamsHandler(now)); + } + + private static final class RenameComponentRelatedParamsHandler implements MassUpdate.Handler { + private final Date now; + + private RenameComponentRelatedParamsHandler(Date now) { + this.now = now; + } + + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + String data = row.getNullableString(2); + String[] fields = StringUtils.split(data, FIELD_SEPARATOR); + + List<String> fieldsToKeep = Lists.newArrayList(); + for (String field : fields) { + if (field.startsWith(COMPONENT_UUIDS) || field.startsWith(COMPONENT_ROOT_UUIDS)) { + fieldsToKeep.add( + field.replace(COMPONENT_UUIDS, "fileUuids=") + .replace(COMPONENT_ROOT_UUIDS, "moduleUuids=")); + } else { + fieldsToKeep.add(field); + } + } + update.setString(1, StringUtils.join(fieldsToKeep, FIELD_SEPARATOR)); + update.setDate(2, now); + update.setLong(3, row.getNullableLong(1)); + return true; + } + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v51/UpdateProjectsModuleUuidPath.java b/sonar-db/src/main/java/org/sonar/db/version/v51/UpdateProjectsModuleUuidPath.java new file mode 100644 index 00000000000..d07f9acc2f8 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v51/UpdateProjectsModuleUuidPath.java @@ -0,0 +1,113 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import java.sql.SQLException; +import javax.annotation.Nullable; +import org.apache.commons.lang.StringUtils; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.MassUpdate.Handler; +import org.sonar.db.version.Select.Row; +import org.sonar.db.version.SqlStatement; + +/** + * SONAR-6054 + * SONAR-6119 + */ +public class UpdateProjectsModuleUuidPath extends BaseDataChange { + + private static final String SEP = "."; + + public UpdateProjectsModuleUuidPath(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + MassUpdate update = context.prepareMassUpdate().rowPluralName("components"); + update.select("SELECT p.id, p.module_uuid_path, p.uuid, p.scope, p.qualifier FROM projects p"); + update.update("UPDATE projects SET module_uuid_path=? WHERE id=?"); + update.execute(new ModuleUuidPathUpdateHandler()); + } + + private static final class ModuleUuidPathUpdateHandler implements Handler { + @Override + public boolean handle(Row row, SqlStatement update) throws SQLException { + Long id = row.getNullableLong(1); + String moduleUuidPath = row.getNullableString(2); + String uuid = row.getNullableString(3); + String scope = row.getNullableString(4); + String qualifier = row.getNullableString(5); + + boolean needUpdate = false; + String newModuleUuidPath = moduleUuidPath; + + if (needUpdateForEmptyPath(newModuleUuidPath)) { + newModuleUuidPath = SEP + uuid + SEP; + needUpdate = true; + } + + if (needUpdateForSeparators(newModuleUuidPath)) { + newModuleUuidPath = newModuleUuidPathWithSeparators(newModuleUuidPath); + needUpdate = true; + } + + if (needUpdateToIncludeItself(newModuleUuidPath, uuid, scope, qualifier)) { + newModuleUuidPath = newModuleUuidPathIncludingItself(newModuleUuidPath, uuid); + needUpdate = true; + } + + if (needUpdate) { + update.setString(1, newModuleUuidPath); + update.setLong(2, id); + } + return needUpdate; + } + + private static boolean needUpdateForEmptyPath(@Nullable String moduleUuidPath) { + return StringUtils.isEmpty(moduleUuidPath) || SEP.equals(moduleUuidPath); + } + + private static boolean needUpdateForSeparators(String moduleUuidPath) { + return !(moduleUuidPath.startsWith(SEP) && moduleUuidPath.endsWith(SEP)); + } + + private static String newModuleUuidPathWithSeparators(String oldModuleUuidPath) { + StringBuilder newModuleUuidPath = new StringBuilder(oldModuleUuidPath); + newModuleUuidPath.insert(0, SEP); + newModuleUuidPath.append(SEP); + return newModuleUuidPath.toString(); + } + + private static boolean needUpdateToIncludeItself(String moduleUuidPath, @Nullable String uuid, @Nullable String scope, @Nullable String qualifier) { + return "PRJ".equals(scope) && !("DEV_PRJ".equals(qualifier)) && !(moduleUuidPath.contains(uuid)); + } + + private static String newModuleUuidPathIncludingItself(String moduleUuidPath, String uuid) { + StringBuilder newModuleUuidPath = new StringBuilder(moduleUuidPath); + newModuleUuidPath.append(uuid); + newModuleUuidPath.append(SEP); + return newModuleUuidPath.toString(); + } + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v52/AddManualMeasuresComponentUuidColumn.java b/sonar-db/src/main/java/org/sonar/db/version/v52/AddManualMeasuresComponentUuidColumn.java new file mode 100644 index 00000000000..686db41ae2f --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v52/AddManualMeasuresComponentUuidColumn.java @@ -0,0 +1,58 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.version.AddColumnsBuilder; +import org.sonar.db.version.DdlChange; + +import static org.sonar.db.version.AddColumnsBuilder.ColumnDef.Type.STRING; + +/** + * Add the following column to the manual_measures table : + * - component_uuid + */ +public class AddManualMeasuresComponentUuidColumn extends DdlChange { + private final Database db; + + public AddManualMeasuresComponentUuidColumn(Database db) { + super(db); + this.db = db; + } + + @Override + public void execute(DdlChange.Context context) throws SQLException { + context.execute(generateSql()); + } + + private String generateSql() { + return new AddColumnsBuilder(db.getDialect(), "manual_measures") + .addColumn( + new AddColumnsBuilder.ColumnDef() + .setName("component_uuid") + .setType(STRING) + .setLimit(50) + .setNullable(true) + ) + .build(); + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v52/FeedEventsComponentUuid.java b/sonar-db/src/main/java/org/sonar/db/version/v52/FeedEventsComponentUuid.java new file mode 100644 index 00000000000..a6139e1e946 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v52/FeedEventsComponentUuid.java @@ -0,0 +1,58 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +public class FeedEventsComponentUuid extends BaseDataChange { + + public FeedEventsComponentUuid(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + MassUpdate update = context.prepareMassUpdate().rowPluralName("events"); + update.select( + "SELECT p.uuid, event.id " + + "FROM events event " + + "INNER JOIN projects p ON p.id=event.resource_id " + + "WHERE event.component_uuid is null"); + update.update("UPDATE events SET component_uuid=? WHERE id=?"); + update.execute(MigrationHandler.INSTANCE); + } + + private enum MigrationHandler implements MassUpdate.Handler { + INSTANCE; + + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + update.setString(1, row.getString(1)); + update.setLong(2, row.getLong(2)); + return true; + } + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v52/FeedFileSourcesDataType.java b/sonar-db/src/main/java/org/sonar/db/version/v52/FeedFileSourcesDataType.java new file mode 100644 index 00000000000..b37e60054b3 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v52/FeedFileSourcesDataType.java @@ -0,0 +1,37 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; + +public class FeedFileSourcesDataType extends BaseDataChange { + + public FeedFileSourcesDataType(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + context.prepareUpsert("update file_sources set data_type = 'SOURCE'").execute().commit(); + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v52/FeedManualMeasuresComponentUuid.java b/sonar-db/src/main/java/org/sonar/db/version/v52/FeedManualMeasuresComponentUuid.java new file mode 100644 index 00000000000..36b14ac2e83 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v52/FeedManualMeasuresComponentUuid.java @@ -0,0 +1,56 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +public class FeedManualMeasuresComponentUuid extends BaseDataChange { + + public FeedManualMeasuresComponentUuid(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + MassUpdate update = context.prepareMassUpdate().rowPluralName("manual measures"); + update.select( + "SELECT p.uuid, mm.resource_id " + + "FROM manual_measures mm " + + "INNER JOIN projects p ON mm.resource_id = p.id " + + "WHERE mm.component_uuid IS NULL"); + update.update("UPDATE manual_measures SET component_uuid=? WHERE resource_id=?"); + update.execute(new SqlRowHandler()); + } + + private static class SqlRowHandler implements MassUpdate.Handler { + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + update.setString(1, row.getString(1)); + update.setLong(2, row.getLong(2)); + return true; + } + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v52/FeedMetricsBooleans.java b/sonar-db/src/main/java/org/sonar/db/version/v52/FeedMetricsBooleans.java new file mode 100644 index 00000000000..f28bc096e5b --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v52/FeedMetricsBooleans.java @@ -0,0 +1,43 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; + +public class FeedMetricsBooleans extends BaseDataChange { + + public FeedMetricsBooleans(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + context.prepareUpsert("update metrics set optimized_best_value=?, hidden=?, delete_historical_data=? " + + "where user_managed=? or optimized_best_value is null or hidden is null or delete_historical_data is null") + .setBoolean(1, false) + .setBoolean(2, false) + .setBoolean(3, false) + .setBoolean(4, true) + .execute().commit(); + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v52/FeedProjectLinksComponentUuid.java b/sonar-db/src/main/java/org/sonar/db/version/v52/FeedProjectLinksComponentUuid.java new file mode 100644 index 00000000000..4162aacb2ca --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v52/FeedProjectLinksComponentUuid.java @@ -0,0 +1,58 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select.Row; +import org.sonar.db.version.SqlStatement; + +public class FeedProjectLinksComponentUuid extends BaseDataChange { + + public FeedProjectLinksComponentUuid(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + MassUpdate update = context.prepareMassUpdate().rowPluralName("project links"); + update.select( + "SELECT p.uuid, link.id " + + "FROM project_links link " + + "INNER JOIN projects p ON p.id=link.project_id " + + "WHERE link.component_uuid is null"); + update.update("UPDATE project_links SET component_uuid=? WHERE id=?"); + update.execute(MigrationHandler.INSTANCE); + } + + private enum MigrationHandler implements MassUpdate.Handler { + INSTANCE; + + @Override + public boolean handle(Row row, SqlStatement update) throws SQLException { + update.setString(1, row.getString(1)); + update.setLong(2, row.getLong(2)); + return true; + } + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v52/MoveProjectProfileAssociation.java b/sonar-db/src/main/java/org/sonar/db/version/v52/MoveProjectProfileAssociation.java new file mode 100644 index 00000000000..d533aa73ef4 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v52/MoveProjectProfileAssociation.java @@ -0,0 +1,136 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Table; +import java.sql.SQLException; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.MassUpdate.Handler; +import org.sonar.db.version.Select; +import org.sonar.db.version.Select.Row; +import org.sonar.db.version.Select.RowReader; +import org.sonar.db.version.SqlStatement; +import org.sonar.db.version.Upsert; + +/** + * SonarQube 5.2 + * SONAR-6328 + * + */ +public class MoveProjectProfileAssociation extends BaseDataChange { + + private static final class ProjectProfileAssociationHandler implements Handler { + private final Upsert setDefaultProfile; + private final Upsert associateProjectToProfile; + private final Table<String, String, String> profileKeysByLanguageThenName; + + private ProjectProfileAssociationHandler(Upsert setDefaultProfile, Upsert associateProjectToProfile, Table<String, String, String> profileKeysByLanguageThenName) { + this.setDefaultProfile = setDefaultProfile; + this.associateProjectToProfile = associateProjectToProfile; + this.profileKeysByLanguageThenName = profileKeysByLanguageThenName; + } + + @Override + public boolean handle(Row row, SqlStatement update) throws SQLException { + Long id = row.getLong(1); + String profileLanguage = extractLanguage(row.getString(2)); + String profileName = row.getString(3); + Long projectId = row.getNullableLong(4); + String projectUuid = row.getString(5); + + if (profileKeysByLanguageThenName.contains(profileLanguage, profileName)) { + String profileKey = profileKeysByLanguageThenName.get(profileLanguage, profileName); + + if (projectUuid == null) { + if (projectId == null) { + setDefaultProfile.setBoolean(1, true).setString(2, profileKey).execute(); + } else { + LOGGER.warn(String.format("Profile with language '%s' and name '%s' is associated with unknown project '%d', ignored", profileLanguage, profileName, projectId)); + } + } else { + associateProjectToProfile.setString(1, projectUuid).setString(2, profileKey).execute(); + } + } else { + LOGGER.warn(String.format("Unable to find profile with language '%s' and name '%s', ignored", profileLanguage, profileName)); + } + + update.setLong(1, id); + return true; + } + } + + private static final Logger LOGGER = Loggers.get(MoveProjectProfileAssociation.class); + + public MoveProjectProfileAssociation(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + + final Table<String, String, String> profileKeysByLanguageThenName = getProfileKeysByLanguageThenName(context); + + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("SELECT prop.id, prop.prop_key, prop.text_value, prop.resource_id, proj.uuid " + + "FROM properties prop " + + "LEFT OUTER JOIN projects proj ON prop.resource_id = proj.id " + + "WHERE prop.prop_key LIKE 'sonar.profile.%'" + ); + massUpdate.update("DELETE FROM properties WHERE id = ?"); + + final Upsert setDefaultProfile = context.prepareUpsert("UPDATE rules_profiles SET is_default = ? WHERE kee = ?"); + final Upsert associateProjectToProfile = context.prepareUpsert("INSERT INTO project_qprofiles (project_uuid, profile_key) VALUES (?, ?)"); + + try { + massUpdate.execute(new ProjectProfileAssociationHandler(setDefaultProfile, associateProjectToProfile, profileKeysByLanguageThenName)); + } finally { + associateProjectToProfile.close(); + setDefaultProfile.close(); + } + } + + private static String extractLanguage(String propertyKey) { + return propertyKey.substring("sonar.profile.".length()); + } + + private Table<String, String, String> getProfileKeysByLanguageThenName(final Context context) throws SQLException { + final Table<String, String, String> profilesByLanguageAndName = HashBasedTable.create(); + + Select selectProfiles = context.prepareSelect("SELECT kee, name, language FROM rules_profiles"); + try { + selectProfiles.list(new RowReader<Void>() { + @Override + public Void read(Row row) throws SQLException { + profilesByLanguageAndName.put(row.getString(3), row.getString(2), row.getString(1)); + return null; + } + }); + } finally { + selectProfiles.close(); + } + + return profilesByLanguageAndName; + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v52/RemoveComponentLibraries.java b/sonar-db/src/main/java/org/sonar/db/version/v52/RemoveComponentLibraries.java new file mode 100644 index 00000000000..11945b60316 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v52/RemoveComponentLibraries.java @@ -0,0 +1,56 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +/** + * Remove all components having qualifier 'LIB' + */ +public class RemoveComponentLibraries extends BaseDataChange { + + public RemoveComponentLibraries(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + MassUpdate update = context.prepareMassUpdate().rowPluralName("component libraries"); + update.select("SELECT p.id FROM projects p WHERE p.qualifier='LIB'"); + update.update("DELETE FROM projects WHERE id=?"); + update.execute(MigrationHandler.INSTANCE); + } + + private enum MigrationHandler implements MassUpdate.Handler { + INSTANCE; + + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + update.setLong(1, row.getLong(1)); + return true; + } + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v52/RemoveDuplicatedComponentKeys.java b/sonar-db/src/main/java/org/sonar/db/version/v52/RemoveDuplicatedComponentKeys.java new file mode 100644 index 00000000000..557c562fca0 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v52/RemoveDuplicatedComponentKeys.java @@ -0,0 +1,163 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.FluentIterable; +import java.sql.SQLException; +import java.util.List; +import java.util.concurrent.atomic.AtomicLong; +import javax.annotation.Nonnull; +import org.sonar.core.util.ProgressLogger; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.Select; +import org.sonar.db.version.Upsert; + +/** + * Remove all duplicated component that have the same keys. + * For each duplicated component key : + * <ul> + * <li>Only the enabled one or last one (with the latest id) is kept</li> + * <li>When deleting a component, all its issues are linked to the remaining component</li> + * </ul> + */ +public class RemoveDuplicatedComponentKeys extends BaseDataChange { + + private final AtomicLong counter = new AtomicLong(0L); + + public RemoveDuplicatedComponentKeys(Database db) { + super(db); + } + + @Override + public void execute(final Context context) throws SQLException { + Upsert componentUpdate = context.prepareUpsert("DELETE FROM projects WHERE id=?"); + Upsert issuesUpdate = context.prepareUpsert("UPDATE issues SET component_uuid=?, project_uuid=? WHERE component_uuid=?"); + + ProgressLogger progress = ProgressLogger.create(getClass(), counter); + progress.start(); + try { + RemoveDuplicatedComponentHandler handler = new RemoveDuplicatedComponentHandler(context, componentUpdate, issuesUpdate); + context.prepareSelect( + "SELECT p.kee, COUNT(p.kee) FROM projects p " + + "GROUP BY p.kee " + + "HAVING COUNT(p.kee) > 1") + .scroll(handler); + if (!handler.isEmpty) { + componentUpdate.execute().commit(); + issuesUpdate.execute().commit(); + } + progress.log(); + } finally { + progress.stop(); + componentUpdate.close(); + issuesUpdate.close(); + } + } + + private class RemoveDuplicatedComponentHandler implements Select.RowHandler { + private final Context context; + private final Upsert componentUpdate; + private final Upsert issuesUpdate; + + private boolean isEmpty = true; + + public RemoveDuplicatedComponentHandler(Context context, Upsert componentUpdate, Upsert issuesUpdate) { + this.context = context; + this.componentUpdate = componentUpdate; + this.issuesUpdate = issuesUpdate; + } + + @Override + public void handle(Select.Row row) throws SQLException { + List<Component> components = context + .prepareSelect("SELECT p.id, p.uuid, p.project_uuid, p.enabled FROM projects p WHERE p.kee=? ORDER BY id") + .setString(1, row.getString(1)) + .list(ComponentRowReader.INSTANCE); + // We keep the enabled component or the last component of the list + Component refComponent = FluentIterable.from(components).firstMatch(EnabledComponent.INSTANCE).or(components.get(components.size() - 1)); + for (Component componentToRemove : FluentIterable.from(components).filter(Predicates.not(new MatchComponentId(refComponent.id)))) { + componentUpdate + .setLong(1, componentToRemove.id) + .addBatch(); + issuesUpdate + .setString(1, refComponent.uuid) + .setString(2, refComponent.projectUuid) + .setString(3, componentToRemove.uuid) + .addBatch(); + counter.getAndIncrement(); + isEmpty = false; + } + } + + public boolean isEmpty() { + return isEmpty; + } + } + + private enum EnabledComponent implements Predicate<Component> { + INSTANCE; + + @Override + public boolean apply(@Nonnull Component input) { + return input.enabled; + } + } + + private static class MatchComponentId implements Predicate<Component> { + + private final long id; + + public MatchComponentId(long id) { + this.id = id; + } + + @Override + public boolean apply(@Nonnull Component input) { + return input.id == this.id; + } + } + + private enum ComponentRowReader implements Select.RowReader<Component> { + INSTANCE; + + @Override + public Component read(Select.Row row) throws SQLException { + return new Component(row.getLong(1), row.getString(2), row.getString(3), row.getBoolean(4)); + } + } + + private static class Component { + private final long id; + private final String uuid; + private final String projectUuid; + private final boolean enabled; + + public Component(long id, String uuid, String projectUuid, boolean enabled) { + this.id = id; + this.uuid = uuid; + this.projectUuid = projectUuid; + this.enabled = enabled; + } + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v52/RemoveSnapshotLibraries.java b/sonar-db/src/main/java/org/sonar/db/version/v52/RemoveSnapshotLibraries.java new file mode 100644 index 00000000000..108200dac7e --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v52/RemoveSnapshotLibraries.java @@ -0,0 +1,56 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +/** + * Remove all components having qualifier 'LIB' + */ +public class RemoveSnapshotLibraries extends BaseDataChange { + + public RemoveSnapshotLibraries(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + MassUpdate update = context.prepareMassUpdate().rowPluralName("snapshot libraries"); + update.select("SELECT s.id FROM snapshots s WHERE s.qualifier='LIB'"); + update.update("DELETE FROM snapshots WHERE id=?"); + update.execute(MigrationHandler.INSTANCE); + } + + private enum MigrationHandler implements MassUpdate.Handler { + INSTANCE; + + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + update.setLong(1, row.getLong(1)); + return true; + } + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/AddColumnsBuilderTest.java b/sonar-db/src/test/java/org/sonar/db/version/AddColumnsBuilderTest.java new file mode 100644 index 00000000000..e5160243c7f --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/AddColumnsBuilderTest.java @@ -0,0 +1,136 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import org.junit.Test; +import org.sonar.db.dialect.H2; +import org.sonar.db.dialect.MsSql; +import org.sonar.db.dialect.MySql; +import org.sonar.db.dialect.Oracle; +import org.sonar.db.dialect.PostgreSql; +import org.sonar.db.version.AddColumnsBuilder; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown; + +public class AddColumnsBuilderTest { + + @Test + public void add_columns_on_h2() { + assertThat(new AddColumnsBuilder(new H2(), "issues") + .addColumn(new AddColumnsBuilder.ColumnDef() + .setName("date_in_ms") + .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER) + .setNullable(true)) + .addColumn(new AddColumnsBuilder.ColumnDef() + .setName("name") + .setType(AddColumnsBuilder.ColumnDef.Type.STRING) + .setNullable(false) + .setLimit(10)) + .build()).isEqualTo("ALTER TABLE issues ADD (date_in_ms BIGINT NULL, name VARCHAR (10) NOT NULL)"); + } + + @Test + public void add_columns_on_mysql() { + assertThat(new AddColumnsBuilder(new MySql(), "issues") + .addColumn(new AddColumnsBuilder.ColumnDef() + .setName("date_in_ms") + .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER) + .setNullable(true)) + .addColumn(new AddColumnsBuilder.ColumnDef() + .setName("name") + .setType(AddColumnsBuilder.ColumnDef.Type.STRING) + .setNullable(false) + .setLimit(10)) + .build()).isEqualTo("ALTER TABLE issues ADD (date_in_ms BIGINT NULL, name VARCHAR (10) NOT NULL)"); + } + + @Test + public void add_columns_on_oracle() { + assertThat(new AddColumnsBuilder(new Oracle(), "issues") + .addColumn(new AddColumnsBuilder.ColumnDef() + .setName("date_in_ms") + .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER) + .setNullable(true)) + .addColumn(new AddColumnsBuilder.ColumnDef() + .setName("name") + .setType(AddColumnsBuilder.ColumnDef.Type.STRING) + .setNullable(false) + .setLimit(10)) + .build()).isEqualTo("ALTER TABLE issues ADD (date_in_ms NUMBER (38) NULL, name VARCHAR (10) NOT NULL)"); + } + + @Test + public void add_columns_on_postgresql() { + assertThat(new AddColumnsBuilder(new PostgreSql(), "issues") + .addColumn(new AddColumnsBuilder.ColumnDef() + .setName("date_in_ms") + .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER) + .setNullable(true)) + .addColumn(new AddColumnsBuilder.ColumnDef() + .setName("name") + .setType(AddColumnsBuilder.ColumnDef.Type.STRING) + .setNullable(false) + .setLimit(10)) + .build()).isEqualTo("ALTER TABLE issues ADD COLUMN date_in_ms BIGINT NULL, ADD COLUMN name VARCHAR (10) NOT NULL"); + } + + @Test + public void add_columns_on_mssql() { + assertThat(new AddColumnsBuilder(new MsSql(), "issues") + .addColumn(new AddColumnsBuilder.ColumnDef() + .setName("date_in_ms") + .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER) + .setNullable(true)) + .addColumn(new AddColumnsBuilder.ColumnDef() + .setName("name") + .setType(AddColumnsBuilder.ColumnDef.Type.STRING) + .setNullable(false) + .setLimit(10)) + .build()).isEqualTo("ALTER TABLE issues ADD date_in_ms BIGINT NULL, name VARCHAR (10) NOT NULL"); + } + + @Test + public void fail_when_column_name_is_in_upper_case() { + try { + new AddColumnsBuilder.ColumnDef() + .setName("DATE_IN_MS") + .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER) + .setNullable(true); + failBecauseExceptionWasNotThrown(IllegalArgumentException.class); + } catch (IllegalArgumentException e) { + assertThat(e).hasMessage("Column name should only contains lowercase and _ characters"); + } + } + + @Test + public void fail_when_column_name_contains_invalid_character() { + try { + new AddColumnsBuilder.ColumnDef() + .setName("date-in/ms") + .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER) + .setNullable(true); + failBecauseExceptionWasNotThrown(IllegalArgumentException.class); + } catch (IllegalArgumentException e) { + assertThat(e).hasMessage("Column name should only contains lowercase and _ characters"); + } + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/BaseDataChangeTest.java b/sonar-db/src/test/java/org/sonar/db/version/BaseDataChangeTest.java new file mode 100644 index 00000000000..56a5ed91799 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/BaseDataChangeTest.java @@ -0,0 +1,481 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.ExpectedException; +import org.sonar.api.utils.System2; +import org.sonar.db.BatchSession; +import org.sonar.db.DbTester; +import org.sonar.db.version.Select.Row; +import org.sonar.db.version.Select.RowReader; +import org.sonar.test.DbTests; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.fail; + +@Category(DbTests.class) +public class BaseDataChangeTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, BaseDataChangeTest.class, "schema.sql"); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Before + public void setUp() { + db.executeUpdateSql("truncate table persons"); + } + + @Test + public void query() throws Exception { + db.prepareDbUnit(getClass(), "persons.xml"); + + final AtomicBoolean executed = new AtomicBoolean(false); + new BaseDataChange(db.database()) { + @Override + public void execute(Context context) throws SQLException { + assertThat(context.prepareSelect("select id from persons order by id desc").list(Select.LONG_READER)) + .containsExactly(3L, 2L, 1L); + assertThat(context.prepareSelect("select id from persons where id=?").setLong(1, 2L).get(Select.LONG_READER)) + .isEqualTo(2L); + assertThat(context.prepareSelect("select id from persons where id=?").setLong(1, 12345L).get(Select.LONG_READER)) + .isNull(); + executed.set(true); + } + }.execute(); + assertThat(executed.get()).isTrue(); + } + + @Test + public void read_column_types() throws Exception { + db.prepareDbUnit(getClass(), "persons.xml"); + + final List<Object[]> persons = new ArrayList<>(); + new BaseDataChange(db.database()) { + @Override + public void execute(Context context) throws SQLException { + persons.addAll(context + .prepareSelect("select id,login,age,enabled,updated_at,coeff from persons where id=2") + .list(new UserReader())); + } + }.execute(); + assertThat(persons).hasSize(1); + assertThat(persons.get(0)[0]).isEqualTo(2L); + assertThat(persons.get(0)[1]).isEqualTo("emmerik"); + assertThat(persons.get(0)[2]).isEqualTo(14); + assertThat(persons.get(0)[3]).isEqualTo(true); + assertThat(persons.get(0)[4]).isNotNull(); + assertThat(persons.get(0)[5]).isEqualTo(5.2); + } + + @Test + public void parameterized_query() throws Exception { + db.prepareDbUnit(getClass(), "persons.xml"); + + final List<Long> ids = new ArrayList<>(); + new BaseDataChange(db.database()) { + @Override + public void execute(Context context) throws SQLException { + ids.addAll(context.prepareSelect("select id from persons where id>=?").setLong(1, 2L).list(Select.LONG_READER)); + } + }.execute(); + assertThat(ids).containsOnly(2L, 3L); + } + + @Test + public void display_current_row_details_if_error_during_get() throws Exception { + db.prepareDbUnit(getClass(), "persons.xml"); + + thrown.expect(IllegalStateException.class); + thrown.expectMessage("Error during processing of row: [id=2]"); + + new BaseDataChange(db.database()) { + @Override + public void execute(Context context) throws SQLException { + context.prepareSelect("select id from persons where id>=?").setLong(1, 2L).get(new RowReader<Long>() { + @Override + public Long read(Row row) throws SQLException { + throw new IllegalStateException("Unexpected error"); + } + }); + } + }.execute(); + + } + + @Test + public void display_current_row_details_if_error_during_list() throws Exception { + db.prepareDbUnit(getClass(), "persons.xml"); + + thrown.expect(IllegalStateException.class); + thrown.expectMessage("Error during processing of row: [id=2]"); + + new BaseDataChange(db.database()) { + @Override + public void execute(Context context) throws SQLException { + context.prepareSelect("select id from persons where id>=?").setLong(1, 2L).list(new RowReader<Long>() { + @Override + public Long read(Row row) throws SQLException { + throw new IllegalStateException("Unexpected error"); + } + }); + } + }.execute(); + + } + + @Test + public void bad_parameterized_query() throws Exception { + db.prepareDbUnit(getClass(), "persons.xml"); + + final List<Long> ids = new ArrayList<>(); + BaseDataChange change = new BaseDataChange(db.database()) { + @Override + public void execute(Context context) throws SQLException { + // parameter value is not set + ids.addAll(context.prepareSelect("select id from persons where id>=?").list(Select.LONG_READER)); + } + }; + + thrown.expect(SQLException.class); + + change.execute(); + } + + @Test + public void scroll() throws Exception { + db.prepareDbUnit(getClass(), "persons.xml"); + + final List<Long> ids = new ArrayList<>(); + new BaseDataChange(db.database()) { + @Override + public void execute(Context context) throws SQLException { + context.prepareSelect("select id from persons order by id desc").scroll(new Select.RowHandler() { + @Override + public void handle(Select.Row row) throws SQLException { + ids.add(row.getNullableLong(1)); + } + }); + } + }.execute(); + assertThat(ids).containsExactly(3L, 2L, 1L); + } + + @Test + public void insert() throws Exception { + db.prepareDbUnit(getClass(), "persons.xml"); + + new BaseDataChange(db.database()) { + @Override + public void execute(Context context) throws SQLException { + context.prepareUpsert("insert into persons(id,login,age,enabled,coeff) values (?,?,?,?,?)") + .setLong(1, 10L) + .setString(2, "kurt") + .setInt(3, 27) + .setBoolean(4, true) + .setDouble(5, 2.2) + .execute().commit().close(); + } + }.execute(); + + db.assertDbUnit(getClass(), "insert-result.xml", "persons"); + } + + @Test + public void batch_insert() throws Exception { + db.prepareDbUnit(getClass(), "persons.xml"); + + new BaseDataChange(db.database()) { + @Override + public void execute(Context context) throws SQLException { + Upsert upsert = context.prepareUpsert("insert into persons(id,login,age,enabled,coeff) values (?,?,?,?,?)"); + upsert + .setLong(1, 10L) + .setString(2, "kurt") + .setInt(3, 27) + .setBoolean(4, true) + .setDouble(5, 2.2) + .addBatch(); + upsert + .setLong(1, 11L) + .setString(2, "courtney") + .setInt(3, 25) + .setBoolean(4, false) + .setDouble(5, 2.3) + .addBatch(); + upsert.execute().commit().close(); + } + }.execute(); + + db.assertDbUnit(getClass(), "batch-insert-result.xml", "persons"); + } + + @Test + public void update_null() throws Exception { + db.prepareDbUnit(getClass(), "persons.xml"); + + new BaseDataChange(db.database()) { + @Override + public void execute(Context context) throws SQLException { + Upsert upsert = context.prepareUpsert("update persons set login=?,age=?,enabled=?, updated_at=?, coeff=? where id=?"); + upsert + .setString(1, null) + .setInt(2, null) + .setBoolean(3, null) + .setDate(4, null) + .setDouble(5, null) + .setLong(6, 2L) + .execute() + .commit() + .close(); + } + }.execute(); + + db.assertDbUnit(getClass(), "update-null-result.xml", "persons"); + } + + @Test + public void mass_batch_insert() throws Exception { + db.executeUpdateSql("truncate table persons"); + + final int count = BatchSession.MAX_BATCH_SIZE + 10; + new BaseDataChange(db.database()) { + @Override + public void execute(Context context) throws SQLException { + Upsert upsert = context.prepareUpsert("insert into persons(id,login,age,enabled,coeff) values (?,?,?,?,?)"); + for (int i = 0; i < count; i++) { + upsert + .setLong(1, 10L + i) + .setString(2, "login" + i) + .setInt(3, 10 + i) + .setBoolean(4, true) + .setDouble(4, i + 0.5) + .addBatch(); + } + upsert.execute().commit().close(); + + } + }.execute(); + + assertThat(db.countRowsOfTable("persons")).isEqualTo(count); + } + + @Test + public void scroll_and_update() throws Exception { + db.prepareDbUnit(getClass(), "persons.xml"); + + new BaseDataChange(db.database()) { + @Override + public void execute(Context context) throws SQLException { + final Upsert upsert = context.prepareUpsert("update persons set login=?, age=? where id=?"); + context.prepareSelect("select id from persons").scroll(new Select.RowHandler() { + @Override + public void handle(Select.Row row) throws SQLException { + long id = row.getNullableLong(1); + upsert.setString(1, "login" + id).setInt(2, 10 + (int) id).setLong(3, id); + upsert.execute(); + } + }); + upsert.commit().close(); + } + }.execute(); + + db.assertDbUnit(getClass(), "scroll-and-update-result.xml", "persons"); + } + + @Test + public void display_current_row_details_if_error_during_scroll() throws Exception { + db.prepareDbUnit(getClass(), "persons.xml"); + + thrown.expect(IllegalStateException.class); + thrown.expectMessage("Error during processing of row: [id=1]"); + + new BaseDataChange(db.database()) { + @Override + public void execute(Context context) throws SQLException { + final Upsert upsert = context.prepareUpsert("update persons set login=?, age=? where id=?"); + context.prepareSelect("select id from persons").scroll(new Select.RowHandler() { + @Override + public void handle(Select.Row row) throws SQLException { + throw new IllegalStateException("Unexpected error"); + } + }); + upsert.commit().close(); + } + }.execute(); + } + + @Test + public void mass_update() throws Exception { + db.prepareDbUnit(getClass(), "persons.xml"); + + new BaseDataChange(db.database()) { + @Override + public void execute(Context context) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("select id from persons where id>=?").setLong(1, 2L); + massUpdate.update("update persons set login=?, age=? where id=?"); + massUpdate.execute(new MassUpdate.Handler() { + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + long id = row.getNullableLong(1); + update + .setString(1, "login" + id) + .setInt(2, 10 + (int) id) + .setLong(3, id); + return true; + } + }); + } + }.execute(); + + db.assertDbUnit(getClass(), "mass-update-result.xml", "persons"); + } + + @Test + public void display_current_row_details_if_error_during_mass_update() throws Exception { + db.prepareDbUnit(getClass(), "persons.xml"); + + thrown.expect(IllegalStateException.class); + thrown.expectMessage("Error during processing of row: [id=2]"); + + new BaseDataChange(db.database()) { + @Override + public void execute(Context context) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("select id from persons where id>=?").setLong(1, 2L); + massUpdate.update("update persons set login=?, age=? where id=?"); + massUpdate.execute(new MassUpdate.Handler() { + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + throw new IllegalStateException("Unexpected error"); + } + }); + } + }.execute(); + } + + @Test + public void mass_update_nothing() throws Exception { + db.prepareDbUnit(getClass(), "persons.xml"); + + new BaseDataChange(db.database()) { + @Override + public void execute(Context context) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("select id from persons where id>=?").setLong(1, 2L); + massUpdate.update("update persons set login=?, age=? where id=?"); + massUpdate.execute(new MassUpdate.Handler() { + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + return false; + } + }); + } + }.execute(); + + db.assertDbUnit(getClass(), "persons.xml", "persons"); + } + + @Test + public void bad_mass_update() throws Exception { + db.prepareDbUnit(getClass(), "persons.xml"); + + BaseDataChange change = new BaseDataChange(db.database()) { + @Override + public void execute(Context context) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("select id from persons where id>=?").setLong(1, 2L); + // update is not set + massUpdate.execute(new MassUpdate.Handler() { + @Override + public boolean handle(Select.Row row, SqlStatement update) throws SQLException { + return false; + } + }); + } + }; + try { + change.execute(); + fail(); + } catch (IllegalStateException e) { + assertThat(e).hasMessage("SELECT or UPDATE requests are not defined"); + } + } + + @Test + public void read_not_null_fields() throws Exception { + db.prepareDbUnit(getClass(), "persons.xml"); + + final List<Object[]> persons = new ArrayList<>(); + new BaseDataChange(db.database()) { + @Override + public void execute(Context context) throws SQLException { + persons.addAll(context + .prepareSelect("select id,login,age,enabled,updated_at,coeff from persons where id=2") + .list(new Select.RowReader<Object[]>() { + @Override + public Object[] read(Select.Row row) throws SQLException { + return new Object[] { + // id, login, age, enabled + row.getLong(1), + row.getString(2), + row.getInt(3), + row.getBoolean(4), + row.getDate(5), + row.getDouble(6), + }; + } + })); + } + }.execute(); + assertThat(persons).hasSize(1); + assertThat(persons.get(0)[0]).isEqualTo(2L); + assertThat(persons.get(0)[1]).isEqualTo("emmerik"); + assertThat(persons.get(0)[2]).isEqualTo(14); + assertThat(persons.get(0)[3]).isEqualTo(true); + assertThat(persons.get(0)[4]).isNotNull(); + assertThat(persons.get(0)[5]).isEqualTo(5.2); + } + + static class UserReader implements Select.RowReader<Object[]> { + @Override + public Object[] read(Select.Row row) throws SQLException { + return new Object[] { + // id, login, age, enabled + row.getNullableLong(1), + row.getNullableString(2), + row.getNullableInt(3), + row.getNullableBoolean(4), + row.getNullableDate(5), + row.getNullableDouble(6), + }; + } + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/DropColumnsBuilderTest.java b/sonar-db/src/test/java/org/sonar/db/version/DropColumnsBuilderTest.java new file mode 100644 index 00000000000..e7c6955f185 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/DropColumnsBuilderTest.java @@ -0,0 +1,64 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import org.junit.Test; +import org.sonar.db.dialect.H2; +import org.sonar.db.dialect.MsSql; +import org.sonar.db.dialect.MySql; +import org.sonar.db.dialect.Oracle; +import org.sonar.db.dialect.PostgreSql; +import org.sonar.db.version.DropColumnsBuilder; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DropColumnsBuilderTest { + + @Test + public void drop_columns_on_mysql() { + assertThat(new DropColumnsBuilder(new MySql(), "issues", "date_in_ms", "name") + .build()).isEqualTo("ALTER TABLE issues DROP COLUMN date_in_ms, DROP COLUMN name"); + } + + @Test + public void drop_columns_on_oracle() { + assertThat(new DropColumnsBuilder(new Oracle(), "issues", "date_in_ms", "name") + .build()).isEqualTo("ALTER TABLE issues DROP (date_in_ms, name)"); + } + + @Test + public void drop_columns_on_postgresql() { + assertThat(new DropColumnsBuilder(new PostgreSql(), "issues", "date_in_ms", "name") + .build()).isEqualTo("ALTER TABLE issues DROP COLUMN date_in_ms, DROP COLUMN name"); + } + + @Test + public void drop_columns_on_mssql() { + assertThat(new DropColumnsBuilder(new MsSql(), "issues", "date_in_ms", "name") + .build()).isEqualTo("ALTER TABLE issues DROP COLUMN date_in_ms, name"); + } + + @Test(expected = IllegalStateException.class) + public void fail_to_drop_columns_on_h2() { + new DropColumnsBuilder(new H2(), "issues", "date_in_ms", "name") + .build(); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java b/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java new file mode 100644 index 00000000000..6c3fb4cba25 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java @@ -0,0 +1,35 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version; + +import org.junit.Test; +import org.sonar.core.platform.ComponentContainer; +import org.sonar.db.version.MigrationStepModule; + +import static org.assertj.core.api.Assertions.assertThat; + +public class MigrationStepModuleTest { + @Test + public void verify_count_of_added_MigrationStep_types() { + ComponentContainer container = new ComponentContainer(); + new MigrationStepModule().configure(container); + assertThat(container.size()).isEqualTo(38); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest.java b/sonar-db/src/test/java/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest.java new file mode 100644 index 00000000000..eb291dda5c9 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest.java @@ -0,0 +1,76 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v451; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class AddMissingCustomRuleParametersMigrationTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, AddMissingCustomRuleParametersMigrationTest.class, "schema.sql"); + + MigrationStep migration; + System2 system = mock(System2.class); + + @Before + public void setUp() { + db.executeUpdateSql("truncate table rules"); + db.executeUpdateSql("truncate table rules_parameters"); + migration = new AddMissingCustomRuleParametersMigrationStep(db.getDbClient(), system); + when(system.now()).thenReturn(DateUtils.parseDate("2014-10-09").getTime()); + } + + @Test + public void execute() throws Exception { + db.prepareDbUnit(getClass(), "execute.xml"); + + migration.execute(); + + db.assertDbUnit(getClass(), "execute-result.xml", "rules", "rules_parameters"); + } + + @Test + public void execute_when_custom_rule_have_no_parameter() throws Exception { + db.prepareDbUnit(getClass(), "execute_when_custom_rule_have_no_parameter.xml"); + + migration.execute(); + + db.assertDbUnit(getClass(), "execute_when_custom_rule_have_no_parameter-result.xml", "rules", "rules_parameters"); + } + + @Test + public void no_changes() throws Exception { + db.prepareDbUnit(getClass(), "no_changes.xml"); + + migration.execute(); + + db.assertDbUnit(getClass(), "no_changes.xml", "rules", "rules_parameters"); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest.java new file mode 100644 index 00000000000..00808bb8f0a --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest.java @@ -0,0 +1,60 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v451; + +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DeleteUnescapedActivitiesTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, DeleteUnescapedActivitiesTest.class, "schema.sql"); + + MigrationStep migration; + + @Test + public void execute() throws Exception { + migration = new DeleteUnescapedActivities(db.database()); + db.prepareDbUnit(getClass(), "execute.xml"); + migration.execute(); + db.assertDbUnit(getClass(), "execute-result.xml", "activities"); + } + + @Test + public void is_unescaped() { + assertThat(DeleteUnescapedActivities.isUnescaped( + "ruleKey=findbugs:PT_RELATIVE_PATH_TRAVERSAL;profileKey=java-findbugs-74105;severity=MAJOR;" + + "key=java-findbugs-74105:findbugs:PT_RELATIVE_PATH_TRAVERSAL")) + .isFalse(); + assertThat(DeleteUnescapedActivities.isUnescaped(null)).isFalse(); + assertThat(DeleteUnescapedActivities.isUnescaped("")).isFalse(); + assertThat(DeleteUnescapedActivities.isUnescaped("foo=bar")).isFalse(); + assertThat(DeleteUnescapedActivities.isUnescaped("param_xpath=/foo/bar")).isFalse(); + + assertThat(DeleteUnescapedActivities.isUnescaped("param_xpath=/foo/bar;foo;ruleKey=S001")).isTrue(); + assertThat(DeleteUnescapedActivities.isUnescaped("param_xpath=/foo=foo;ruleKey=S001")).isTrue(); + + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v50/FeedFileSourcesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v50/FeedFileSourcesTest.java new file mode 100644 index 00000000000..1ac8362180a --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v50/FeedFileSourcesTest.java @@ -0,0 +1,319 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v50; + +import java.nio.charset.StandardCharsets; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.util.List; +import java.util.Map; +import org.apache.commons.dbutils.DbUtils; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class FeedFileSourcesTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedFileSourcesTest.class, "schema.sql"); + + private static final long NOW = 1414770242000L; + + FeedFileSources migration; + + System2 system; + + @Before + public void setUp() { + db.executeUpdateSql("truncate table metrics"); + db.executeUpdateSql("truncate table snapshots"); + db.executeUpdateSql("truncate table snapshot_sources"); + db.executeUpdateSql("truncate table projects"); + db.executeUpdateSql("truncate table project_measures"); + db.executeUpdateSql("truncate table file_sources"); + + system = mock(System2.class); + when(system.now()).thenReturn(NOW); + migration = new FeedFileSources(db.database(), system); + } + + @Test + public void migrate_empty_db() throws Exception { + migration.execute(); + } + + @Test + public void migrate_sources_with_no_scm_no_coverage() throws Exception { + db.prepareDbUnit(getClass(), "before.xml"); + + db.executeUpdateSql("insert into snapshot_sources " + + "(snapshot_id, data, updated_at) " + + "values " + + "(6, 'class Foo {\r\n // Empty\r\n}\r\n', '2014-10-31 16:44:02.000')"); + + db.executeUpdateSql("insert into snapshot_sources " + + "(snapshot_id, data, updated_at) " + + "values " + + "(7, '', '2014-10-31 16:44:02.000')"); + + migration.execute(); + + List<Map<String, Object>> results = db.select("select project_uuid as \"projectUuid\", file_uuid as \"fileUuid\", created_at as \"createdAt\", " + + "updated_at as \"updatedAt\", data as \"data\", data as \"data\", line_hashes as \"lineHashes\", data_hash as \"dataHash\" from file_sources"); + assertThat(results).hasSize(2); + + assertThat(results.get(0).get("projectUuid")).isEqualTo("uuid-MyProject"); + assertThat(results.get(0).get("fileUuid")).isEqualTo("uuid-Migrated.xoo"); + assertThat(results.get(0).get("data")).isEqualTo(""); + assertThat(results.get(0).get("lineHashes")).isEqualTo(""); + assertThat(results.get(0).get("dataHash")).isEqualTo(""); + assertThat(results.get(0).get("updatedAt")).isEqualTo(NOW); + assertThat(results.get(0).get("createdAt")).isEqualTo(1416238020000L); + + assertThat(results.get(1).get("projectUuid")).isEqualTo("uuid-MyProject"); + assertThat(results.get(1).get("fileUuid")).isEqualTo("uuid-MyFile.xoo"); + assertThat(results.get(1).get("data")).isEqualTo(",,,,,,,,,,,,,,,class Foo {\r\n,,,,,,,,,,,,,,, // Empty\r\n,,,,,,,,,,,,,,,}\r\n,,,,,,,,,,,,,,,\r\n"); + assertThat(results.get(1).get("lineHashes")).isEqualTo("6a19ce786467960a3a9b0d26383a464a\naab2dbc5fdeaa80b050b1d049ede357c\ncbb184dd8e05c9709e5dcaedaa0495cf\n\n"); + assertThat(results.get(1).get("dataHash")).isEqualTo(""); + assertThat(formatLongDate((long) results.get(1).get("updatedAt")).toString()).startsWith("2014-10-31"); + assertThat(results.get(1).get("createdAt")).isEqualTo(NOW); + } + + @Test + public void migrate_sources_with_scm_and_coverage_in_text_value() throws Exception { + migrate_sources_with_scm_and_coverage_in("text_value"); + } + + @Test + public void migrate_sources_with_scm_and_coverage_in_measure_data() throws Exception { + migrate_sources_with_scm_and_coverage_in("measure_data"); + } + + private void migrate_sources_with_scm_and_coverage_in(String columnName) throws Exception { + db.prepareDbUnit(getClass(), "before.xml"); + + Connection connection = null; + try { + connection = db.openConnection(); + + connection.prepareStatement("insert into snapshot_sources " + + "(snapshot_id, data, updated_at) " + + "values " + + "(6, 'class Foo {\r\n // Empty\r\n}\r\n', '2014-10-31 16:44:02.000')") + .executeUpdate(); + + db.executeUpdateSql("insert into snapshot_sources " + + "(snapshot_id, data, updated_at) " + + "values " + + "(7, '', '2014-10-31 16:44:02.000')"); + + PreparedStatement revisionStmt = connection.prepareStatement("insert into project_measures " + + "(metric_id, snapshot_id, " + columnName + ") " + + "values " + + "(1, 6, ?)"); + revisionStmt.setBytes(1, "1=aef12a;2=abe465;3=afb789;4=afb789".getBytes(StandardCharsets.UTF_8)); + revisionStmt.executeUpdate(); + + PreparedStatement authorStmt = connection.prepareStatement("insert into project_measures " + + "(metric_id, snapshot_id, " + columnName + ") " + + "values " + + "(2, 6, ?)"); + authorStmt.setBytes(1, "1=alice;2=bob;3=carol;4=carol".getBytes(StandardCharsets.UTF_8)); + authorStmt.executeUpdate(); + + PreparedStatement dateStmt = connection.prepareStatement("insert into project_measures " + + "(metric_id, snapshot_id, " + columnName + ") " + + "values " + + "(3, 6, ?)"); + dateStmt.setBytes(1, "1=2014-04-25T12:34:56+0100;2=2014-07-25T12:34:56+0100;3=2014-03-23T12:34:56+0100;4=2014-03-23T12:34:56+0100".getBytes(StandardCharsets.UTF_8)); + dateStmt.executeUpdate(); + + PreparedStatement utHitsStmt = connection.prepareStatement("insert into project_measures " + + "(metric_id, snapshot_id, " + columnName + ") " + + "values " + + "(4, 6, ?)"); + utHitsStmt.setBytes(1, "1=1;3=0".getBytes(StandardCharsets.UTF_8)); + utHitsStmt.executeUpdate(); + + PreparedStatement utCondStmt = connection.prepareStatement("insert into project_measures " + + "(metric_id, snapshot_id, " + columnName + ") " + + "values " + + "(5, 6, ?)"); + utCondStmt.setBytes(1, "1=4".getBytes(StandardCharsets.UTF_8)); + utCondStmt.executeUpdate(); + + PreparedStatement utCoveredCondStmt = connection.prepareStatement("insert into project_measures " + + "(metric_id, snapshot_id, " + columnName + ") " + + "values " + + "(6, 6, ?)"); + utCoveredCondStmt.setBytes(1, "1=2".getBytes(StandardCharsets.UTF_8)); + utCoveredCondStmt.executeUpdate(); + + PreparedStatement itHitsStmt = connection.prepareStatement("insert into project_measures " + + "(metric_id, snapshot_id, " + columnName + ") " + + "values " + + "(7, 6, ?)"); + itHitsStmt.setBytes(1, "1=2;3=0".getBytes(StandardCharsets.UTF_8)); + itHitsStmt.executeUpdate(); + + PreparedStatement itCondStmt = connection.prepareStatement("insert into project_measures " + + "(metric_id, snapshot_id, " + columnName + ") " + + "values " + + "(8, 6, ?)"); + itCondStmt.setBytes(1, "1=5".getBytes(StandardCharsets.UTF_8)); + itCondStmt.executeUpdate(); + + PreparedStatement itCoveredCondStmt = connection.prepareStatement("insert into project_measures " + + "(metric_id, snapshot_id, " + columnName + ") " + + "values " + + "(9, 6, ?)"); + itCoveredCondStmt.setBytes(1, "1=3".getBytes(StandardCharsets.UTF_8)); + itCoveredCondStmt.executeUpdate(); + + PreparedStatement overallHitsStmt = connection.prepareStatement("insert into project_measures " + + "(metric_id, snapshot_id, " + columnName + ") " + + "values " + + "(10, 6, ?)"); + overallHitsStmt.setBytes(1, "1=3;3=0".getBytes(StandardCharsets.UTF_8)); + overallHitsStmt.executeUpdate(); + + PreparedStatement overallCondStmt = connection.prepareStatement("insert into project_measures " + + "(metric_id, snapshot_id, " + columnName + ") " + + "values " + + "(11, 6, ?)"); + overallCondStmt.setBytes(1, "1=6".getBytes(StandardCharsets.UTF_8)); + overallCondStmt.executeUpdate(); + + PreparedStatement overallCoveredCondStmt = connection.prepareStatement("insert into project_measures " + + "(metric_id, snapshot_id, " + columnName + ") " + + "values " + + "(12, 6, ?)"); + overallCoveredCondStmt.setBytes(1, "1=4".getBytes(StandardCharsets.UTF_8)); + overallCoveredCondStmt.executeUpdate(); + + PreparedStatement duplicationDataStmt = connection.prepareStatement("insert into project_measures " + + "(metric_id, snapshot_id, " + columnName + ") " + + "values " + + "(13, 6, ?)"); + duplicationDataStmt + .setBytes( + 1, + "<duplications><g><b s=\"1\" l=\"1\" r=\"MyProject:src/main/xoo/prj/MyFile.xoo\"/><b s=\"2\" l=\"1\" r=\"MyProject:src/main/xoo/prj/MyFile.xoo\"/><b s=\"3\" l=\"1\" r=\"MyProject:src/main/xoo/prj/AnotherFile.xoo\"/></g></duplications>" + .getBytes(StandardCharsets.UTF_8)); + duplicationDataStmt.executeUpdate(); + } finally { + DbUtils.commitAndCloseQuietly(connection); + } + + migration.execute(); + + List<Map<String, Object>> results = db.select("select project_uuid as \"projectUuid\", file_uuid as \"fileUuid\", created_at as \"createdAt\", " + + "updated_at as \"updatedAt\", data as \"data\", data as \"data\", line_hashes as \"lineHashes\", data_hash as \"dataHash\" from file_sources"); + assertThat(results).hasSize(2); + + assertThat(results.get(0).get("projectUuid")).isEqualTo("uuid-MyProject"); + assertThat(results.get(0).get("fileUuid")).isEqualTo("uuid-Migrated.xoo"); + assertThat(results.get(0).get("data")).isEqualTo(""); + assertThat(results.get(0).get("lineHashes")).isEqualTo(""); + assertThat(results.get(0).get("dataHash")).isEqualTo(""); + assertThat(results.get(0).get("updatedAt")).isEqualTo(NOW); + assertThat(results.get(0).get("createdAt")).isEqualTo(1416238020000L); + + assertThat(results.get(1).get("projectUuid")).isEqualTo("uuid-MyProject"); + assertThat(results.get(1).get("fileUuid")).isEqualTo("uuid-MyFile.xoo"); + assertThat(results.get(1).get("data")).isEqualTo( + "aef12a,alice,2014-04-25T12:34:56+0100,1,4,2,2,5,3,3,6,4,,,1,class Foo {\r\nabe465,bob,2014-07-25T12:34:56+0100,,,,,,,,,,,,2, " + + "// Empty\r\nafb789,carol,2014-03-23T12:34:56+0100,0,,,0,,,0,,,,,,}\r\nafb789,carol,2014-03-23T12:34:56+0100,,,,,,,,,,,,,\r\n"); + assertThat(results.get(1).get("lineHashes")).isEqualTo("6a19ce786467960a3a9b0d26383a464a\naab2dbc5fdeaa80b050b1d049ede357c\ncbb184dd8e05c9709e5dcaedaa0495cf\n\n"); + assertThat(results.get(1).get("dataHash")).isEqualTo(""); + assertThat(formatLongDate((long) results.get(1).get("updatedAt")).toString()).startsWith("2014-10-31"); + assertThat(results.get(1).get("createdAt")).isEqualTo(NOW); + } + + @Test + public void migrate_sources_with_invalid_duplication() throws Exception { + db.prepareDbUnit(getClass(), "before.xml"); + + Connection connection = null; + try { + connection = db.openConnection(); + + connection.prepareStatement("insert into snapshot_sources " + + "(snapshot_id, data, updated_at) " + + "values " + + "(6, 'class Foo {\r\n // Empty\r\n}\r\n', '2014-10-31 16:44:02.000')") + .executeUpdate(); + + db.executeUpdateSql("insert into snapshot_sources " + + "(snapshot_id, data, updated_at) " + + "values " + + "(7, '', '2014-10-31 16:44:02.000')"); + + PreparedStatement duplicationDataStmt = connection.prepareStatement("insert into project_measures " + + "(metric_id, snapshot_id, text_value) " + + "values " + + "(13, 6, ?)"); + duplicationDataStmt + .setBytes( + 1, + "<duplications><g><b s=\"1\" l=\"1\" r=\"MyProject:src/main/xoo/prj/MyFile.xoo\"/><b s=\"2\" l=\"1\" r=\"MyProject:src/main/xoo/prj/MyFile.xoo\"/><b s=\"3\" l=\"1\" r=\"MyProject:src/main/xoo/prj/AnotherFile.xoo\"/" + .getBytes(StandardCharsets.UTF_8)); + duplicationDataStmt.executeUpdate(); + } finally { + DbUtils.commitAndCloseQuietly(connection); + } + + migration.execute(); + + // db.assertDbUnit(getClass(), "after-with-invalid-duplication.xml", "file_sources"); + + List<Map<String, Object>> results = db.select("select project_uuid as \"projectUuid\", file_uuid as \"fileUuid\", created_at as \"createdAt\", " + + "updated_at as \"updatedAt\", data as \"data\", data as \"data\", line_hashes as \"lineHashes\", data_hash as \"dataHash\" from file_sources"); + assertThat(results).hasSize(2); + + assertThat(results.get(0).get("projectUuid")).isEqualTo("uuid-MyProject"); + assertThat(results.get(0).get("fileUuid")).isEqualTo("uuid-Migrated.xoo"); + assertThat(results.get(0).get("data")).isEqualTo(""); + assertThat(results.get(0).get("lineHashes")).isEqualTo(""); + assertThat(results.get(0).get("dataHash")).isEqualTo(""); + assertThat(results.get(0).get("updatedAt")).isEqualTo(NOW); + assertThat(results.get(0).get("createdAt")).isEqualTo(1416238020000L); + + assertThat(results.get(1).get("projectUuid")).isEqualTo("uuid-MyProject"); + assertThat(results.get(1).get("fileUuid")).isEqualTo("uuid-MyFile.xoo"); + assertThat(results.get(1).get("data")).isEqualTo(",,,,,,,,,,,,,,,class Foo {\r\n,,,,,,,,,,,,,,, // Empty\r\n,,,,,,,,,,,,,,,}\r\n,,,,,,,,,,,,,,,\r\n"); + assertThat(results.get(1).get("lineHashes")).isEqualTo("6a19ce786467960a3a9b0d26383a464a\naab2dbc5fdeaa80b050b1d049ede357c\ncbb184dd8e05c9709e5dcaedaa0495cf\n\n"); + assertThat(results.get(1).get("dataHash")).isEqualTo(""); + assertThat(formatLongDate((long) results.get(1).get("updatedAt")).toString()).startsWith("2014-10-31"); + assertThat(results.get(1).get("createdAt")).isEqualTo(NOW); + } + + private String formatLongDate(long dateInMs) { + return DateUtils.formatDateTime(DateUtils.longToDate(dateInMs)); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v50/FeedIssueLongDatesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v50/FeedIssueLongDatesTest.java new file mode 100644 index 00000000000..5969a262803 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v50/FeedIssueLongDatesTest.java @@ -0,0 +1,51 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v50; + +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class FeedIssueLongDatesTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedIssueLongDatesTest.class, "schema.sql"); + + @Test + public void execute() throws Exception { + db.prepareDbUnit(getClass(), "before.xml"); + + System2 system = mock(System2.class); + when(system.now()).thenReturn(1500000000000L); + MigrationStep migration = new FeedIssueLongDates(db.database(), system); + migration.execute(); + + int count = db.countSql("select count(*) from issues where created_at_ms is not null and updated_at_ms is not null"); + assertThat(count).isEqualTo(3); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v50/FileSourceDtoTest.java b/sonar-db/src/test/java/org/sonar/db/version/v50/FileSourceDtoTest.java new file mode 100644 index 00000000000..ebb137512cd --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v50/FileSourceDtoTest.java @@ -0,0 +1,35 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v50; + +import org.junit.Test; +import org.sonar.db.version.v50.FileSourceDto; + +import static org.assertj.core.api.Assertions.assertThat; + +public class FileSourceDtoTest { + + @Test + public void checksumOfBlankLine() { + assertThat(FileSourceDto.lineChecksum("")).isEmpty(); + assertThat(FileSourceDto.lineChecksum(" \r\n")).isEmpty(); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest.java b/sonar-db/src/test/java/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest.java new file mode 100644 index 00000000000..4226635344a --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest.java @@ -0,0 +1,57 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v50; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class InsertProjectsAuthorizationUpdatedAtMigrationTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, InsertProjectsAuthorizationUpdatedAtMigrationTest.class, "schema.sql"); + + MigrationStep migration; + System2 system = mock(System2.class); + + @Before + public void setUp() { + db.executeUpdateSql("truncate table projects"); + migration = new InsertProjectsAuthorizationUpdatedAtMigrationStep(db.database(), system); + when(system.now()).thenReturn(123456789L); + } + + @Test + public void execute() throws Exception { + db.prepareDbUnit(getClass(), "before.xml"); + + migration.execute(); + + db.assertDbUnit(getClass(), "after.xml", "projects"); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest.java b/sonar-db/src/test/java/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest.java new file mode 100644 index 00000000000..4de215aae6f --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest.java @@ -0,0 +1,324 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v50; + +import com.google.common.collect.ImmutableSet; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbClient; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +import static org.assertj.core.api.Assertions.assertThat; + +public class PopulateProjectsUuidColumnsMigrationTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, PopulateProjectsUuidColumnsMigrationTest.class, "schema.sql"); + + DbClient dbClient = db.getDbClient(); + + Migration50Mapper mapper; + + MigrationStep migration; + + @Before + public void setUp() { + db.executeUpdateSql("truncate table projects"); + db.executeUpdateSql("truncate table snapshots"); + mapper = db.getSession().getMapper(Migration50Mapper.class); + migration = new PopulateProjectsUuidColumnsMigrationStep(dbClient); + } + + @Test + public void migrate_components() throws Exception { + db.prepareDbUnit(getClass(), "migrate_components.xml"); + + migration.execute(); + db.getSession().commit(); + + Component root = mapper.selectComponentByKey("org.struts:struts"); + assertThat(root.getUuid()).isNotNull(); + assertThat(root.getProjectUuid()).isEqualTo(root.getUuid()); + assertThat(root.getModuleUuid()).isNull(); + assertThat(root.getModuleUuidPath()).isEmpty(); + + Component module = mapper.selectComponentByKey("org.struts:struts-core"); + assertThat(module.getUuid()).isNotNull(); + assertThat(module.getProjectUuid()).isEqualTo(root.getUuid()); + assertThat(module.getModuleUuid()).isEqualTo(root.getUuid()); + assertThat(module.getModuleUuidPath()).isEqualTo(root.getUuid()); + + Component subModule = mapper.selectComponentByKey("org.struts:struts-db"); + assertThat(subModule.getUuid()).isNotNull(); + assertThat(subModule.getProjectUuid()).isEqualTo(root.getUuid()); + assertThat(subModule.getModuleUuid()).isEqualTo(module.getUuid()); + assertThat(subModule.getModuleUuidPath()).isEqualTo(root.getUuid() + "." + module.getUuid()); + + Component directory = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts"); + assertThat(directory.getUuid()).isNotNull(); + assertThat(directory.getProjectUuid()).isEqualTo(root.getUuid()); + assertThat(directory.getModuleUuid()).isEqualTo(subModule.getUuid()); + assertThat(directory.getModuleUuidPath()).isEqualTo(root.getUuid() + "." + module.getUuid() + "." + subModule.getUuid()); + + Component file = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts/RequestContext.java"); + assertThat(file.getUuid()).isNotNull(); + assertThat(file.getProjectUuid()).isEqualTo(root.getUuid()); + assertThat(file.getModuleUuid()).isEqualTo(subModule.getUuid()); + assertThat(file.getModuleUuidPath()).isEqualTo(root.getUuid() + "." + module.getUuid() + "." + subModule.getUuid()); + + // Verify that each generated uuid is unique + assertThat(ImmutableSet.of(root.getUuid(), module.getUuid(), subModule.getUuid(), directory.getUuid(), file.getUuid())).hasSize(5); + } + + @Test + public void not_migrate_already_migrated_components() throws Exception { + db.prepareDbUnit(getClass(), "not_migrate_already_migrated_components.xml"); + + migration.execute(); + db.getSession().commit(); + + Component root = mapper.selectComponentByKey("org.struts:struts"); + assertThat(root.getUuid()).isEqualTo("ABCD"); + assertThat(root.getProjectUuid()).isEqualTo("ABCD"); + assertThat(root.getModuleUuid()).isNull(); + assertThat(root.getModuleUuidPath()).isEmpty(); + + Component module = mapper.selectComponentByKey("org.struts:struts-core"); + assertThat(module.getUuid()).isEqualTo("BCDE"); + assertThat(module.getProjectUuid()).isEqualTo("ABCD"); + assertThat(module.getModuleUuid()).isEqualTo("ABCD"); + assertThat(module.getModuleUuidPath()).isEqualTo("ABCD"); + + Component subModule = mapper.selectComponentByKey("org.struts:struts-db"); + assertThat(subModule.getUuid()).isNotNull(); + assertThat(subModule.getProjectUuid()).isEqualTo("ABCD"); + assertThat(subModule.getModuleUuid()).isEqualTo("BCDE"); + assertThat(subModule.getModuleUuidPath()).isEqualTo("ABCD.BCDE"); + + Component directory = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts"); + assertThat(directory.getUuid()).isNotNull(); + assertThat(directory.getProjectUuid()).isEqualTo("ABCD"); + assertThat(directory.getModuleUuid()).isEqualTo(subModule.getUuid()); + assertThat(directory.getModuleUuidPath()).isEqualTo("ABCD.BCDE." + subModule.getUuid()); + + Component file = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts/RequestContext.java"); + assertThat(file.getUuid()).isNotNull(); + assertThat(file.getProjectUuid()).isEqualTo("ABCD"); + assertThat(file.getModuleUuid()).isEqualTo(subModule.getUuid()); + assertThat(file.getModuleUuidPath()).isEqualTo("ABCD.BCDE." + subModule.getUuid()); + + Component removedFile = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts/RequestContext2.java"); + assertThat(removedFile.getUuid()).isEqualTo("DCBA"); + assertThat(removedFile.getProjectUuid()).isEqualTo("ABCD"); + assertThat(removedFile.getModuleUuid()).isEqualTo("BCDE"); + assertThat(removedFile.getModuleUuidPath()).isEqualTo("ABCD.BCDE"); + } + + @Test + public void migrate_disable_components() throws Exception { + db.prepareDbUnit(getClass(), "migrate_disable_components.xml"); + + migration.execute(); + db.getSession().commit(); + + Component root = mapper.selectComponentByKey("org.struts:struts"); + assertThat(root.getUuid()).isNotNull(); + + Component module = mapper.selectComponentByKey("org.struts:struts-core"); + assertThat(module.getUuid()).isNotNull(); + assertThat(module.getProjectUuid()).isEqualTo(root.getUuid()); + // Module and module path will always be null for removed components + assertThat(module.getModuleUuid()).isNull(); + assertThat(module.getModuleUuidPath()).isEmpty(); + + Component subModule = mapper.selectComponentByKey("org.struts:struts-db"); + assertThat(subModule.getUuid()).isNotNull(); + assertThat(subModule.getProjectUuid()).isEqualTo(root.getUuid()); + // Module and module path will always be null for removed components + assertThat(subModule.getModuleUuid()).isNull(); + assertThat(subModule.getModuleUuidPath()).isEmpty(); + + Component directory = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts"); + assertThat(directory.getUuid()).isNotNull(); + assertThat(directory.getProjectUuid()).isEqualTo(root.getUuid()); + // Module and module path will always be null for removed components + assertThat(directory.getModuleUuid()).isNull(); + assertThat(directory.getModuleUuidPath()).isEmpty(); + + Component file = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts/RequestContext.java"); + assertThat(file.getUuid()).isNotNull(); + assertThat(file.getProjectUuid()).isEqualTo(root.getUuid()); + // Module and module path will always be null for removed components + assertThat(file.getModuleUuid()).isNull(); + assertThat(file.getModuleUuidPath()).isEmpty(); + } + + @Test + public void migrate_provisioned_project() throws Exception { + db.prepareDbUnit(getClass(), "migrate_provisioned_project.xml"); + + migration.execute(); + db.getSession().commit(); + + Component root = mapper.selectComponentByKey("org.struts:struts"); + assertThat(root.getUuid()).isNotNull(); + assertThat(root.getProjectUuid()).isEqualTo(root.getUuid()); + assertThat(root.getModuleUuid()).isNull(); + assertThat(root.getModuleUuidPath()).isEmpty(); + } + + @Test + public void migrate_library() throws Exception { + db.prepareDbUnit(getClass(), "migrate_library.xml"); + + migration.execute(); + db.getSession().commit(); + + Component root = mapper.selectComponentByKey("org.hamcrest:hamcrest-library"); + assertThat(root.getUuid()).isNotNull(); + assertThat(root.getProjectUuid()).isEqualTo(root.getUuid()); + assertThat(root.getModuleUuid()).isNull(); + assertThat(root.getModuleUuidPath()).isEmpty(); + } + + @Test + public void migrate_view() throws Exception { + db.prepareDbUnit(getClass(), "migrate_view.xml"); + + migration.execute(); + db.getSession().commit(); + + Component view = mapper.selectComponentByKey("view"); + assertThat(view.getUuid()).isNotNull(); + assertThat(view.getProjectUuid()).isEqualTo(view.getUuid()); + assertThat(view.getModuleUuid()).isNull(); + assertThat(view.getModuleUuidPath()).isEmpty(); + + Component subView = mapper.selectComponentByKey("subView"); + assertThat(subView.getUuid()).isNotNull(); + assertThat(subView.getProjectUuid()).isEqualTo(view.getUuid()); + assertThat(subView.getModuleUuid()).isEqualTo(view.getUuid()); + assertThat(subView.getModuleUuidPath()).isEqualTo(view.getUuid()); + + Component techProject = mapper.selectComponentByKey("vieworg.struts:struts"); + assertThat(techProject.getUuid()).isNotNull(); + assertThat(techProject.getProjectUuid()).isEqualTo(view.getUuid()); + assertThat(techProject.getModuleUuid()).isEqualTo(subView.getUuid()); + assertThat(techProject.getModuleUuidPath()).isEqualTo(view.getUuid() + "." + subView.getUuid()); + } + + @Test + public void migrate_developer() throws Exception { + db.prepareDbUnit(getClass(), "migrate_developer.xml"); + + migration.execute(); + db.getSession().commit(); + + Component dev = mapper.selectComponentByKey("DEV:developer@company.net"); + assertThat(dev.getUuid()).isNotNull(); + assertThat(dev.getProjectUuid()).isEqualTo(dev.getUuid()); + assertThat(dev.getModuleUuid()).isNull(); + assertThat(dev.getModuleUuidPath()).isEmpty(); + + Component techDev = mapper.selectComponentByKey("DEV:developer@company.net:org.struts:struts"); + assertThat(techDev.getUuid()).isNotNull(); + assertThat(techDev.getProjectUuid()).isEqualTo(dev.getUuid()); + assertThat(techDev.getModuleUuid()).isEqualTo(dev.getUuid()); + assertThat(techDev.getModuleUuidPath()).isEqualTo(dev.getUuid()); + } + + @Test + public void migrate_components_without_uuid() throws Exception { + db.prepareDbUnit(getClass(), "migrate_components_without_uuid.xml"); + + migration.execute(); + db.getSession().commit(); + + // Root project migrated + Component root = mapper.selectComponentByKey("org.struts:struts"); + assertThat(root.getUuid()).isNotNull(); + assertThat(root.getProjectUuid()).isEqualTo(root.getUuid()); + assertThat(root.getModuleUuid()).isNull(); + assertThat(root.getModuleUuidPath()).isEmpty(); + + // Module with a snapshot having no islast=true + Component module = mapper.selectComponentByKey("org.struts:struts-core"); + assertThat(module.getUuid()).isNotNull(); + assertThat(module.getProjectUuid()).isEqualTo(module.getUuid()); + assertThat(module.getModuleUuid()).isNull(); + assertThat(module.getModuleUuidPath()).isEmpty(); + + // File linked on a no more existing project + Component file = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts/RequestContext.java"); + assertThat(file.getUuid()).isNotNull(); + assertThat(file.getProjectUuid()).isEqualTo(file.getUuid()); + assertThat(file.getModuleUuid()).isNull(); + assertThat(file.getModuleUuidPath()).isEmpty(); + } + + @Test + public void not_fail_when_module_has_no_root_id() throws Exception { + db.prepareDbUnit(getClass(), "not_fail_when_module_has_no_root_id.xml"); + + migration.execute(); + db.getSession().commit(); + + // Root project migrated + Component root = mapper.selectComponentByKey("org.struts:struts"); + assertThat(root.getUuid()).isNotNull(); + assertThat(root.getProjectUuid()).isEqualTo(root.getUuid()); + assertThat(root.getModuleUuid()).isNull(); + assertThat(root.getModuleUuidPath()).isEmpty(); + + // The module without uuid will be migrated as a standalone component + Component module = mapper.selectComponentByKey("org.struts:struts-core"); + assertThat(module.getUuid()).isNotNull(); + assertThat(module.getProjectUuid()).isEqualTo(module.getUuid()); + assertThat(module.getModuleUuid()).isNull(); + assertThat(module.getModuleUuidPath()).isEmpty(); + } + + @Test + public void not_fail_when_project_has_two_active_snapshots() throws Exception { + db.prepareDbUnit(getClass(), "not_fail_when_project_has_two_active_snapshots.xml"); + + migration.execute(); + db.getSession().commit(); + + // Root project migrated + Component root = mapper.selectComponentByKey("org.struts:struts"); + assertThat(root.getUuid()).isNotNull(); + assertThat(root.getProjectUuid()).isEqualTo(root.getUuid()); + assertThat(root.getModuleUuid()).isNull(); + assertThat(root.getModuleUuidPath()).isEmpty(); + + // The module linked on second active snapshot should be migrated a standalone component + Component module = mapper.selectComponentByKey("org.struts:struts-core"); + assertThat(module.getUuid()).isNotNull(); + assertThat(module.getProjectUuid()).isEqualTo(module.getUuid()); + assertThat(module.getModuleUuid()).isNull(); + assertThat(module.getModuleUuidPath()).isEmpty(); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest.java b/sonar-db/src/test/java/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest.java new file mode 100644 index 00000000000..bf96e3af226 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest.java @@ -0,0 +1,56 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v50; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class RemoveSortFieldFromIssueFiltersMigrationTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, RemoveSortFieldFromIssueFiltersMigrationTest.class, "schema.sql"); + + MigrationStep migration; + System2 system = mock(System2.class); + + @Before + public void setUp() { + db.executeUpdateSql("truncate table issue_filters"); + migration = new RemoveSortFieldFromIssueFiltersMigrationStep(db.database(), system); + when(system.now()).thenReturn(DateUtils.parseDate("2014-10-29").getTime()); + } + + @Test + public void execute() throws Exception { + db.prepareDbUnit(getClass(), "execute.xml"); + + migration.execute(); + + db.assertDbUnit(getClass(), "execute-result.xml", "issue_filters"); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest.java b/sonar-db/src/test/java/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest.java new file mode 100644 index 00000000000..e51c5fd2b32 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest.java @@ -0,0 +1,66 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v50; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class ReplaceIssueFiltersProjectKeyByUuidTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, ReplaceIssueFiltersProjectKeyByUuidTest.class, "schema.sql"); + + MigrationStep migration; + System2 system = mock(System2.class); + + @Before + public void setUp() { + db.executeUpdateSql("truncate table issue_filters"); + migration = new ReplaceIssueFiltersProjectKeyByUuid(db.database(), system); + when(system.now()).thenReturn(DateUtils.parseDate("2014-10-29").getTime()); + } + + @Test + public void execute() throws Exception { + db.prepareDbUnit(getClass(), "execute.xml"); + + migration.execute(); + + db.assertDbUnit(getClass(), "execute-result.xml", "issue_filters"); + } + + @Test + public void do_not_execute_if_already_migrated() throws Exception { + db.prepareDbUnit(getClass(), "do_not_execute_if_already_migrated.xml"); + + migration.execute(); + + db.assertDbUnit(getClass(), "do_not_execute_if_already_migrated-result.xml", "issue_filters"); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/AddIssuesColumnsTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/AddIssuesColumnsTest.java new file mode 100644 index 00000000000..40683d1ebb4 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v51/AddIssuesColumnsTest.java @@ -0,0 +1,54 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import java.sql.Types; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +public class AddIssuesColumnsTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, AddIssuesColumnsTest.class, "schema.sql"); + + MigrationStep migration; + + @Before + public void setUp() { + migration = new AddIssuesColumns(db.database()); + } + + @Test + public void update_columns() throws Exception { + migration.execute(); + + db.assertColumnDefinition("issues", "issue_creation_date_ms", Types.BIGINT, null); + db.assertColumnDefinition("issues", "issue_update_date_ms", Types.BIGINT, null); + db.assertColumnDefinition("issues", "issue_close_date_ms", Types.BIGINT, null); + db.assertColumnDefinition("issues", "tags", Types.VARCHAR, 4000); + db.assertColumnDefinition("issues", "component_uuid", Types.VARCHAR, 50); + db.assertColumnDefinition("issues", "project_uuid", Types.VARCHAR, 50); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/AddNewCharacteristicsTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/AddNewCharacteristicsTest.java new file mode 100644 index 00000000000..cfc43d2246d --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v51/AddNewCharacteristicsTest.java @@ -0,0 +1,138 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.MessageException; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +import static junit.framework.TestCase.fail; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class AddNewCharacteristicsTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, AddNewCharacteristicsTest.class, "schema.sql"); + + MigrationStep migration; + + System2 system = mock(System2.class); + + @Before + public void setUp() { + db.executeUpdateSql("truncate table characteristics"); + + when(system.now()).thenReturn(DateUtils.parseDate("2015-02-15").getTime()); + + migration = new AddNewCharacteristics(db.database(), system); + } + + @Test + public void migrate() throws Exception { + db.prepareDbUnit(getClass(), "migrate.xml"); + migration.execute(); + db.assertDbUnit(getClass(), "migrate-result.xml", "characteristics"); + } + + @Test + public void do_nothing_when_already_migrated() throws Exception { + db.prepareDbUnit(getClass(), "do_nothing_when_already_migrated.xml"); + migration.execute(); + db.assertDbUnit(getClass(), "do_nothing_when_already_migrated.xml", "characteristics"); + } + + @Test + public void do_nothing_when_no_characteristics() throws Exception { + db.prepareDbUnit(getClass(), "empty.xml"); + migration.execute(); + assertThat(db.countRowsOfTable("characteristics")).isEqualTo(0); + } + + @Test + public void insert_usability_at_the_top_if_security_does_exists() throws Exception { + db.prepareDbUnit(getClass(), "insert_usability_at_the_top_if_security_does_exists.xml"); + migration.execute(); + db.assertDbUnit(getClass(), "insert_usability_at_the_top_if_security_does_exists-result.xml", "characteristics"); + } + + @Test + public void update_usability_order_if_already_exists() throws Exception { + db.prepareDbUnit(getClass(), "update_usability_if_already_exists.xml"); + migration.execute(); + db.assertDbUnit(getClass(), "update_usability_if_already_exists-result.xml", "characteristics"); + } + + @Test + public void fail_if_usability_exists_as_sub_characteristic() { + db.prepareDbUnit(getClass(), "fail_if_usability_exists_as_sub_characteristic.xml"); + + try { + migration.execute(); + fail(); + } catch (Exception e) { + assertThat(e).isInstanceOf(MessageException.class).hasMessage( + "'Usability' must be a characteristic. Please restore your DB backup, start the previous version of SonarQube " + + "and update your SQALE model to fix this issue before trying again to run the migration."); + } + } + + @Test + public void fail_if_compliance_already_exists_as_characteristic() { + db.prepareDbUnit(getClass(), "fail_if_compliance_already_exists_as_characteristic.xml"); + + try { + migration.execute(); + fail(); + } catch (Exception e) { + assertThat(e).isInstanceOf(MessageException.class).hasMessage( + "'Compliance' must be a sub-characteristic. Please restore your DB backup, start the previous version of SonarQube " + + "and update your SQALE model to fix this issue before trying again to run the migration."); + } + } + + @Test + public void fail_if_compliance_already_exists_under_wrong_characteristic() { + db.prepareDbUnit(getClass(), "fail_if_compliance_already_exists_under_wrong_characteristic.xml"); + + try { + migration.execute(); + fail(); + } catch (Exception e) { + assertThat(e).isInstanceOf(MessageException.class).hasMessage( + "'Reusability Compliance' must be defined under 'Reusability'. Please restore your DB backup, start the previous version of SonarQube " + + "and update your SQALE model to fix this issue before trying again to run the migration."); + } + } + + @Test + public void not_fail_if_some_deprecated_requirements_still_exists_in_db() throws Exception { + db.prepareDbUnit(getClass(), "not_fail_if_some_deprecated_requirements_still_exists_in_db.xml"); + migration.execute(); + db.assertDbUnit(getClass(), "not_fail_if_some_deprecated_requirements_still_exists_in_db.xml", "characteristics"); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest.java new file mode 100644 index 00000000000..c0345ad2862 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest.java @@ -0,0 +1,102 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import java.util.Map; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.user.UserDto; +import org.sonar.db.version.MigrationStep; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class CopyScmAccountsFromAuthorsToUsersTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, CopyScmAccountsFromAuthorsToUsersTest.class, "schema.sql"); + + MigrationStep migration; + System2 system = mock(System2.class); + + @Before + public void setUp() { + db.executeUpdateSql("truncate table authors"); + db.executeUpdateSql("truncate table users"); + migration = new CopyScmAccountsFromAuthorsToUsers(db.database(), system); + } + + @Test + public void migrate() throws Exception { + db.prepareDbUnit(getClass(), "before.xml"); + Long oldDate = 1500000000000L; + Long updatedDate = 2000000000000L; + when(system.now()).thenReturn(updatedDate); + + migration.execute(); + + User simon = getUserByLogin("simon"); + assertThat(simon.scmAccounts).isEqualTo(UserDto.SCM_ACCOUNTS_SEPARATOR + "Simon B" + UserDto.SCM_ACCOUNTS_SEPARATOR + "simon@codehaus.org" + UserDto.SCM_ACCOUNTS_SEPARATOR); + assertThat(simon.updatedAt).isEqualTo(updatedDate); + + User fabrice = getUserByLogin("fabrice"); + assertThat(fabrice.scmAccounts).isEqualTo(UserDto.SCM_ACCOUNTS_SEPARATOR + "fab" + UserDto.SCM_ACCOUNTS_SEPARATOR); + assertThat(fabrice.updatedAt).isEqualTo(updatedDate); + + assertThat(getUserByLogin("julien").updatedAt).isEqualTo(oldDate); + assertThat(getUserByLogin("jb").updatedAt).isEqualTo(oldDate); + assertThat(getUserByLogin("disable").updatedAt).isEqualTo(oldDate); + assertThat(getUserByLogin("teryk").updatedAt).isEqualTo(oldDate); + assertThat(getUserByLogin("teryk2").updatedAt).isEqualTo(oldDate); + } + + @Test + public void nothing_to_migrate_when_no_authors() throws Exception { + db.prepareDbUnit(getClass(), "no_authors.xml"); + Long oldDate = 1500000000000L; + Long updatedDate = 2000000000000L; + when(system.now()).thenReturn(updatedDate); + + migration.execute(); + + assertThat(db.countSql("SELECT count(*) FROM USERS WHERE updated_at=" + updatedDate)).isEqualTo(0); + assertThat(db.countSql("SELECT count(*) FROM USERS WHERE updated_at=" + oldDate)).isEqualTo(7); + } + + private User getUserByLogin(String login) { + return new User(db.selectFirst("SELECT u.scm_Accounts as \"scmAccounts\", u.updated_at as \"updatedAt\" FROM users u WHERE u.login='" + login + "'")); + } + + private static class User { + String scmAccounts; + Long updatedAt; + + User(Map<String, Object> map) { + scmAccounts = (String) map.get("scmAccounts"); + updatedAt = (Long) map.get("updatedAt"); + } + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/DropIssuesColumnsTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/DropIssuesColumnsTest.java new file mode 100644 index 00000000000..3971e9c1838 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v51/DropIssuesColumnsTest.java @@ -0,0 +1,52 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import org.junit.Before; +import org.junit.Test; +import org.sonar.db.Database; +import org.sonar.db.dialect.PostgreSql; +import org.sonar.db.version.v51.DropIssuesColumns; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class DropIssuesColumnsTest { + + DropIssuesColumns migration; + + Database database; + + @Before + public void setUp() { + database = mock(Database.class); + migration = new DropIssuesColumns(database); + } + + @Test + public void generate_sql_on_postgresql() { + when(database.getDialect()).thenReturn(new PostgreSql()); + assertThat(migration.generateSql()).isEqualTo( + "ALTER TABLE issues DROP COLUMN issue_creation_date, DROP COLUMN issue_update_date, DROP COLUMN issue_close_date, DROP COLUMN component_id, DROP COLUMN root_component_id" + ); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest.java new file mode 100644 index 00000000000..c3e75f1fc75 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest.java @@ -0,0 +1,53 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class FeedAnalysisReportsLongDatesTest { + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedAnalysisReportsLongDatesTest.class, "schema.sql"); + + @Test + public void execute() throws Exception { + db.prepareDbUnit(getClass(), "before.xml"); + + System2 system = mock(System2.class); + when(system.now()).thenReturn(1500000000000L); + MigrationStep migration = new FeedAnalysisReportsLongDates(db.database(), system); + migration.execute(); + + int count = db.countSql("select count(*) from analysis_reports where created_at_ms is not null and updated_at_ms is not null"); + assertThat(count).isEqualTo(3); + + int countWithAllDateFieldsNull = db + .countSql("select count(*) from analysis_reports where created_at_ms is not null and updated_at_ms is not null and started_at_ms is not null and finished_at_ms is not null"); + assertThat(countWithAllDateFieldsNull).isEqualTo(2); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedEventsLongDatesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedEventsLongDatesTest.java new file mode 100644 index 00000000000..96104aee886 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedEventsLongDatesTest.java @@ -0,0 +1,88 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.api.utils.DateUtils.parseDate; + +public class FeedEventsLongDatesTest { + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedEventsLongDatesTest.class, "schema.sql"); + + @Before + public void before() { + db.prepareDbUnit(getClass(), "before.xml"); + } + + @Test + public void execute() throws Exception { + MigrationStep migration = newMigration(System2.INSTANCE); + + migration.execute(); + + int count = db + .countSql("select count(*) from events where " + + "created_at_ms is not null " + + "and event_date_ms is not null"); + assertThat(count).isEqualTo(3); + } + + @Test + public void take_now_if_date_in_the_future() throws Exception { + System2 system = mock(System2.class); + when(system.now()).thenReturn(1234L); + + MigrationStep migration = newMigration(system); + + migration.execute(); + + int count = db + .countSql("select count(*) from events where " + + "created_at_ms = 1234"); + assertThat(count).isEqualTo(2); + } + + @Test + public void take_date_if_in_the_past() throws Exception { + MigrationStep migration = newMigration(System2.INSTANCE); + + migration.execute(); + + long time = parseDate("2014-09-25").getTime(); + int count = db + .countSql("select count(*) from events where " + + "created_at_ms=" + time); + assertThat(count).isEqualTo(1); + } + + private MigrationStep newMigration(System2 system) { + return new FeedEventsLongDates(db.database(), system); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest.java new file mode 100644 index 00000000000..2bf3bc23004 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest.java @@ -0,0 +1,97 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import java.io.InputStream; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import org.apache.commons.dbutils.DbUtils; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.source.FileSourceDto; +import org.sonar.db.version.MigrationStep; +import org.sonar.server.source.db.FileSourceDb; + +import static org.assertj.core.api.Assertions.assertThat; + +public class FeedFileSourcesBinaryDataTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedFileSourcesBinaryDataTest.class, "schema.sql"); + + @Test + public void convert_csv_to_protobuf() throws Exception { + db.prepareDbUnit(getClass(), "data.xml"); + + MigrationStep migration = new FeedFileSourcesBinaryData(db.database()); + migration.execute(); + + int count = db.countSql("select count(*) from file_sources where binary_data is not null"); + assertThat(count).isEqualTo(3); + + try (Connection connection = db.openConnection()) { + FileSourceDb.Data data = selectData(connection, 1L); + assertThat(data.getLinesCount()).isEqualTo(4); + assertThat(data.getLines(0).getScmRevision()).isEqualTo("aef12a"); + + data = selectData(connection, 2L); + assertThat(data.getLinesCount()).isEqualTo(4); + assertThat(data.getLines(0).hasScmRevision()).isFalse(); + + data = selectData(connection, 3L); + assertThat(data.getLinesCount()).isEqualTo(0); + } + } + + @Test + public void fail_to_parse_csv() throws Exception { + db.prepareDbUnit(getClass(), "bad_data.xml"); + + MigrationStep migration = new FeedFileSourcesBinaryData(db.database()); + + thrown.expect(IllegalStateException.class); + thrown.expectMessage("Error during processing of row: [id=1,data="); + + migration.execute(); + } + + private FileSourceDb.Data selectData(Connection connection, long fileSourceId) throws SQLException { + PreparedStatement pstmt = connection.prepareStatement("select binary_data from file_sources where id=?"); + ResultSet rs = null; + try { + pstmt.setLong(1, fileSourceId); + rs = pstmt.executeQuery(); + rs.next(); + InputStream data = rs.getBinaryStream(1); + return FileSourceDto.decodeSourceData(data); + } finally { + DbUtils.closeQuietly(rs); + DbUtils.closeQuietly(pstmt); + } + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest.java new file mode 100644 index 00000000000..01690ce52df --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest.java @@ -0,0 +1,53 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class FeedIssueChangesLongDatesTest { + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedIssueChangesLongDatesTest.class, "schema.sql"); + + @Test + public void execute() throws Exception { + db.prepareDbUnit(getClass(), "before.xml"); + + System2 system = mock(System2.class); + when(system.now()).thenReturn(1500000000000L); + MigrationStep migration = new FeedIssueChangesLongDates(db.database(), system); + migration.execute(); + + int count = db.countSql("select count(*) from issue_changes where created_at_ms is not null and updated_at_ms is not null"); + assertThat(count).isEqualTo(3); + + int countWithAllDateFieldsNull = db + .countSql("select count(*) from issue_changes where created_at_ms is not null and updated_at_ms is not null and issue_change_creation_date_ms is not null"); + assertThat(countWithAllDateFieldsNull).isEqualTo(2); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueComponentUuidsTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueComponentUuidsTest.java new file mode 100644 index 00000000000..de5f1c94c05 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueComponentUuidsTest.java @@ -0,0 +1,53 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; + +public class FeedIssueComponentUuidsTest { + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedIssueComponentUuidsTest.class, "schema.sql"); + + FeedIssueComponentUuids underTest; + + @Before + public void setUp() { + db.truncateTables(); + + underTest = new FeedIssueComponentUuids(db.database()); + } + + @Test + public void migrate_empty_db() throws Exception { + underTest.execute(); + } + + @Test + public void migrate() throws Exception { + db.prepareDbUnit(this.getClass(), "before.xml"); + underTest.execute(); + db.assertDbUnit(this.getClass(), "after-result.xml", "issues"); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueTagsTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueTagsTest.java new file mode 100644 index 00000000000..1e630545f94 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueTagsTest.java @@ -0,0 +1,64 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import java.util.Date; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class FeedIssueTagsTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedIssueTagsTest.class, "schema.sql"); + + FeedIssueTags migration; + + System2 system; + + @Before + public void setUp() { + db.executeUpdateSql("truncate table rules"); + db.executeUpdateSql("truncate table issues"); + + system = mock(System2.class); + Date now = DateUtils.parseDateTime("2014-12-08T17:33:00+0100"); + when(system.now()).thenReturn(now.getTime()); + migration = new FeedIssueTags(db.database(), system); + } + + @Test + public void migrate_empty_db() throws Exception { + migration.execute(); + } + + @Test + public void migrate_with_rule_tags() throws Exception { + db.prepareDbUnit(this.getClass(), "before.xml"); + migration.execute(); + db.assertDbUnit(this.getClass(), "after-result.xml", "issues"); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssuesLongDatesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssuesLongDatesTest.java new file mode 100644 index 00000000000..b10df31cb5d --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssuesLongDatesTest.java @@ -0,0 +1,81 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.api.utils.DateUtils.parseDate; + +public class FeedIssuesLongDatesTest { + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedIssuesLongDatesTest.class, "schema.sql"); + + @Test + public void execute() throws Exception { + db.prepareDbUnit(getClass(), "before.xml"); + + MigrationStep migration = new FeedIssuesLongDates(db.database(), System2.INSTANCE); + migration.execute(); + + int count = db + .countSql("select count(*) from issues where " + + "issue_creation_date_ms is not null " + + "and issue_update_date_ms is not null " + + "and issue_close_date_ms is not null"); + assertThat(count).isEqualTo(2); + } + + @Test + public void take_now_if_date_in_the_future() throws Exception { + db.prepareDbUnit(getClass(), "before.xml"); + System2 system2 = mock(System2.class); + when(system2.now()).thenReturn(0L); + + MigrationStep migration = new FeedIssuesLongDates(db.database(), mock(System2.class)); + migration.execute(); + + int count = db + .countSql("select count(*) from issues where " + + "issue_creation_date_ms = 0"); + assertThat(count).isEqualTo(1); + } + + @Test + public void take_snapshot_date_if_in_the_past() throws Exception { + db.prepareDbUnit(getClass(), "before.xml"); + long snapshotTime = parseDate("2014-09-25").getTime(); + + MigrationStep migration = new FeedIssuesLongDates(db.database(), System2.INSTANCE); + migration.execute(); + + int count = db + .countSql("select count(*) from issues where " + + "issue_creation_date_ms=" + snapshotTime); + assertThat(count).isEqualTo(1); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest.java new file mode 100644 index 00000000000..2b4f3f5facb --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest.java @@ -0,0 +1,88 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.api.utils.DateUtils.parseDate; + +public class FeedManualMeasuresLongDatesTest { + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedManualMeasuresLongDatesTest.class, "schema.sql"); + + @Before + public void before() { + db.prepareDbUnit(getClass(), "before.xml"); + } + + @Test + public void execute() throws Exception { + MigrationStep migration = newMigration(System2.INSTANCE); + + migration.execute(); + + int count = db + .countSql("select count(*) from manual_measures where " + + "created_at_ms is not null " + + "and updated_at_ms is not null"); + assertThat(count).isEqualTo(2); + } + + @Test + public void take_now_if_date_in_the_future() throws Exception { + System2 system = mock(System2.class); + when(system.now()).thenReturn(1234L); + + MigrationStep migration = newMigration(system); + + migration.execute(); + + int count = db + .countSql("select count(*) from manual_measures where " + + "created_at_ms = 1234"); + assertThat(count).isEqualTo(1); + } + + @Test + public void take_manual_measure_date_if_in_the_past() throws Exception { + MigrationStep migration = newMigration(System2.INSTANCE); + + migration.execute(); + + long snapshotTime = parseDate("2014-09-25").getTime(); + int count = db + .countSql("select count(*) from manual_measures where " + + "created_at_ms=" + snapshotTime); + assertThat(count).isEqualTo(1); + } + + private MigrationStep newMigration(System2 system) { + return new FeedManualMeasuresLongDates(db.database(), system); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest.java new file mode 100644 index 00000000000..8eeb8bb588b --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest.java @@ -0,0 +1,84 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.api.utils.DateUtils.parseDate; + +public class FeedSnapshotsLongDatesTest { + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedSnapshotsLongDatesTest.class, "schema.sql"); + + @Test + public void execute() throws Exception { + db.prepareDbUnit(getClass(), "before.xml"); + + MigrationStep migration = new FeedSnapshotsLongDates(db.database(), System2.INSTANCE); + migration.execute(); + + int count = db + .countSql("select count(*) from snapshots where created_at_ms is not null " + + "and build_date_ms is not null " + + "and period1_date_ms is not null " + + "and period2_date_ms is not null " + + "and period3_date_ms is not null " + + "and period4_date_ms is not null " + + "and period5_date_ms is not null"); + assertThat(count).isEqualTo(2); + } + + @Test + public void take_now_if_date_in_the_future() throws Exception { + db.prepareDbUnit(getClass(), "before.xml"); + System2 system2 = mock(System2.class); + when(system2.now()).thenReturn(0L); + + MigrationStep migration = new FeedSnapshotsLongDates(db.database(), mock(System2.class)); + migration.execute(); + + int count = db + .countSql("select count(*) from snapshots where " + + "created_at_ms = 0"); + assertThat(count).isEqualTo(1); + } + + @Test + public void take_snapshot_date_if_in_the_past() throws Exception { + db.prepareDbUnit(getClass(), "before.xml"); + long snapshotTime = parseDate("2014-09-25").getTime(); + + MigrationStep migration = new FeedSnapshotsLongDates(db.database(), System2.INSTANCE); + migration.execute(); + + int count = db + .countSql("select count(*) from snapshots where " + + "created_at_ms=" + snapshotTime); + assertThat(count).isEqualTo(1); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedUsersLongDatesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedUsersLongDatesTest.java new file mode 100644 index 00000000000..88923fbcb6e --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedUsersLongDatesTest.java @@ -0,0 +1,51 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class FeedUsersLongDatesTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedUsersLongDatesTest.class, "schema.sql"); + + @Test + public void execute() throws Exception { + db.prepareDbUnit(getClass(), "before.xml"); + + System2 system = mock(System2.class); + when(system.now()).thenReturn(1500000000000L); + MigrationStep migration = new FeedUsersLongDates(db.database(), system); + migration.execute(); + + int count = db.countSql("select count(*) from users where created_at_ms is not null and updated_at_ms is not null"); + assertThat(count).isEqualTo(3); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest.java new file mode 100644 index 00000000000..3b41af6846e --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest.java @@ -0,0 +1,59 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +public class RemovePermissionsOnModulesMigrationTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, RemovePermissionsOnModulesMigrationTest.class, "schema.sql"); + + MigrationStep migration; + + @Before + public void setUp() { + migration = new RemovePermissionsOnModulesMigrationStep(db.database()); + } + + @Test + public void execute() throws Exception { + db.prepareDbUnit(getClass(), "migrate.xml"); + + migration.execute(); + + db.assertDbUnit(getClass(), "migrate-result.xml", "user_roles", "group_roles"); + } + + @Test + public void nothing_to_do_when_already_migrated() throws Exception { + db.prepareDbUnit(getClass(), "nothing_to_do_when_already_migrated.xml"); + + migration.execute(); + + db.assertDbUnit(getClass(), "nothing_to_do_when_already_migrated.xml", "user_roles", "group_roles"); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest.java new file mode 100644 index 00000000000..b2ecde9fa88 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest.java @@ -0,0 +1,56 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class RenameComponentRelatedParamsInIssueFiltersMigrationTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, RenameComponentRelatedParamsInIssueFiltersMigrationTest.class, "schema.sql"); + + MigrationStep migration; + System2 system = mock(System2.class); + + @Before + public void setUp() { + db.executeUpdateSql("truncate table issue_filters"); + migration = new RenameComponentRelatedParamsInIssueFilters(db.database(), system); + when(system.now()).thenReturn(DateUtils.parseDate("2014-10-29").getTime()); + } + + @Test + public void execute() throws Exception { + db.prepareDbUnit(getClass(), "execute.xml"); + + migration.execute(); + + db.assertDbUnit(getClass(), "execute-result.xml", "issue_filters"); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest.java new file mode 100644 index 00000000000..89a8d7e6c7d --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest.java @@ -0,0 +1,65 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v51; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +public class UpdateProjectsModuleUuidPathTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, UpdateProjectsModuleUuidPathTest.class, "schema.sql"); + + MigrationStep migration; + + System2 system; + + @Before + public void setUp() { + db.executeUpdateSql("truncate table projects"); + + migration = new UpdateProjectsModuleUuidPath(db.database()); + } + + @Test + public void migrate_empty_db() throws Exception { + migration.execute(); + } + + @Test + public void migrate() throws Exception { + db.prepareDbUnit(this.getClass(), "migrate_components.xml"); + migration.execute(); + db.assertDbUnit(this.getClass(), "migrate_components-result.xml", "projects"); + } + + @Test + public void not_migrate_already_migrated_components() throws Exception { + db.prepareDbUnit(this.getClass(), "not_migrate_already_migrated_components.xml"); + migration.execute(); + db.assertDbUnit(this.getClass(), "not_migrate_already_migrated_components.xml", "projects"); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/AddManualMeasuresComponentUuidColumnTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/AddManualMeasuresComponentUuidColumnTest.java new file mode 100644 index 00000000000..07f48d9a144 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v52/AddManualMeasuresComponentUuidColumnTest.java @@ -0,0 +1,49 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import java.sql.Types; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; + +public class AddManualMeasuresComponentUuidColumnTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, AddManualMeasuresComponentUuidColumnTest.class, "schema.sql"); + + AddManualMeasuresComponentUuidColumn underTest; + + @Before + public void setUp() { + underTest = new AddManualMeasuresComponentUuidColumn(db.database()); + } + + @Test + public void update_columns() throws Exception { + underTest.execute(); + + db.assertColumnDefinition("manual_measures", "component_uuid", Types.VARCHAR, 50); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/FeedEventsComponentUuidTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedEventsComponentUuidTest.java new file mode 100644 index 00000000000..87f156d39be --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedEventsComponentUuidTest.java @@ -0,0 +1,64 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +public class FeedEventsComponentUuidTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedEventsComponentUuidTest.class, "schema.sql"); + + MigrationStep migration; + + @Before + public void setUp() { + db.executeUpdateSql("truncate table events"); + db.executeUpdateSql("truncate table projects"); + + migration = new FeedEventsComponentUuid(db.database()); + } + + @Test + public void migrate_empty_db() throws Exception { + migration.execute(); + } + + @Test + public void migrate() throws Exception { + db.prepareDbUnit(this.getClass(), "migrate.xml"); + migration.execute(); + db.assertDbUnit(this.getClass(), "migrate-result.xml", "events"); + } + + @Test + public void not_migrate_already_migrated_data() throws Exception { + db.prepareDbUnit(this.getClass(), "not_migrate_already_migrated_data.xml"); + migration.execute(); + db.assertDbUnit(this.getClass(), "not_migrate_already_migrated_data.xml", "events"); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest.java new file mode 100644 index 00000000000..615a41ba117 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest.java @@ -0,0 +1,55 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +public class FeedFileSourcesDataTypeTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedFileSourcesDataTypeTest.class, "schema.sql"); + + MigrationStep migration; + + @Before + public void setUp() { + db.executeUpdateSql("truncate table file_sources"); + + migration = new FeedFileSourcesDataType(db.database()); + } + + @Test + public void migrate_empty_db() throws Exception { + migration.execute(); + } + + @Test + public void migrate() throws Exception { + db.prepareDbUnit(this.getClass(), "migrate.xml"); + migration.execute(); + db.assertDbUnit(this.getClass(), "migrate-result.xml", "file_sources"); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest.java new file mode 100644 index 00000000000..cf76d6a4430 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest.java @@ -0,0 +1,55 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; + +public class FeedManualMeasuresComponentUuidTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedManualMeasuresComponentUuidTest.class, "schema.sql"); + + FeedManualMeasuresComponentUuid underTest; + + @Before + public void setUp() { + db.executeUpdateSql("truncate table manual_measures"); + db.executeUpdateSql("truncate table projects"); + + underTest = new FeedManualMeasuresComponentUuid(db.database()); + } + + @Test + public void migrate_empty_db() throws Exception { + underTest.execute(); + } + + @Test + public void migrate() throws Exception { + db.prepareDbUnit(this.getClass(), "migrate.xml"); + underTest.execute(); + db.assertDbUnit(this.getClass(), "migrate-result.xml", "manual_measures"); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/FeedMetricsBooleansTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedMetricsBooleansTest.java new file mode 100644 index 00000000000..b565f04dd34 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedMetricsBooleansTest.java @@ -0,0 +1,54 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +public class FeedMetricsBooleansTest { + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedMetricsBooleansTest.class, "schema.sql"); + + MigrationStep migration; + + @Before + public void setUp() { + db.executeUpdateSql("truncate table metrics"); + + migration = new FeedMetricsBooleans(db.database()); + } + + @Test + public void migrate_empty_db() throws Exception { + migration.execute(); + } + + @Test + public void migrate() throws Exception { + db.prepareDbUnit(this.getClass(), "migrate.xml"); + migration.execute(); + db.assertDbUnit(this.getClass(), "migrate-result.xml", "metrics"); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest.java new file mode 100644 index 00000000000..4487d000614 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest.java @@ -0,0 +1,63 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +public class FeedProjectLinksComponentUuidTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedProjectLinksComponentUuidTest.class, "schema.sql"); + + MigrationStep migration; + + @Before + public void setUp() { + db.executeUpdateSql("truncate table project_links"); + + migration = new FeedProjectLinksComponentUuid(db.database()); + } + + @Test + public void migrate_empty_db() throws Exception { + migration.execute(); + } + + @Test + public void migrate() throws Exception { + db.prepareDbUnit(this.getClass(), "migrate.xml"); + migration.execute(); + db.assertDbUnit(this.getClass(), "migrate-result.xml", "project_links"); + } + + @Test + public void not_migrate_already_migrated_data() throws Exception { + db.prepareDbUnit(this.getClass(), "not_migrate_already_migrated_data.xml"); + migration.execute(); + db.assertDbUnit(this.getClass(), "not_migrate_already_migrated_data.xml", "project_links"); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/MoveProjectProfileAssociationTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/MoveProjectProfileAssociationTest.java new file mode 100644 index 00000000000..982859c34ae --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v52/MoveProjectProfileAssociationTest.java @@ -0,0 +1,66 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +public class MoveProjectProfileAssociationTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, MoveProjectProfileAssociationTest.class, "schema.sql"); + + MigrationStep migration; + + @Before + public void setUp() { + db.executeUpdateSql("truncate table projects"); + db.executeUpdateSql("truncate table project_qprofiles"); + db.executeUpdateSql("truncate table properties"); + db.executeUpdateSql("truncate table rules_profiles"); + + migration = new MoveProjectProfileAssociation(db.database()); + } + + @Test + public void migrate_empty_db() throws Exception { + migration.execute(); + } + + @Test + public void migrate() throws Exception { + db.prepareDbUnit(this.getClass(), "migrate.xml"); + migration.execute(); + db.assertDbUnit(this.getClass(), "migrate-result.xml", "rules_profiles", "project_qprofiles"); + } + + @Test + public void not_migrate_already_migrated_data() throws Exception { + db.prepareDbUnit(this.getClass(), "migrate-result.xml"); + migration.execute(); + db.assertDbUnit(this.getClass(), "migrate-result.xml", "rules_profiles", "project_qprofiles"); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/RemoveComponentLibrariesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/RemoveComponentLibrariesTest.java new file mode 100644 index 00000000000..fa1d876f5af --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v52/RemoveComponentLibrariesTest.java @@ -0,0 +1,56 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +public class RemoveComponentLibrariesTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, RemoveComponentLibrariesTest.class, "schema.sql"); + + MigrationStep migration; + + @Before + public void setUp() { + db.executeUpdateSql("truncate table projects"); + + migration = new RemoveComponentLibraries(db.database()); + } + + @Test + public void migrate_empty_db() throws Exception { + migration.execute(); + } + + @Test + public void remove_libraries() throws Exception { + db.prepareDbUnit(this.getClass(), "remove_libraries.xml"); + migration.execute(); + db.assertDbUnit(this.getClass(), "remove_libraries-result.xml", "projects"); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest.java new file mode 100644 index 00000000000..79d5b1511ab --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest.java @@ -0,0 +1,78 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +public class RemoveDuplicatedComponentKeysTest { + + @ClassRule + public static DbTester db = DbTester.createForSchema(System2.INSTANCE, RemoveDuplicatedComponentKeysTest.class, "schema.sql"); + + MigrationStep migration; + + @Before + public void setUp() { + db.executeUpdateSql("truncate table projects"); + db.executeUpdateSql("truncate table issues"); + + migration = new RemoveDuplicatedComponentKeys(db.database()); + } + + @Test + public void migrate_empty_db() throws Exception { + migration.execute(); + } + + @Test + public void migrate_components_and_issues() throws Exception { + db.prepareDbUnit(this.getClass(), "migrate.xml"); + migration.execute(); + db.assertDbUnit(this.getClass(), "migrate-result.xml", "projects", "issues"); + } + + @Test + public void not_migrate_components_and_issues_already_migrated() throws Exception { + db.prepareDbUnit(this.getClass(), "migrate-result.xml"); + migration.execute(); + db.assertDbUnit(this.getClass(), "migrate-result.xml", "projects", "issues"); + } + + @Test + public void keep_enable_component_when_enabled_component_exists() throws Exception { + db.prepareDbUnit(this.getClass(), "keep_enable_component.xml"); + migration.execute(); + db.assertDbUnit(this.getClass(), "keep_enable_component-result.xml", "projects"); + } + + @Test + public void keep_last_component_when_no_enabled_components() throws Exception { + db.prepareDbUnit(this.getClass(), "keep_last_component.xml"); + migration.execute(); + db.assertDbUnit(this.getClass(), "keep_last_component-result.xml", "projects"); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest.java new file mode 100644 index 00000000000..c9163a6c702 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest.java @@ -0,0 +1,56 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.version.v52; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.version.MigrationStep; + +public class RemoveSnapshotLibrariesTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, RemoveSnapshotLibrariesTest.class, "schema.sql"); + + MigrationStep migration; + + @Before + public void setUp() { + db.executeUpdateSql("truncate table snapshots"); + + migration = new RemoveSnapshotLibraries(db.database()); + } + + @Test + public void migrate_empty_db() throws Exception { + migration.execute(); + } + + @Test + public void remove_libraries() throws Exception { + db.prepareDbUnit(this.getClass(), "remove_libraries.xml"); + migration.execute(); + db.assertDbUnit(this.getClass(), "remove_libraries-result.xml", "snapshots"); + } + +} diff --git a/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/batch-insert-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/batch-insert-result.xml new file mode 100644 index 00000000000..96ecbf4062f --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/batch-insert-result.xml @@ -0,0 +1,8 @@ +<dataset> + <persons id="1" login="barbara" age="56" enabled="[false]" coeff="1.5" updated_at="2014-01-25"/> + <persons id="2" login="emmerik" age="14" enabled="[true]" coeff="5.2" updated_at="2014-01-25"/> + <persons id="3" login="morgan" age="3" enabled="[true]" coeff="5.4" updated_at="2014-01-25"/> + + <persons id="10" login="kurt" age="27" enabled="[true]" coeff="2.2" updated_at="[null]"/> + <persons id="11" login="courtney" age="25" enabled="[false]" coeff="2.3" updated_at="[null]"/> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/insert-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/insert-result.xml new file mode 100644 index 00000000000..32b7ac03f06 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/insert-result.xml @@ -0,0 +1,7 @@ +<dataset> + <persons id="1" login="barbara" age="56" enabled="[false]" coeff="1.5" updated_at="2014-01-25"/> + <persons id="2" login="emmerik" age="14" enabled="[true]" coeff="5.2" updated_at="2014-01-25"/> + <persons id="3" login="morgan" age="3" enabled="[true]" coeff="5.4" updated_at="2014-01-25"/> + + <persons id="10" login="kurt" age="27" enabled="[true]" coeff="2.2" updated_at="[null]"/> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/mass-update-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/mass-update-result.xml new file mode 100644 index 00000000000..9eb2317febf --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/mass-update-result.xml @@ -0,0 +1,5 @@ +<dataset> + <persons id="1" login="barbara" age="56" enabled="[false]" coeff="1.5" updated_at="2014-01-25"/> + <persons id="2" login="login2" age="12" enabled="[true]" coeff="5.2" updated_at="2014-01-25"/> + <persons id="3" login="login3" age="13" enabled="[true]" coeff="5.4" updated_at="2014-01-25"/> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/persons.xml b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/persons.xml new file mode 100644 index 00000000000..62c226d53b7 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/persons.xml @@ -0,0 +1,5 @@ +<dataset> + <persons id="1" login="barbara" age="56" enabled="[false]" coeff="1.5" updated_at="2014-01-25"/> + <persons id="2" login="emmerik" age="14" enabled="[true]" coeff="5.2" updated_at="2014-01-25"/> + <persons id="3" login="morgan" age="3" enabled="[true]" coeff="5.4" updated_at="2014-01-25"/> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/schema.sql new file mode 100644 index 00000000000..499b25b599d --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/schema.sql @@ -0,0 +1,8 @@ +CREATE TABLE "PERSONS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "LOGIN" VARCHAR(50), + "AGE" INTEGER, + "ENABLED" BOOLEAN, + "UPDATED_AT" TIMESTAMP, + "COEFF" DOUBLE +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/scroll-and-update-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/scroll-and-update-result.xml new file mode 100644 index 00000000000..0cf4e593d4d --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/scroll-and-update-result.xml @@ -0,0 +1,5 @@ +<dataset> + <persons id="1" login="login1" age="11" enabled="[false]" coeff="1.5" updated_at="2014-01-25"/> + <persons id="2" login="login2" age="12" enabled="[true]" coeff="5.2" updated_at="2014-01-25"/> + <persons id="3" login="login3" age="13" enabled="[true]" coeff="5.4" updated_at="2014-01-25"/> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/update-null-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/update-null-result.xml new file mode 100644 index 00000000000..ec48c899b40 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/update-null-result.xml @@ -0,0 +1,5 @@ +<dataset> + <persons id="1" login="barbara" age="56" enabled="[false]" coeff="1.5" updated_at="2014-01-25"/> + <persons id="2" login="[null]" age="[null]" enabled="[null]" coeff="[null]" updated_at="[null]"/> + <persons id="3" login="morgan" age="3" enabled="[true]" coeff="5.4" updated_at="2014-01-25"/> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/after.xml b/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/after.xml new file mode 100644 index 00000000000..bb36c83c788 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/after.xml @@ -0,0 +1,20 @@ +<dataset> + <!-- with default value --> + <rules_parameters id="1" rule_id="10" name="max" param_type="INT" default_value="10" description="[null]"/> + + <!-- without default value, to be ignored --> + <rules_parameters id="2" rule_id="10" name="min" param_type="INT" default_value="[null]" description="[null]"/> + + <!-- this active rule has all parameters --> + <active_rules id="100" profile_id="1000" rule_id="10" failure_level="3" inheritance="[null]" + created_at="2012-01-01" updated_at="2012-01-01"/> + <active_rule_parameters id="10000" active_rule_id="100" rules_parameter_id="1" rules_parameter_key="max" value="9"/> + <active_rule_parameters id="10001" active_rule_id="100" rules_parameter_id="2" rules_parameter_key="min" value="4"/> + + <!-- this active rule does not have parameters. UPDATED_AT CHANGED --> + <active_rules id="101" profile_id="1000" rule_id="10" failure_level="3" inheritance="[null]" + created_at="2012-01-01" updated_at="2014-04-28"/> + + <!-- newly created --> + <active_rule_parameters id="10002" active_rule_id="101" rules_parameter_id="1" rules_parameter_key="max" value="10"/> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/before.xml new file mode 100644 index 00000000000..df5d8fa0bbd --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/before.xml @@ -0,0 +1,17 @@ +<dataset> + <!-- with default value --> + <rules_parameters id="1" rule_id="10" name="max" param_type="INT" default_value="10" description="[null]"/> + + <!-- without default value, to be ignored --> + <rules_parameters id="2" rule_id="10" name="min" param_type="INT" default_value="[null]" description="[null]"/> + + <!-- this active rule has all parameters --> + <active_rules id="100" profile_id="1000" rule_id="10" failure_level="3" inheritance="[null]" + created_at="2012-01-01" updated_at="2012-01-01"/> + <active_rule_parameters id="10000" active_rule_id="100" rules_parameter_id="1" rules_parameter_key="max" value="9"/> + <active_rule_parameters id="10001" active_rule_id="100" rules_parameter_id="2" rules_parameter_key="min" value="4"/> + + <!-- this active rule does not have parameters --> + <active_rules id="101" profile_id="1000" rule_id="10" failure_level="3" inheritance="[null]" + created_at="2012-01-01" updated_at="2012-01-01"/> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/no_changes.xml b/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/no_changes.xml new file mode 100644 index 00000000000..fdd7750955e --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/no_changes.xml @@ -0,0 +1,11 @@ +<dataset> + <!-- with default value --> + <rules_parameters id="1" rule_id="10" name="max" param_type="INT" default_value="10" description="[null]"/> + + <!-- this active rule has all parameters --> + <active_rules id="100" profile_id="1000" rule_id="10" failure_level="3" inheritance="[null]" + created_at="2012-01-01" updated_at="2012-01-01"/> + <active_rule_parameters id="10000" active_rule_id="100" rules_parameter_id="1" rules_parameter_key="max" value="9"/> + <active_rule_parameters id="10001" active_rule_id="100" rules_parameter_id="2" rules_parameter_key="min" value="4"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/schema.sql new file mode 100644 index 00000000000..ebb574482c3 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/schema.sql @@ -0,0 +1,28 @@ +CREATE TABLE "RULES_PARAMETERS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "RULE_ID" INTEGER NOT NULL, + "NAME" VARCHAR(128) NOT NULL, + "PARAM_TYPE" VARCHAR(512) NOT NULL, + "DEFAULT_VALUE" VARCHAR(4000), + "DESCRIPTION" VARCHAR(4000) +); + + +CREATE TABLE "ACTIVE_RULES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "PROFILE_ID" INTEGER NOT NULL, + "RULE_ID" INTEGER NOT NULL, + "FAILURE_LEVEL" INTEGER NOT NULL, + "INHERITANCE" VARCHAR(10), + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP +); + + +CREATE TABLE "ACTIVE_RULE_PARAMETERS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "ACTIVE_RULE_ID" INTEGER NOT NULL, + "RULES_PARAMETER_ID" INTEGER NOT NULL, + "RULES_PARAMETER_KEY" VARCHAR(128), + "VALUE" VARCHAR(4000) +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v45/DeleteMeasuresOnDeletedProfilesMigrationTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v45/DeleteMeasuresOnDeletedProfilesMigrationTest/before.xml new file mode 100644 index 00000000000..14e559f4a12 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v45/DeleteMeasuresOnDeletedProfilesMigrationTest/before.xml @@ -0,0 +1,34 @@ +<dataset> + <metrics id="1" name="quality_profiles" VAL_TYPE="DATA" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="[true]" worst_value="0" optimized_best_value="[true]" best_value="100" direction="1" + hidden="[false]" delete_historical_data="[null]"/> + + <!-- old format, references a numeric value which is profile id --> + <project_measures id="1" VALUE="60" METRIC_ID="1" SNAPSHOT_ID="1001" alert_text="[null]" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" + url="[null]" + variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" + variation_value_4="[null]" variation_value_5="[null]"/> + + <!-- new format, json data --> + <project_measures id="2" VALUE="[null]" text_value="{json}" METRIC_ID="1" SNAPSHOT_ID="1001" alert_text="[null]" + RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" + url="[null]" + variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" + variation_value_4="[null]" variation_value_5="[null]"/> + + <!-- last snapshot --> + <snapshots purge_status="[null]" id="1001" project_id="1" parent_snapshot_id="[null]" root_project_id="1" + root_snapshot_id="[null]" + scope="PRJ" qualifier="TRK" created_at="2009-11-01 13:58:00.00" build_date="2009-11-01 13:58:00.00" + version="[null]" path="" + status="P" islast="[true]" depth="0" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" + period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" + period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" + period5_date="[null]"/> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v45/DeleteMeasuresOnDeletedProfilesMigrationTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v45/DeleteMeasuresOnDeletedProfilesMigrationTest/schema.sql new file mode 100644 index 00000000000..912fd080b0d --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v45/DeleteMeasuresOnDeletedProfilesMigrationTest/schema.sql @@ -0,0 +1,77 @@ +CREATE TABLE "PROJECT_MEASURES" ( + "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "VALUE" DOUBLE, + "METRIC_ID" INTEGER NOT NULL, + "SNAPSHOT_ID" INTEGER, + "RULE_ID" INTEGER, + "RULES_CATEGORY_ID" INTEGER, + "TEXT_VALUE" VARCHAR(4000), + "TENDENCY" INTEGER, + "MEASURE_DATE" TIMESTAMP, + "PROJECT_ID" INTEGER, + "ALERT_STATUS" VARCHAR(5), + "ALERT_TEXT" VARCHAR(4000), + "URL" VARCHAR(2000), + "DESCRIPTION" VARCHAR(4000), + "RULE_PRIORITY" INTEGER, + "CHARACTERISTIC_ID" INTEGER, + "PERSON_ID" INTEGER, + "VARIATION_VALUE_1" DOUBLE, + "VARIATION_VALUE_2" DOUBLE, + "VARIATION_VALUE_3" DOUBLE, + "VARIATION_VALUE_4" DOUBLE, + "VARIATION_VALUE_5" DOUBLE, + "MEASURE_DATA" BINARY(167772150) +); + +CREATE TABLE "METRICS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "NAME" VARCHAR(64) NOT NULL, + "DESCRIPTION" VARCHAR(255), + "DIRECTION" INTEGER NOT NULL DEFAULT 0, + "DOMAIN" VARCHAR(64), + "SHORT_NAME" VARCHAR(64), + "QUALITATIVE" BOOLEAN NOT NULL DEFAULT FALSE, + "VAL_TYPE" VARCHAR(8), + "USER_MANAGED" BOOLEAN DEFAULT FALSE, + "ENABLED" BOOLEAN DEFAULT TRUE, + "ORIGIN" VARCHAR(3), + "WORST_VALUE" DOUBLE, + "BEST_VALUE" DOUBLE, + "OPTIMIZED_BEST_VALUE" BOOLEAN, + "HIDDEN" BOOLEAN, + "DELETE_HISTORICAL_DATA" BOOLEAN +); + +CREATE TABLE "SNAPSHOTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "CREATED_AT" TIMESTAMP, + "BUILD_DATE" TIMESTAMP, + "PROJECT_ID" INTEGER NOT NULL, + "PARENT_SNAPSHOT_ID" INTEGER, + "STATUS" VARCHAR(4) NOT NULL DEFAULT 'U', + "PURGE_STATUS" INTEGER, + "ISLAST" BOOLEAN NOT NULL DEFAULT FALSE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10), + "ROOT_SNAPSHOT_ID" INTEGER, + "VERSION" VARCHAR(500), + "PATH" VARCHAR(500), + "DEPTH" INTEGER, + "ROOT_PROJECT_ID" INTEGER, + "PERIOD1_MODE" VARCHAR(100), + "PERIOD1_PARAM" VARCHAR(100), + "PERIOD1_DATE" TIMESTAMP, + "PERIOD2_MODE" VARCHAR(100), + "PERIOD2_PARAM" VARCHAR(100), + "PERIOD2_DATE" TIMESTAMP, + "PERIOD3_MODE" VARCHAR(100), + "PERIOD3_PARAM" VARCHAR(100), + "PERIOD3_DATE" TIMESTAMP, + "PERIOD4_MODE" VARCHAR(100), + "PERIOD4_PARAM" VARCHAR(100), + "PERIOD4_DATE" TIMESTAMP, + "PERIOD5_MODE" VARCHAR(100), + "PERIOD5_PARAM" VARCHAR(100), + "PERIOD5_DATE" TIMESTAMP +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute-result.xml new file mode 100644 index 00000000000..0e6a35407d8 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute-result.xml @@ -0,0 +1,35 @@ +<dataset> + + <!-- Template rule --> + <rules id="1" plugin_rule_key="ArchitecturalConstraint" plugin_name="xoo" name="Architectural constraint" + description="Architectural constraint" status="READY" priority="1" language="xoo" + note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]" + description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]" + characteristic_id="[null]" default_characteristic_id="[null]" + remediation_function="[null]" default_remediation_function="[null]" + remediation_coeff="[null]" default_remediation_coeff="[null]" + remediation_offset="[null]" default_remediation_offset="[null]" + effort_to_fix_description="[null]" + is_template="[true]" template_id="[null]" created_at="2014-01-01" updated_at="2014-01-01"/> + <rules_parameters id="1" rule_id="1" name="max" param_type="INT" default_value="10" description="[null]"/> + <rules_parameters id="2" rule_id="1" name="format" param_type="STRING" default_value="txt" description="[null]"/> + <rules_parameters id="3" rule_id="1" name="type" param_type="STRING" default_value="[null]" description="[null]"/> + <rules_parameters id="4" rule_id="1" name="param" param_type="STRING" default_value="" description="[null]"/> + + <!-- Custom rule, 2 parameters should be added --> + <rules id="2" plugin_rule_key="ArchitecturalConstraint_2" plugin_name="xoo" name="Architectural constraint 2" + description="Architectural constraint 2" status="READY" priority="1" language="xoo" + note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]" + description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]" + characteristic_id="[null]" default_characteristic_id="[null]" + remediation_function="[null]" default_remediation_function="[null]" + remediation_coeff="[null]" default_remediation_coeff="[null]" + remediation_offset="[null]" default_remediation_offset="[null]" + effort_to_fix_description="[null]" + is_template="[false]" template_id="1" created_at="2014-01-01" updated_at="2014-10-09"/> + <rules_parameters id="5" rule_id="2" name="max" param_type="INT" default_value="10" description="[null]"/> + <rules_parameters id="6" rule_id="2" name="format" param_type="STRING" default_value="csv" description="[null]"/> + <rules_parameters id="7" rule_id="2" name="type" param_type="STRING" default_value="[null]" description="[null]"/> + <rules_parameters id="8" rule_id="2" name="param" param_type="STRING" default_value="[null]" description="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute.xml b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute.xml new file mode 100644 index 00000000000..a951abd43de --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute.xml @@ -0,0 +1,33 @@ +<dataset> + + <!-- Template rule --> + <rules id="1" plugin_rule_key="ArchitecturalConstraint" plugin_name="xoo" name="Architectural constraint" + description="Architectural constraint" status="READY" priority="1" language="xoo" + note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]" + description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]" + characteristic_id="[null]" default_characteristic_id="[null]" + remediation_function="[null]" default_remediation_function="[null]" + remediation_coeff="[null]" default_remediation_coeff="[null]" + remediation_offset="[null]" default_remediation_offset="[null]" + effort_to_fix_description="[null]" + is_template="[true]" template_id="[null]" created_at="2014-01-01" updated_at="2014-01-01"/> + <rules_parameters id="1" rule_id="1" name="max" param_type="INT" default_value="10" description="[null]"/> + <rules_parameters id="2" rule_id="1" name="format" param_type="STRING" default_value="txt" description="[null]"/> + <rules_parameters id="3" rule_id="1" name="type" param_type="STRING" default_value="[null]" description="[null]"/> + <rules_parameters id="4" rule_id="1" name="param" param_type="STRING" default_value="" description="[null]"/> + + <!-- Custom rule, 2 parameters are existing, 2 parameters should be added --> + <rules id="2" plugin_rule_key="ArchitecturalConstraint_2" plugin_name="xoo" name="Architectural constraint 2" + description="Architectural constraint 2" status="READY" priority="1" language="xoo" + note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]" + description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]" + characteristic_id="[null]" default_characteristic_id="[null]" + remediation_function="[null]" default_remediation_function="[null]" + remediation_coeff="[null]" default_remediation_coeff="[null]" + remediation_offset="[null]" default_remediation_offset="[null]" + effort_to_fix_description="[null]" + is_template="[false]" template_id="1" created_at="2014-01-01" updated_at="2014-01-01"/> + <rules_parameters id="5" rule_id="2" name="max" param_type="INT" default_value="10" description="[null]"/> + <rules_parameters id="6" rule_id="2" name="format" param_type="STRING" default_value="csv" description="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter-result.xml new file mode 100644 index 00000000000..ae74ca8fbe3 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter-result.xml @@ -0,0 +1,35 @@ +<dataset> + + <!-- Template rule --> + <rules id="1" plugin_rule_key="ArchitecturalConstraint" plugin_name="xoo" name="Architectural constraint" + description="Architectural constraint" status="READY" priority="1" language="xoo" + note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]" + description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]" + characteristic_id="[null]" default_characteristic_id="[null]" + remediation_function="[null]" default_remediation_function="[null]" + remediation_coeff="[null]" default_remediation_coeff="[null]" + remediation_offset="[null]" default_remediation_offset="[null]" + effort_to_fix_description="[null]" + is_template="[true]" template_id="[null]" created_at="2014-01-01" updated_at="2014-01-01"/> + <rules_parameters id="1" rule_id="1" name="max" param_type="INT" default_value="10" description="[null]"/> + <rules_parameters id="2" rule_id="1" name="format" param_type="STRING" default_value="txt" description="[null]"/> + <rules_parameters id="3" rule_id="1" name="type" param_type="STRING" default_value="[null]" description="[null]"/> + <rules_parameters id="4" rule_id="1" name="param" param_type="STRING" default_value="" description="[null]"/> + + <!-- Custom rule, 0 parameter are existing, 4 parameters should be added --> + <rules id="3" plugin_rule_key="ArchitecturalConstraint_3" plugin_name="xoo" name="Architectural constraint 3" + description="Architectural constraint 3" status="READY" priority="1" language="xoo" + note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]" + description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]" + characteristic_id="[null]" default_characteristic_id="[null]" + remediation_function="[null]" default_remediation_function="[null]" + remediation_coeff="[null]" default_remediation_coeff="[null]" + remediation_offset="[null]" default_remediation_offset="[null]" + effort_to_fix_description="[null]" + is_template="[false]" template_id="1" created_at="2014-01-01" updated_at="2014-10-09"/> + <rules_parameters id="5" rule_id="3" name="max" param_type="INT" default_value="[null]" description="[null]"/> + <rules_parameters id="6" rule_id="3" name="format" param_type="STRING" default_value="[null]" description="[null]"/> + <rules_parameters id="7" rule_id="3" name="type" param_type="STRING" default_value="[null]" description="[null]"/> + <rules_parameters id="8" rule_id="3" name="param" param_type="STRING" default_value="[null]" description="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter.xml b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter.xml new file mode 100644 index 00000000000..ae7a8443d9a --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter.xml @@ -0,0 +1,31 @@ +<dataset> + + <!-- Template rule --> + <rules id="1" plugin_rule_key="ArchitecturalConstraint" plugin_name="xoo" name="Architectural constraint" + description="Architectural constraint" status="READY" priority="1" language="xoo" + note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]" + description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]" + characteristic_id="[null]" default_characteristic_id="[null]" + remediation_function="[null]" default_remediation_function="[null]" + remediation_coeff="[null]" default_remediation_coeff="[null]" + remediation_offset="[null]" default_remediation_offset="[null]" + effort_to_fix_description="[null]" + is_template="[true]" template_id="[null]" created_at="2014-01-01" updated_at="2014-01-01"/> + <rules_parameters id="1" rule_id="1" name="max" param_type="INT" default_value="10" description="[null]"/> + <rules_parameters id="2" rule_id="1" name="format" param_type="STRING" default_value="txt" description="[null]"/> + <rules_parameters id="3" rule_id="1" name="type" param_type="STRING" default_value="[null]" description="[null]"/> + <rules_parameters id="4" rule_id="1" name="param" param_type="STRING" default_value="" description="[null]"/> + + <!-- Custom rule, 0 parameter are existing, 4 parameters should be added --> + <rules id="3" plugin_rule_key="ArchitecturalConstraint_3" plugin_name="xoo" name="Architectural constraint 3" + description="Architectural constraint 3" status="READY" priority="1" language="xoo" + note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]" + description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]" + characteristic_id="[null]" default_characteristic_id="[null]" + remediation_function="[null]" default_remediation_function="[null]" + remediation_coeff="[null]" default_remediation_coeff="[null]" + remediation_offset="[null]" default_remediation_offset="[null]" + effort_to_fix_description="[null]" + is_template="[false]" template_id="1" created_at="2014-01-01" updated_at="2014-01-01"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/no_changes.xml b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/no_changes.xml new file mode 100644 index 00000000000..53ad673ec69 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/no_changes.xml @@ -0,0 +1,29 @@ +<dataset> + + <!-- Template rule --> + <rules id="10" plugin_rule_key="Rule2" plugin_name="xoo" name="Rule2" description="Rule2" status="READY" priority="1" + language="xoo" + note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]" + description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]" + characteristic_id="[null]" default_characteristic_id="[null]" + remediation_function="[null]" default_remediation_function="[null]" + remediation_coeff="[null]" default_remediation_coeff="[null]" + remediation_offset="[null]" default_remediation_offset="[null]" + effort_to_fix_description="[null]" + is_template="[true]" template_id="[null]" created_at="2014-01-01" updated_at="2014-01-01"/> + <rules_parameters id="10" rule_id="10" name="max" param_type="INT" default_value="10" description="[null]"/> + + <!-- Custom rule, no parameter should be added --> + <rules id="11" plugin_rule_key="Rule2_2" plugin_name="xoo" name="Rule2_2" description="Rule2_2" status="READY" + priority="1" language="xoo" + note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]" + description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]" + characteristic_id="[null]" default_characteristic_id="[null]" + remediation_function="[null]" default_remediation_function="[null]" + remediation_coeff="[null]" default_remediation_coeff="[null]" + remediation_offset="[null]" default_remediation_offset="[null]" + effort_to_fix_description="[null]" + is_template="[false]" template_id="10" created_at="2014-01-01" updated_at="2014-01-01"/> + <rules_parameters id="11" rule_id="11" name="max" param_type="INT" default_value="10" description="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/schema.sql new file mode 100644 index 00000000000..0bf38617681 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/schema.sql @@ -0,0 +1,40 @@ +CREATE TABLE "RULES_PARAMETERS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "RULE_ID" INTEGER NOT NULL, + "NAME" VARCHAR(128) NOT NULL, + "PARAM_TYPE" VARCHAR(512) NOT NULL, + "DEFAULT_VALUE" VARCHAR(4000), + "DESCRIPTION" VARCHAR(4000) +); + +CREATE TABLE "RULES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "PLUGIN_RULE_KEY" VARCHAR(200) NOT NULL, + "PLUGIN_NAME" VARCHAR(255) NOT NULL, + "DESCRIPTION" VARCHAR(16777215), + "DESCRIPTION_FORMAT" VARCHAR(20), + "PRIORITY" INTEGER, + "IS_TEMPLATE" BOOLEAN DEFAULT FALSE, + "TEMPLATE_ID" INTEGER, + "PLUGIN_CONFIG_KEY" VARCHAR(500), + "NAME" VARCHAR(200), + "STATUS" VARCHAR(40), + "LANGUAGE" VARCHAR(20), + "NOTE_DATA" CLOB(2147483647), + "NOTE_USER_LOGIN" VARCHAR(255), + "NOTE_CREATED_AT" TIMESTAMP, + "NOTE_UPDATED_AT" TIMESTAMP, + "CHARACTERISTIC_ID" INTEGER, + "DEFAULT_CHARACTERISTIC_ID" INTEGER, + "REMEDIATION_FUNCTION" VARCHAR(20), + "DEFAULT_REMEDIATION_FUNCTION" VARCHAR(20), + "REMEDIATION_COEFF" VARCHAR(20), + "DEFAULT_REMEDIATION_COEFF" VARCHAR(20), + "REMEDIATION_OFFSET" VARCHAR(20), + "DEFAULT_REMEDIATION_OFFSET" VARCHAR(20), + "EFFORT_TO_FIX_DESCRIPTION" VARCHAR(4000), + "TAGS" VARCHAR(4000), + "SYSTEM_TAGS" VARCHAR(4000), + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/execute-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/execute-result.xml new file mode 100644 index 00000000000..49462b9bbcd --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/execute-result.xml @@ -0,0 +1,12 @@ +<dataset> + + <!-- ok --> + <activities id="1" log_key="abcde" created_at="2014-01-10" user_login="[null]" log_type="QPROFILE" + log_action="ACTIVATED" log_message="[null]" + data_field="ruleKey=findbugs:PT_RELATIVE_PATH_TRAVERSAL;profileKey=java-findbugs-74105;severity=MAJOR"/> + + <!-- ko - deleted --> + <!--<activities id="2" log_key="fghij" created_at="2014-01-10" user_login="[null]" log_type="QPROFILE" + log_action="ACTIVATED" log_message="[null]" + data_field="ruleKey=findbugs:PT_RELATIVE_PATH_TRAVERSAL;param_xpath=foo;bar;baz"/>--> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/execute.xml b/sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/execute.xml new file mode 100644 index 00000000000..415484745fb --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/execute.xml @@ -0,0 +1,12 @@ +<dataset> + + <!-- ok --> + <activities id="1" log_key="abcde" created_at="2014-01-10" user_login="[null]" log_type="QPROFILE" + log_action="ACTIVATED" log_message="[null]" + data_field="ruleKey=findbugs:PT_RELATIVE_PATH_TRAVERSAL;profileKey=java-findbugs-74105;severity=MAJOR"/> + + <!-- ko --> + <activities id="2" log_key="fghij" created_at="2014-01-10" user_login="[null]" log_type="QPROFILE" + log_action="ACTIVATED" log_message="[null]" + data_field="ruleKey=findbugs:PT_RELATIVE_PATH_TRAVERSAL;param_xpath=foo;bar;baz"/> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/schema.sql new file mode 100644 index 00000000000..336e2fd7f01 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/schema.sql @@ -0,0 +1,10 @@ +CREATE TABLE "ACTIVITIES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "LOG_KEY" VARCHAR(250), + "CREATED_AT" TIMESTAMP, + "USER_LOGIN" VARCHAR(30), + "LOG_TYPE" VARCHAR(250), + "LOG_ACTION" VARCHAR(250), + "LOG_MESSAGE" VARCHAR(250), + "DATA_FIELD" CLOB(2147483647) +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after-with-invalid-duplication.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after-with-invalid-duplication.xml new file mode 100644 index 00000000000..6810f0a5dfe --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after-with-invalid-duplication.xml @@ -0,0 +1,15 @@ +<dataset> + + <file_sources id="1" project_uuid="uuid-MyProject" file_uuid="uuid-Migrated.xoo" created_at="1416238020000" + updated_at="1414770242000" + data="" + line_hashes="" + data_hash=""/> + + <file_sources id="2" project_uuid="uuid-MyProject" file_uuid="uuid-MyFile.xoo" created_at="1416238020000" + updated_at="1414770242000" + data=",,,,,,,,,,,,,,,class Foo { ,,,,,,,,,,,,,,, // Empty ,,,,,,,,,,,,,,,} ,,,,,,,,,,,,,,, " + line_hashes="6a19ce786467960a3a9b0d26383a464a aab2dbc5fdeaa80b050b1d049ede357c cbb184dd8e05c9709e5dcaedaa0495cf " + data_hash=""/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after-with-scm.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after-with-scm.xml new file mode 100644 index 00000000000..fa4d6332c5b --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after-with-scm.xml @@ -0,0 +1,15 @@ +<dataset> + + <file_sources id="1" project_uuid="uuid-MyProject" file_uuid="uuid-Migrated.xoo" created_at="1416238020000" + updated_at="1414770242000" + data="" + line_hashes="" + data_hash=""/> + + <file_sources id="2" project_uuid="uuid-MyProject" file_uuid="uuid-MyFile.xoo" created_at="1416238020000" + updated_at="1414770242000" + data="aef12a,alice,2014-04-25T12:34:56+0100,1,4,2,2,5,3,3,6,4,,,1,class Foo { abe465,bob,2014-07-25T12:34:56+0100,,,,,,,,,,,,2, // Empty afb789,carol,2014-03-23T12:34:56+0100,0,,,0,,,0,,,,,,} afb789,carol,2014-03-23T12:34:56+0100,,,,,,,,,,,,, " + line_hashes="6a19ce786467960a3a9b0d26383a464a aab2dbc5fdeaa80b050b1d049ede357c cbb184dd8e05c9709e5dcaedaa0495cf " + data_hash=""/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after.xml new file mode 100644 index 00000000000..6810f0a5dfe --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after.xml @@ -0,0 +1,15 @@ +<dataset> + + <file_sources id="1" project_uuid="uuid-MyProject" file_uuid="uuid-Migrated.xoo" created_at="1416238020000" + updated_at="1414770242000" + data="" + line_hashes="" + data_hash=""/> + + <file_sources id="2" project_uuid="uuid-MyProject" file_uuid="uuid-MyFile.xoo" created_at="1416238020000" + updated_at="1414770242000" + data=",,,,,,,,,,,,,,,class Foo { ,,,,,,,,,,,,,,, // Empty ,,,,,,,,,,,,,,,} ,,,,,,,,,,,,,,, " + line_hashes="6a19ce786467960a3a9b0d26383a464a aab2dbc5fdeaa80b050b1d049ede357c cbb184dd8e05c9709e5dcaedaa0495cf " + data_hash=""/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/before.xml new file mode 100644 index 00000000000..065480f088d --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/before.xml @@ -0,0 +1,134 @@ +<dataset> + + <metrics id="1" name="revisions_by_line" description="[null]" direction="0" domain="SCM" + short_name="Revisions by line" qualitative="false" val_type="DATA" + user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]" + optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/> + <metrics id="2" name="authors_by_line" description="[null]" direction="0" domain="SCM" short_name="Authors by line" + qualitative="false" val_type="DATA" + user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]" + optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/> + <metrics id="3" name="last_commit_datetimes_by_line" description="[null]" direction="0" domain="SCM" + short_name="Last commit dates by line" qualitative="false" val_type="DATA" + user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]" + optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/> + <metrics id="4" name="coverage_line_hits_data" description="[null]" direction="0" domain="Test" + short_name="Coverage hits by line" qualitative="false" val_type="DATA" + user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]" + optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/> + <metrics id="5" name="conditions_by_line" description="[null]" direction="0" domain="Tests" + short_name="Conditions by line" qualitative="false" val_type="DATA" + user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]" + optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/> + <metrics id="6" name="covered_conditions_by_line" description="[null]" direction="0" domain="Tests" + short_name="Covered conditions by line" qualitative="false" val_type="DATA" + user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]" + optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/> + <metrics id="7" name="it_coverage_line_hits_data" description="[null]" direction="0" domain="Test" + short_name="Coverage hits by line" qualitative="false" val_type="DATA" + user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]" + optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/> + <metrics id="8" name="it_conditions_by_line" description="[null]" direction="0" domain="Tests" + short_name="Conditions by line" qualitative="false" val_type="DATA" + user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]" + optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/> + <metrics id="9" name="it_covered_conditions_by_line" description="[null]" direction="0" domain="Tests" + short_name="Covered conditions by line" qualitative="false" val_type="DATA" + user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]" + optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/> + <metrics id="10" name="overall_coverage_line_hits_data" description="[null]" direction="0" domain="Test" + short_name="Coverage hits by line" qualitative="false" val_type="DATA" + user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]" + optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/> + <metrics id="11" name="overall_conditions_by_line" description="[null]" direction="0" domain="Tests" + short_name="Conditions by line" qualitative="false" val_type="DATA" + user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]" + optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/> + <metrics id="12" name="overall_covered_conditions_by_line" description="[null]" direction="0" domain="Tests" + short_name="Covered conditions by line" qualitative="false" val_type="DATA" + user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]" + optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/> + <metrics id="13" name="duplications_data" description="[null]" direction="0" domain="Duplications" + short_name="Duplication data" qualitative="false" val_type="DATA" + user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]" + optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/> + + <projects id="1" uuid="uuid-MyProject" kee="MyProject" scope="PRJ" qualifier="TRK"/> + <projects id="2" uuid="uuid-prj" kee="MyProject:src/main/xoo/prj" scope="DIR" qualifier="DIR"/> + <projects id="3" uuid="uuid-MyFile.xoo" kee="MyProject:src/main/xoo/prj/MyFile.xoo" scope="FIL" qualifier="FIL"/> + <projects id="4" uuid="uuid-Migrated.xoo" kee="MyProject:src/main/xoo/prj/Migrated.xoo" scope="FIL" qualifier="FIL"/> + + <snapshots id="1" project_id="1" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1" + status="P" islast="[false]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="2011-09-24" + period2_mode="days2" period2_param="31" period2_date="2011-09-25" + period3_mode="days3" period3_param="32" period3_date="2011-09-26" + period4_mode="days4" period4_param="33" period4_date="2011-09-27" + period5_mode="days5" period5_param="34" period5_date="2011-09-28" + depth="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02" build_date="2011-09-29" + version="2.1-SNAPSHOT" path="1.2."/> + <snapshots id="2" project_id="1" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="2011-09-24" + period2_mode="days2" period2_param="31" period2_date="2011-09-25" + period3_mode="days3" period3_param="32" period3_date="2011-09-26" + period4_mode="days4" period4_param="33" period4_date="2011-09-27" + period5_mode="days5" period5_param="34" period5_date="2011-09-28" + depth="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02" build_date="2011-09-29" + version="2.1-SNAPSHOT" path="1.2."/> + + <snapshots id="3" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1" + status="P" islast="[false]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="2011-09-24" + period2_mode="days2" period2_param="31" period2_date="2011-09-25" + period3_mode="days3" period3_param="32" period3_date="2011-09-26" + period4_mode="days4" period4_param="33" period4_date="2011-09-27" + period5_mode="days5" period5_param="34" period5_date="2011-09-28" + depth="1" scope="DIR" qualifier="DIR" created_at="2008-12-02" build_date="2011-09-29" + version="2.1-SNAPSHOT" path="1.2."/> + <snapshots id="4" project_id="2" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="2" + status="P" islast="[true]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="2011-09-24" + period2_mode="days2" period2_param="31" period2_date="2011-09-25" + period3_mode="days3" period3_param="32" period3_date="2011-09-26" + period4_mode="days4" period4_param="33" period4_date="2011-09-27" + depth="1" scope="DIR" qualifier="DIR" created_at="2008-12-02" build_date="2011-09-29" + period5_mode="days5" period5_param="34" period5_date="2011-09-28" + version="2.1-SNAPSHOT" path="1.2."/> + + <snapshots id="5" project_id="3" parent_snapshot_id="3" root_project_id="1" root_snapshot_id="1" + status="P" islast="[false]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="2011-09-24" + period2_mode="days2" period2_param="31" period2_date="2011-09-25" + period3_mode="days3" period3_param="32" period3_date="2011-09-26" + period4_mode="days4" period4_param="33" period4_date="2011-09-27" + period5_mode="days5" period5_param="34" period5_date="2011-09-28" + depth="1" scope="DIR" qualifier="DIR" created_at="2008-12-02" build_date="2011-09-29" + version="2.1-SNAPSHOT" path="1.2."/> + <snapshots id="6" project_id="3" parent_snapshot_id="4" root_project_id="1" root_snapshot_id="2" + status="P" islast="[true]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="2011-09-24" + period2_mode="days2" period2_param="31" period2_date="2011-09-25" + period3_mode="days3" period3_param="32" period3_date="2011-09-26" + period4_mode="days4" period4_param="33" period4_date="2011-09-27" + period5_mode="days5" period5_param="34" period5_date="2011-09-28" + depth="1" scope="FIL" qualifier="FIL" created_at="2008-12-02" build_date="2011-09-29" + version="2.1-SNAPSHOT" path="1.2."/> + + <snapshots id="7" project_id="4" parent_snapshot_id="5" root_project_id="1" root_snapshot_id="2" + status="P" islast="[true]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="2011-09-24" + period2_mode="days2" period2_param="31" period2_date="2011-09-25" + period3_mode="days3" period3_param="32" period3_date="2011-09-26" + period4_mode="days4" period4_param="33" period4_date="2011-09-27" + period5_mode="days5" period5_param="34" period5_date="2011-09-28" + depth="1" scope="FIL" qualifier="FIL" created_at="2008-12-02" build_date="2011-09-29" + version="2.1-SNAPSHOT" path="1.2."/> + + <file_sources id="1" project_uuid="uuid-MyProject" file_uuid="uuid-Migrated.xoo" created_at="1416238020000" + updated_at="1414770242000" + data="" + line_hashes="" + data_hash=""/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/schema.sql new file mode 100644 index 00000000000..481ea89ba0a --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/schema.sql @@ -0,0 +1,119 @@ + +CREATE TABLE "METRICS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "NAME" VARCHAR(64) NOT NULL, + "DESCRIPTION" VARCHAR(255), + "DIRECTION" INTEGER NOT NULL DEFAULT 0, + "DOMAIN" VARCHAR(64), + "SHORT_NAME" VARCHAR(64), + "QUALITATIVE" BOOLEAN NOT NULL DEFAULT FALSE, + "VAL_TYPE" VARCHAR(8), + "USER_MANAGED" BOOLEAN DEFAULT FALSE, + "ENABLED" BOOLEAN DEFAULT TRUE, + "ORIGIN" VARCHAR(3), + "WORST_VALUE" DOUBLE, + "BEST_VALUE" DOUBLE, + "OPTIMIZED_BEST_VALUE" BOOLEAN, + "HIDDEN" BOOLEAN, + "DELETE_HISTORICAL_DATA" BOOLEAN +); + +CREATE TABLE "SNAPSHOTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "CREATED_AT" TIMESTAMP, + "BUILD_DATE" TIMESTAMP, + "PROJECT_ID" INTEGER NOT NULL, + "PARENT_SNAPSHOT_ID" INTEGER, + "STATUS" VARCHAR(4) NOT NULL DEFAULT 'U', + "PURGE_STATUS" INTEGER, + "ISLAST" BOOLEAN NOT NULL DEFAULT FALSE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10), + "ROOT_SNAPSHOT_ID" INTEGER, + "VERSION" VARCHAR(500), + "PATH" VARCHAR(500), + "DEPTH" INTEGER, + "ROOT_PROJECT_ID" INTEGER, + "PERIOD1_MODE" VARCHAR(100), + "PERIOD1_PARAM" VARCHAR(100), + "PERIOD1_DATE" TIMESTAMP, + "PERIOD2_MODE" VARCHAR(100), + "PERIOD2_PARAM" VARCHAR(100), + "PERIOD2_DATE" TIMESTAMP, + "PERIOD3_MODE" VARCHAR(100), + "PERIOD3_PARAM" VARCHAR(100), + "PERIOD3_DATE" TIMESTAMP, + "PERIOD4_MODE" VARCHAR(100), + "PERIOD4_PARAM" VARCHAR(100), + "PERIOD4_DATE" TIMESTAMP, + "PERIOD5_MODE" VARCHAR(100), + "PERIOD5_PARAM" VARCHAR(100), + "PERIOD5_DATE" TIMESTAMP +); + +CREATE TABLE "SNAPSHOT_SOURCES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "SNAPSHOT_ID" INTEGER NOT NULL, + "UPDATED_AT" TIMESTAMP, + "DATA" CLOB(2147483647) +); + +CREATE TABLE "PROJECTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(400), + "ROOT_ID" INTEGER, + "UUID" VARCHAR(50), + "PROJECT_UUID" VARCHAR(50), + "MODULE_UUID" VARCHAR(50), + "MODULE_UUID_PATH" VARCHAR(4000), + "NAME" VARCHAR(256), + "DESCRIPTION" VARCHAR(2000), + "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10), + "DEPRECATED_KEE" VARCHAR(400), + "PATH" VARCHAR(2000), + "LANGUAGE" VARCHAR(20), + "COPY_RESOURCE_ID" INTEGER, + "LONG_NAME" VARCHAR(256), + "PERSON_ID" INTEGER, + "CREATED_AT" TIMESTAMP, + "AUTHORIZATION_UPDATED_AT" BIGINT +); + +CREATE TABLE "PROJECT_MEASURES" ( + "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "VALUE" DOUBLE, + "METRIC_ID" INTEGER NOT NULL, + "SNAPSHOT_ID" INTEGER, + "RULE_ID" INTEGER, + "RULES_CATEGORY_ID" INTEGER, + "TEXT_VALUE" VARCHAR(4000), + "TENDENCY" INTEGER, + "MEASURE_DATE" TIMESTAMP, + "PROJECT_ID" INTEGER, + "ALERT_STATUS" VARCHAR(5), + "ALERT_TEXT" VARCHAR(4000), + "URL" VARCHAR(2000), + "DESCRIPTION" VARCHAR(4000), + "RULE_PRIORITY" INTEGER, + "CHARACTERISTIC_ID" INTEGER, + "PERSON_ID" INTEGER, + "VARIATION_VALUE_1" DOUBLE, + "VARIATION_VALUE_2" DOUBLE, + "VARIATION_VALUE_3" DOUBLE, + "VARIATION_VALUE_4" DOUBLE, + "VARIATION_VALUE_5" DOUBLE, + "MEASURE_DATA" BINARY(167772150) +); + +CREATE TABLE "FILE_SOURCES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "PROJECT_UUID" VARCHAR(50) NOT NULL, + "FILE_UUID" VARCHAR(50) NOT NULL, + "DATA" CLOB(2147483647), + "LINE_HASHES" CLOB(2147483647), + "DATA_HASH" VARCHAR(50) NOT NULL, + "CREATED_AT" BIGINT NOT NULL, + "UPDATED_AT" BIGINT NOT NULL +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedIssueLongDatesTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedIssueLongDatesTest/before.xml new file mode 100644 index 00000000000..7f2e3baa257 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedIssueLongDatesTest/before.xml @@ -0,0 +1,75 @@ +<dataset> + + <issues id="1" kee="ABC" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" + author_login="[null]" + checksum="[null]" + effort_to_fix="[null]" + technical_debt="10" + message="[null]" + line="5000" + component_id="100" + root_component_id="10" + rule_id="200" + reporter="emmerik" + issue_attributes="foo=bar" + action_plan_key="[null]" + issue_creation_date="2013-05-18" + issue_update_date="2013-05-18" + issue_close_date="2013-05-18" + created_at="2014-05-12" + updated_at="2014-05-13" + CREATED_AT_MS="[null]" + UPDATED_AT_MS="[null]" + /> + + <!-- re-entrant migration - ignore the issues that are already fed with new dates --> + <issues id="2" kee="DEF" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" + author_login="[null]" + checksum="[null]" + effort_to_fix="[null]" + technical_debt="10" + message="[null]" + line="5000" + component_id="100" + root_component_id="10" + rule_id="200" + reporter="emmerik" + issue_attributes="foo=bar" + action_plan_key="[null]" + issue_creation_date="2013-05-18" + issue_update_date="2013-05-18" + issue_close_date="2013-05-18" + + created_at="2014-05-12" + updated_at="2014-05-13" + CREATED_AT_MS="1500000000000" + UPDATED_AT_MS="1500000000000" + /> + + <!-- NULL dates --> + <issues id="3" kee="MISSINGDATES" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" + author_login="[null]" + checksum="[null]" + effort_to_fix="[null]" + technical_debt="10" + message="[null]" + line="5000" + component_id="100" + root_component_id="10" + rule_id="200" + reporter="emmerik" + issue_attributes="foo=bar" + action_plan_key="[null]" + issue_creation_date="[null]" + issue_update_date="[null]" + issue_close_date="[null]" + created_at="[null]" + updated_at="[null]" + CREATED_AT_MS="[null]" + UPDATED_AT_MS="[null]" + /> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedIssueLongDatesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedIssueLongDatesTest/schema.sql new file mode 100644 index 00000000000..66c7d3a7a9f --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedIssueLongDatesTest/schema.sql @@ -0,0 +1,28 @@ +CREATE TABLE "ISSUES" ( + "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(50) UNIQUE NOT NULL, + "COMPONENT_ID" INTEGER NOT NULL, + "ROOT_COMPONENT_ID" INTEGER, + "RULE_ID" INTEGER, + "SEVERITY" VARCHAR(10), + "MANUAL_SEVERITY" BOOLEAN NOT NULL, + "MESSAGE" VARCHAR(4000), + "LINE" INTEGER, + "EFFORT_TO_FIX" DOUBLE, + "TECHNICAL_DEBT" INTEGER, + "STATUS" VARCHAR(20), + "RESOLUTION" VARCHAR(20), + "CHECKSUM" VARCHAR(1000), + "REPORTER" VARCHAR(255), + "ASSIGNEE" VARCHAR(255), + "AUTHOR_LOGIN" VARCHAR(255), + "ACTION_PLAN_KEY" VARCHAR(50) NULL, + "ISSUE_ATTRIBUTES" VARCHAR(4000), + "ISSUE_CREATION_DATE" TIMESTAMP, + "ISSUE_CLOSE_DATE" TIMESTAMP, + "ISSUE_UPDATE_DATE" TIMESTAMP, + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP, + "CREATED_AT_MS" BIGINT, + "UPDATED_AT_MS" BIGINT +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/after.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/after.xml new file mode 100644 index 00000000000..0b0dfa1d728 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/after.xml @@ -0,0 +1,28 @@ +<dataset> + + <projects id="1" kee="project" name="project" long_name="project" scope="PRJ" qualifier="TRK" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-09-01" authorization_updated_at="123456789"/> + + <projects id="2" kee="view" name="View" long_name="View" scope="PRJ" qualifier="VW" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-09-01" authorization_updated_at="123456789"/> + + <!-- File should not be updated --> + <projects id="3" kee="file" name="File" long_name="File" scope="FIL" qualifier="CLA" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-09-01" authorization_updated_at="[null]"/> + + <projects id="4" kee="disabled" name="Disabled" long_name="Disabled" scope="PRJ" qualifier="TRK" root_id="1" + description="[null]" + enabled="false" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-09-01" authorization_updated_at="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/before.xml new file mode 100644 index 00000000000..8cf83a39b03 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/before.xml @@ -0,0 +1,28 @@ +<dataset> + + <projects id="1" kee="project" name="project" long_name="project" scope="PRJ" qualifier="TRK" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-09-01" authorization_updated_at="[null]"/> + + <projects id="2" kee="view" name="View" long_name="View" scope="PRJ" qualifier="VW" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-09-01" authorization_updated_at="[null]"/> + + <!-- File should not be updated --> + <projects id="3" kee="file" name="File" long_name="File" scope="FIL" qualifier="CLA" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-09-01" authorization_updated_at="[null]"/> + + <projects id="4" kee="disabled" name="Disabled" long_name="Disabled" scope="PRJ" qualifier="TRK" root_id="1" + description="[null]" + enabled="false" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-09-01" authorization_updated_at="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/schema.sql new file mode 100644 index 00000000000..e10b82bd90e --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/schema.sql @@ -0,0 +1,18 @@ +CREATE TABLE "PROJECTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "NAME" VARCHAR(256), + "DESCRIPTION" VARCHAR(2000), + "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10), + "KEE" VARCHAR(400), + "DEPRECATED_KEE" VARCHAR(400), + "PATH" VARCHAR(2000), + "ROOT_ID" INTEGER, + "LANGUAGE" VARCHAR(20), + "COPY_RESOURCE_ID" INTEGER, + "LONG_NAME" VARCHAR(256), + "PERSON_ID" INTEGER, + "CREATED_AT" TIMESTAMP, + "AUTHORIZATION_UPDATED_AT" BIGINT +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components.xml new file mode 100644 index 00000000000..3ea725be763 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components.xml @@ -0,0 +1,93 @@ +<dataset> + + <!-- root project --> + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-06-18"/> + <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path=""/> + + <!-- module --> + <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + scope="PRJ" qualifier="BRC" long_name="Struts Core" deprecated_kee="[null]" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" + created_at="2014-06-18"/> + <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1."/> + + <!-- sub module --> + <projects id="3" root_id="2" kee="org.struts:struts-db" name="Struts Db" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + scope="PRJ" qualifier="BRC" long_name="Struts Db" deprecated_kee="[null]" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" + created_at="2014-06-18"/> + <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1.2."/> + + <!-- directory --> + <projects long_name="org.struts" id="4" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + name="src/org/struts" root_id="2" + description="[null]" deprecated_kee="[null]" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" + created_at="2014-06-18"/> + <snapshots id="4" project_id="4" parent_snapshot_id="3" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1.2.3."/> + + <!-- file --> + <projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL" + kee="org.struts:struts-core:src/org/struts/RequestContext.java" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + name="RequestContext.java" root_id="2" + description="[null]" deprecated_kee="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" + path="src/org/struts/RequestContext.java" created_at="2014-06-18"/> + + <snapshots id="5" project_id="5" parent_snapshot_id="4" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1.2.3.4."/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components_without_uuid.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components_without_uuid.xml new file mode 100644 index 00000000000..e5f8a0223ed --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components_without_uuid.xml @@ -0,0 +1,58 @@ +<dataset> + + <!-- root project --> + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-06-18"/> + <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path=""/> + + <!-- module with a snapshot having no islast=true --> + <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + scope="PRJ" qualifier="BRC" long_name="Struts Core" deprecated_kee="[null]" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" + created_at="2014-06-18"/> + <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1" + status="P" islast="[false]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1."/> + + <!-- file linked on a no more existing project --> + <projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL" + kee="org.struts:struts-core:src/org/struts/RequestContext.java" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + name="RequestContext.java" root_id="999" + description="[null]" deprecated_kee="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" + path="src/org/struts/RequestContext.java" created_at="2014-06-18"/> + + <snapshots id="5" project_id="5" parent_snapshot_id="999" root_project_id="999" root_snapshot_id="999" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1.2.3.4."/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_developer.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_developer.xml new file mode 100644 index 00000000000..68496498454 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_developer.xml @@ -0,0 +1,40 @@ +<dataset> + + <!-- developer --> + <projects id="1" kee="DEV:developer@company.net" name="developer@company.net" long_name="Developer" scope="PRJ" + qualifier="DEV" root_id="[null]" description="[null]" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-09-01"/> + <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="DEV" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path=""/> + + <!-- technical project --> + <projects id="2" root_id="1" scope="PRJ" qualifier="DEV_PRJ" kee="DEV:developer@company.net:org.struts:struts" + name="Struts" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="10" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-06-18"/> + <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="1" scope="PRJ" qualifier="DEV_PRJ" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1."/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_disable_components.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_disable_components.xml new file mode 100644 index 00000000000..47998eecac3 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_disable_components.xml @@ -0,0 +1,93 @@ +<dataset> + + <!-- root project --> + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-06-18"/> + <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path=""/> + + <!-- removed module --> + <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + scope="PRJ" qualifier="BRC" long_name="Struts Core" deprecated_kee="[null]" + description="[null]" enabled="[false]" language="[null]" copy_resource_id="[null]" person_id="[null]" + created_at="2014-06-18"/> + <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1" + status="P" islast="[false]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1."/> + + <!--removed sub module --> + <projects id="3" root_id="2" kee="org.struts:struts-db" name="Struts Db" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + scope="PRJ" qualifier="BRC" long_name="Struts Db" deprecated_kee="[null]" + description="[null]" enabled="[false]" language="[null]" copy_resource_id="[null]" person_id="[null]" + created_at="2014-06-18"/> + <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1" + status="P" islast="[false]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1.2."/> + + <!-- removed directory --> + <projects long_name="org.struts" id="4" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + name="src/org/struts" root_id="2" + description="[null]" deprecated_kee="[null]" + enabled="[false]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" + created_at="2014-06-18"/> + <snapshots id="4" project_id="4" parent_snapshot_id="3" root_project_id="1" root_snapshot_id="1" + status="P" islast="[false]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1.2.3."/> + + <!-- removed file --> + <projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL" + kee="org.struts:struts-core:src/org/struts/RequestContext.java" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + name="RequestContext.java" root_id="2" + description="[null]" deprecated_kee="[null]" + enabled="[false]" language="java" copy_resource_id="[null]" person_id="[null]" + path="src/org/struts/RequestContext.java" created_at="2014-06-18"/> + + <snapshots id="5" project_id="5" parent_snapshot_id="4" root_project_id="1" root_snapshot_id="1" + status="P" islast="[false]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1.2.3.4."/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_library.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_library.xml new file mode 100644 index 00000000000..89709dca85d --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_library.xml @@ -0,0 +1,12 @@ +<dataset> + + <!-- library --> + <projects id="1" root_id="[null]" scope="PRJ" qualifier="LIB" kee="org.hamcrest:hamcrest-library" + name="org.hamcrest:hamcrest-library" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + description="[null]" long_name="org.hamcrest:hamcrest-library" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-06-18"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_provisioned_project.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_provisioned_project.xml new file mode 100644 index 00000000000..c485cc06664 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_provisioned_project.xml @@ -0,0 +1,11 @@ +<dataset> + + <!-- provisioned project --> + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-06-18"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_view.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_view.xml new file mode 100644 index 00000000000..b3ae4868b4c --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_view.xml @@ -0,0 +1,57 @@ +<dataset> + + <!-- view --> + <projects id="1" kee="view" name="View" long_name="View" scope="PRJ" qualifier="VW" root_id="[null]" + description="[null]" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-09-01"/> + <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="VW" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path=""/> + + <!-- sub view --> + <projects id="2" kee="subView" name="Sub View" long_name="Sub View" scope="PRJ" qualifier="SVW" root_id="1" + description="[null]" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-09-01"/> + <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="SVW" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1."/> + + <!-- technical project --> + <projects id="3" root_id="1" scope="FIL" qualifier="TRK" kee="vieworg.struts:struts" name="Struts" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="10" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-06-18"/> + <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="1" scope="FIL" qualifier="TRK" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1.2."/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_fail_when_module_has_no_root_id.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_fail_when_module_has_no_root_id.xml new file mode 100644 index 00000000000..c0b7676303d --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_fail_when_module_has_no_root_id.xml @@ -0,0 +1,38 @@ +<dataset> + + <!-- root project --> + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-06-18"/> + <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path=""/> + + <!-- module with null root id (probably a project that became a module) --> + <projects id="2" root_id="[null]" kee="org.struts:struts-core" name="Struts Core" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + scope="PRJ" qualifier="BRC" long_name="Struts Core" deprecated_kee="[null]" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" + created_at="2014-06-18"/> + <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1."/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_fail_when_project_has_two_active_snapshots.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_fail_when_project_has_two_active_snapshots.xml new file mode 100644 index 00000000000..e42d8158831 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_fail_when_project_has_two_active_snapshots.xml @@ -0,0 +1,48 @@ +<dataset> + + <!-- root project with 2 snapshots having islast to true--> + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-06-18"/> + <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path=""/> + <snapshots id="10" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path=""/> + + <!-- module linked on second active snapshot of the project --> + <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + scope="PRJ" qualifier="BRC" long_name="Struts Core" deprecated_kee="[null]" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" + created_at="2014-06-18"/> + <snapshots id="2" project_id="2" parent_snapshot_id="10" root_project_id="1" root_snapshot_id="10" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="10."/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_migrate_already_migrated_components.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_migrate_already_migrated_components.xml new file mode 100644 index 00000000000..76b63671f12 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_migrate_already_migrated_components.xml @@ -0,0 +1,113 @@ +<dataset> + + <!-- root project migrated --> + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-06-18"/> + <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path=""/> + + <!-- module migrated --> + <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" + uuid="BCDE" project_uuid="ABCD" module_uuid="ABCD" module_uuid_path="ABCD" + scope="PRJ" qualifier="BRC" long_name="Struts Core" deprecated_kee="[null]" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" + created_at="2014-06-18"/> + <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1."/> + + <!-- sub module not migrated --> + <projects id="3" root_id="2" kee="org.struts:struts-db" name="Struts Db" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + scope="PRJ" qualifier="BRC" long_name="Struts Db" deprecated_kee="[null]" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" + created_at="2014-06-18"/> + <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1.2."/> + + <!-- directory not migrated --> + <projects long_name="org.struts" id="4" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + name="src/org/struts" root_id="2" + description="[null]" deprecated_kee="[null]" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" + created_at="2014-06-18"/> + <snapshots id="4" project_id="4" parent_snapshot_id="3" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1.2.3."/> + + <!-- file not migrated --> + <projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL" + kee="org.struts:struts-core:src/org/struts/RequestContext.java" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + name="RequestContext.java" root_id="2" + description="[null]" deprecated_kee="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" + path="src/org/struts/RequestContext.java" created_at="2014-06-18"/> + + <snapshots id="5" project_id="5" parent_snapshot_id="4" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1.2.3.4."/> + + <!-- removed file linked on module, migrated --> + <projects long_name="org.struts.RequestContext2" id="6" scope="FIL" qualifier="FIL" + kee="org.struts:struts-core:src/org/struts/RequestContext2.java" + uuid="DCBA" project_uuid="ABCD" module_uuid="BCDE" module_uuid_path="ABCD.BCDE" + name="RequestContext.java" root_id="2" + description="[null]" deprecated_kee="[null]" + enabled="[false]" language="java" copy_resource_id="[null]" person_id="[null]" + path="src/org/struts/RequestContext.java" created_at="2014-06-18"/> + + <snapshots id="6" project_id="6" parent_snapshot_id="4" root_project_id="1" root_snapshot_id="1" + status="P" islast="[false]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" + build_date="2008-12-02 13:58:00.00" + version="[null]" path="1.2.3.4."/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/schema.sql new file mode 100644 index 00000000000..c8fee3449dd --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/schema.sql @@ -0,0 +1,54 @@ +CREATE TABLE "PROJECTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(400), + "ROOT_ID" INTEGER, + "UUID" VARCHAR(50), + "PROJECT_UUID" VARCHAR(50), + "MODULE_UUID" VARCHAR(50), + "MODULE_UUID_PATH" VARCHAR(4000), + "NAME" VARCHAR(256), + "DESCRIPTION" VARCHAR(2000), + "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10), + "DEPRECATED_KEE" VARCHAR(400), + "PATH" VARCHAR(2000), + "LANGUAGE" VARCHAR(20), + "COPY_RESOURCE_ID" INTEGER, + "LONG_NAME" VARCHAR(256), + "PERSON_ID" INTEGER, + "CREATED_AT" TIMESTAMP +); + +CREATE TABLE "SNAPSHOTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "CREATED_AT" TIMESTAMP, + "BUILD_DATE" TIMESTAMP, + "PROJECT_ID" INTEGER NOT NULL, + "PARENT_SNAPSHOT_ID" INTEGER, + "STATUS" VARCHAR(4) NOT NULL DEFAULT 'U', + "PURGE_STATUS" INTEGER, + "ISLAST" BOOLEAN NOT NULL DEFAULT FALSE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10), + "ROOT_SNAPSHOT_ID" INTEGER, + "VERSION" VARCHAR(500), + "PATH" VARCHAR(500), + "DEPTH" INTEGER, + "ROOT_PROJECT_ID" INTEGER, + "PERIOD1_MODE" VARCHAR(100), + "PERIOD1_PARAM" VARCHAR(100), + "PERIOD1_DATE" TIMESTAMP, + "PERIOD2_MODE" VARCHAR(100), + "PERIOD2_PARAM" VARCHAR(100), + "PERIOD2_DATE" TIMESTAMP, + "PERIOD3_MODE" VARCHAR(100), + "PERIOD3_PARAM" VARCHAR(100), + "PERIOD3_DATE" TIMESTAMP, + "PERIOD4_MODE" VARCHAR(100), + "PERIOD4_PARAM" VARCHAR(100), + "PERIOD4_DATE" TIMESTAMP, + "PERIOD5_MODE" VARCHAR(100), + "PERIOD5_PARAM" VARCHAR(100), + "PERIOD5_DATE" TIMESTAMP +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/execute-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/execute-result.xml new file mode 100644 index 00000000000..2be1be35633 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/execute-result.xml @@ -0,0 +1,33 @@ +<dataset> + + <issue_filters + id="1" + name="No sort field" + user_login="stephane" + shared="[true]" + description="no not touch" + data="projectUuids=ABCD" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <issue_filters + id="2" + name="Has sort field" + user_login="michael" + shared="[false]" + description="to be updated" + data="statuses=OPEN|projectUuids=ABC" + created_at="2013-06-10" + updated_at="2014-10-29 00:00:00.0"/> + + <issue_filters + id="3" + name="corner-case" + user_login="michael" + shared="[true]" + description="do not touch" + data="statuses=CLOSED|resort=true" + created_at="2013-06-10" + updated_at="2013-06-10"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/execute.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/execute.xml new file mode 100644 index 00000000000..e3fdb367e19 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/execute.xml @@ -0,0 +1,33 @@ +<dataset> + + <issue_filters + id="1" + name="No sort field" + user_login="stephane" + shared="[true]" + description="no not touch" + data="projectUuids=ABCD" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <issue_filters + id="2" + name="Has sort field" + user_login="michael" + shared="[false]" + description="to be updated" + data="statuses=OPEN|sort=SEVERITY|asc=true|projectUuids=ABC" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <issue_filters + id="3" + name="corner-case" + user_login="michael" + shared="[true]" + description="do not touch" + data="statuses=CLOSED|resort=true" + created_at="2013-06-10" + updated_at="2013-06-10"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/schema.sql new file mode 100644 index 00000000000..0627153a62d --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/schema.sql @@ -0,0 +1,10 @@ +CREATE TABLE "ISSUE_FILTERS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "NAME" VARCHAR(100) NOT NULL, + "SHARED" BOOLEAN NOT NULL DEFAULT FALSE, + "USER_LOGIN" VARCHAR(255), + "DESCRIPTION" VARCHAR(4000), + "DATA" CLOB(2147483647), + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/do_not_execute_if_already_migrated-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/do_not_execute_if_already_migrated-result.xml new file mode 100644 index 00000000000..7f657ff712c --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/do_not_execute_if_already_migrated-result.xml @@ -0,0 +1,43 @@ +<dataset> + + <issue_filters + id="1" + name="Struts Issues" + user_login="stephane" + shared="[true]" + description="All issues of Struts" + data="projectUuids=ABCD" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <issue_filters + id="2" + name="Open issues" + user_login="michael" + shared="[false]" + description="All open issues" + data="statuses=OPEN" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <issue_filters + id="3" + name="Sonar Open issues" + user_login="michael" + shared="[true]" + description="All open issues on Sonar" + data="statuses=CLOSED|projectUuids=ABCD|resolution=FIXED" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <issue_filters + id="4" + name="Bad component roots fields" + user_login="michael" + shared="[true]" + description="All open issues on Sonar" + data="statuses=CLOSED|projectUuids=|resolution=FIXED" + created_at="2013-06-10" + updated_at="2013-06-10"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/do_not_execute_if_already_migrated.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/do_not_execute_if_already_migrated.xml new file mode 100644 index 00000000000..524a2bef4a7 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/do_not_execute_if_already_migrated.xml @@ -0,0 +1,50 @@ +<dataset> + + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="." + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-06-18"/> + + <issue_filters + id="1" + name="Struts Issues" + user_login="stephane" + shared="[true]" + description="All issues of Struts" + data="projectUuids=ABCD" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <issue_filters + id="2" + name="Open issues" + user_login="michael" + shared="[false]" + description="All open issues" + data="statuses=OPEN" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <issue_filters + id="3" + name="Sonar Open issues" + user_login="michael" + shared="[true]" + description="All open issues on Sonar" + data="statuses=CLOSED|projectUuids=ABCD|resolution=FIXED" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <issue_filters + id="4" + name="Bad component roots fields" + user_login="michael" + shared="[true]" + description="All open issues on Sonar" + data="statuses=CLOSED|projectUuids=|resolution=FIXED" + created_at="2013-06-10" + updated_at="2013-06-10"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/execute-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/execute-result.xml new file mode 100644 index 00000000000..3d2bb6937e5 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/execute-result.xml @@ -0,0 +1,63 @@ +<dataset> + + <issue_filters + id="1" + name="Struts Issues" + user_login="stephane" + shared="[true]" + description="All issues of Struts" + data="projectUuids=ABCD" + created_at="2013-06-10" + updated_at="2014-10-29"/> + + <issue_filters + id="2" + name="Open issues" + user_login="michael" + shared="[false]" + description="All open issues" + data="statuses=OPEN" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <issue_filters + id="3" + name="Sonar Open issues" + user_login="michael" + shared="[true]" + description="All open issues on Sonar" + data="statuses=CLOSED|projectUuids=ABCD|resolution=FIXED" + created_at="2013-06-10" + updated_at="2014-10-29"/> + + <issue_filters + id="4" + name="Bad component roots fields" + user_login="michael" + shared="[true]" + description="Bad component roots fields" + data="statuses=CLOSED||resolution=FIXED" + created_at="2013-06-10" + updated_at="2014-10-29"/> + + <issue_filters + id="5" + name="Linked on not existing file" + user_login="michael" + shared="[true]" + description="Linked on not existing file" + data="statuses=CLOSED||resolution=FIXED" + created_at="2013-06-10" + updated_at="2014-10-29"/> + + <issue_filters + id="6" + name="Empty data" + user_login="michael" + shared="[true]" + description="Empty data" + data="[null]" + created_at="2013-06-10" + updated_at="2013-06-10"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/execute.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/execute.xml new file mode 100644 index 00000000000..a952ef40542 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/execute.xml @@ -0,0 +1,70 @@ +<dataset> + + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="." + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-06-18"/> + + <issue_filters + id="1" + name="Struts Issues" + user_login="stephane" + shared="[true]" + description="All issues of Struts" + data="componentRoots=org.struts:struts" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <issue_filters + id="2" + name="Open issues" + user_login="michael" + shared="[false]" + description="All open issues" + data="statuses=OPEN" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <issue_filters + id="3" + name="Sonar Open issues" + user_login="michael" + shared="[true]" + description="All open issues on Sonar" + data="statuses=CLOSED|componentRoots=org.struts:struts|resolution=FIXED" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <issue_filters + id="4" + name="Bad component roots fields" + user_login="michael" + shared="[true]" + description="Bad component roots fields" + data="statuses=CLOSED|componentRoots=|resolution=FIXED" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <issue_filters + id="5" + name="Linked on not existing file" + user_login="michael" + shared="[true]" + description="Linked on not existing file" + data="statuses=CLOSED|componentRoots=unknown|resolution=FIXED" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <issue_filters + id="6" + name="Empty data" + user_login="michael" + shared="[true]" + description="Empty data" + data="[null]" + created_at="2013-06-10" + updated_at="2013-06-10"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/schema.sql new file mode 100644 index 00000000000..a1182dd7d46 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/schema.sql @@ -0,0 +1,32 @@ +CREATE TABLE "ISSUE_FILTERS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "NAME" VARCHAR(100) NOT NULL, + "SHARED" BOOLEAN NOT NULL DEFAULT FALSE, + "USER_LOGIN" VARCHAR(255), + "DESCRIPTION" VARCHAR(4000), + "DATA" CLOB(2147483647), + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP +); + +CREATE TABLE "PROJECTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(400), + "ROOT_ID" INTEGER, + "UUID" VARCHAR(50), + "PROJECT_UUID" VARCHAR(50), + "MODULE_UUID" VARCHAR(50), + "MODULE_UUID_PATH" VARCHAR(4000), + "NAME" VARCHAR(256), + "DESCRIPTION" VARCHAR(2000), + "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10), + "DEPRECATED_KEE" VARCHAR(400), + "PATH" VARCHAR(2000), + "LANGUAGE" VARCHAR(20), + "COPY_RESOURCE_ID" INTEGER, + "LONG_NAME" VARCHAR(256), + "PERSON_ID" INTEGER, + "CREATED_AT" TIMESTAMP +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddIssuesColumnsTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddIssuesColumnsTest/schema.sql new file mode 100644 index 00000000000..3e799c31508 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddIssuesColumnsTest/schema.sql @@ -0,0 +1,26 @@ +CREATE TABLE "ISSUES" ( + "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(50) UNIQUE NOT NULL, + "COMPONENT_ID" INTEGER NOT NULL, + "ROOT_COMPONENT_ID" INTEGER, + "RULE_ID" INTEGER, + "SEVERITY" VARCHAR(10), + "MANUAL_SEVERITY" BOOLEAN NOT NULL, + "MESSAGE" VARCHAR(4000), + "LINE" INTEGER, + "EFFORT_TO_FIX" DOUBLE, + "TECHNICAL_DEBT" INTEGER, + "STATUS" VARCHAR(20), + "RESOLUTION" VARCHAR(20), + "CHECKSUM" VARCHAR(1000), + "REPORTER" VARCHAR(255), + "ASSIGNEE" VARCHAR(255), + "AUTHOR_LOGIN" VARCHAR(255), + "ACTION_PLAN_KEY" VARCHAR(50) NULL, + "ISSUE_ATTRIBUTES" VARCHAR(4000), + "ISSUE_CREATION_DATE" TIMESTAMP, + "ISSUE_CLOSE_DATE" TIMESTAMP, + "ISSUE_UPDATE_DATE" TIMESTAMP, + "CREATED_AT" BIGINT, + "UPDATED_AT" BIGINT +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/do_nothing_when_already_migrated.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/do_nothing_when_already_migrated.xml new file mode 100644 index 00000000000..5df0387b5f8 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/do_nothing_when_already_migrated.xml @@ -0,0 +1,73 @@ +<dataset> + + <characteristics id="1" kee="REUSABILITY" name="Reusability" parent_id="[null]" rule_id="[null]" + characteristic_order="1" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + <characteristics id="2" kee="REUSABILITY_COMPLIANCE" name="Reusability Compliance" parent_id="1" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2013-11-20" updated_at="[null]"/> + + <characteristics id="3" kee="PORTABILITY" name="Portability" parent_id="[null]" rule_id="[null]" + characteristic_order="2" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + <characteristics id="4" kee="PORTABILITY_COMPLIANCE" name="Portability Compliance" parent_id="3" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2013-11-20" updated_at="[null]"/> + + <characteristics id="5" kee="MAINTAINABILITY" name="Maintainability" parent_id="[null]" rule_id="[null]" + characteristic_order="3" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + <characteristics id="6" kee="MAINTAINABILITY_COMPLIANCE" name="Maintainability Compliance" parent_id="5" + rule_id="[null]" characteristic_order="[null]" enabled="[true]" + created_at="2013-11-20" updated_at="[null]"/> + + <characteristics id="7" kee="SECURITY" name="Security" parent_id="[null]" rule_id="[null]" characteristic_order="4" + enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + <characteristics id="8" kee="SECURITY_COMPLIANCE" name="Security Compliance" parent_id="7" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" created_at="2013-11-20" + updated_at="[null]"/> + + <characteristics id="9" kee="USABILITY" name="Usability" parent_id="[null]" rule_id="[null]" characteristic_order="5" + enabled="[true]" created_at="2013-11-20" + updated_at="[null]"/> + <characteristics id="10" kee="USABILITY_ACCESSIBILITY" name="Accessibility" parent_id="9" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" created_at="2013-11-20" + updated_at="[null]"/> + <characteristics id="11" kee="USABILITY_EASE_OF_USE" name="Ease of Use" parent_id="9" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" created_at="2013-11-20" + updated_at="[null]"/> + <characteristics id="12" kee="USABILITY_COMPLIANCE" name="Usability Compliance" parent_id="9" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2013-11-20" updated_at="[null]"/> + + <characteristics id="13" kee="EFFICIENCY" name="Efficiency" parent_id="[null]" rule_id="[null]" + characteristic_order="6" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-20"/> + <characteristics id="14" kee="EFFICIENCY_COMPLIANCE" name="Efficiency Compliance" parent_id="13" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2013-11-20" updated_at="[null]"/> + + <characteristics id="15" kee="CHANGEABILITY" name="Changeability" parent_id="[null]" rule_id="[null]" + characteristic_order="7" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-20"/> + <characteristics id="16" kee="CHANGEABILITY_COMPLIANCE" name="Changeability Compliance" parent_id="15" + rule_id="[null]" characteristic_order="[null]" enabled="[true]" + created_at="2013-11-20" updated_at="[null]"/> + + <characteristics id="17" kee="RELIABILITY" name="Reliability" parent_id="[null]" rule_id="[null]" + characteristic_order="8" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-20"/> + <characteristics id="18" kee="RELIABILITY_COMPLIANCE" name="Reliability Compliance" parent_id="17" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2013-11-20" updated_at="[null]"/> + + <characteristics id="19" kee="TESTABILITY" name="Testability" parent_id="[null]" rule_id="[null]" + characteristic_order="9" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-20"/> + <characteristics id="20" kee="TESTABILITY_COMPLIANCE" name="Testability Compliance" parent_id="19" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2013-11-20" updated_at="[null]"/> + + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/empty.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/empty.xml new file mode 100644 index 00000000000..871dedcb5e9 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/empty.xml @@ -0,0 +1,3 @@ +<dataset> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_compliance_already_exists_as_characteristic.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_compliance_already_exists_as_characteristic.xml new file mode 100644 index 00000000000..72521ba290d --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_compliance_already_exists_as_characteristic.xml @@ -0,0 +1,11 @@ +<dataset> + + <characteristics id="1" kee="REUSABILITY" name="Reusability" parent_id="[null]" rule_id="[null]" + characteristic_order="1" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <characteristics id="2" kee="REUSABILITY_COMPLIANCE" name="Compliance" parent_id="[null]" rule_id="[null]" + characteristic_order="2" enabled="[true]" created_at="2013-11-20" + updated_at="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_compliance_already_exists_under_wrong_characteristic.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_compliance_already_exists_under_wrong_characteristic.xml new file mode 100644 index 00000000000..62a08ca6f7c --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_compliance_already_exists_under_wrong_characteristic.xml @@ -0,0 +1,16 @@ +<dataset> + + <characteristics id="1" kee="REUSABILITY" name="Reusability" parent_id="[null]" rule_id="[null]" + characteristic_order="1" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <characteristics id="2" kee="PORTABILITY" name="Portability" parent_id="[null]" rule_id="[null]" + characteristic_order="2" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <characteristics id="3" kee="REUSABILITY_COMPLIANCE" name="Reusability Compliance" parent_id="2" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2013-11-20" + updated_at="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_usability_exists_as_sub_characteristic.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_usability_exists_as_sub_characteristic.xml new file mode 100644 index 00000000000..9db2b164d0d --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_usability_exists_as_sub_characteristic.xml @@ -0,0 +1,11 @@ +<dataset> + + <characteristics id="1" kee="REUSABILITY" name="Reusability" parent_id="[null]" rule_id="[null]" + characteristic_order="1" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <characteristics id="2" kee="USABILITY" name="Usability" parent_id="1" rule_id="[null]" characteristic_order="[null]" + enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/insert_usability_at_the_top_if_security_does_exists-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/insert_usability_at_the_top_if_security_does_exists-result.xml new file mode 100644 index 00000000000..62b66901fe8 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/insert_usability_at_the_top_if_security_does_exists-result.xml @@ -0,0 +1,38 @@ +<dataset> + + <!-- Oder has changed : this characteristic is now one step lower --> + <characteristics id="1" kee="REUSABILITY" name="Reusability" parent_id="[null]" rule_id="[null]" + characteristic_order="2" enabled="[true]" created_at="2013-11-20" + updated_at="2015-02-15"/> + + <!-- Oder has changed : this characteristic is now one step lower --> + <characteristics id="2" kee="PORTABILITY" name="Portability" parent_id="[null]" rule_id="[null]" + characteristic_order="3" enabled="[true]" created_at="2013-11-20" + updated_at="2015-02-15"/> + + <!-- New characteristic 'Usability' is on the top (order 1) --> + <characteristics id="3" kee="USABILITY" name="Usability" parent_id="[null]" rule_id="[null]" characteristic_order="1" + enabled="[true]" created_at="2015-02-15" + updated_at="[null]"/> + <characteristics id="4" kee="USABILITY_ACCESSIBILITY" name="Accessibility" parent_id="3" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" created_at="2015-02-15" + updated_at="[null]"/> + <characteristics id="5" kee="USABILITY_EASE_OF_USE" name="Ease of Use" parent_id="3" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" created_at="2015-02-15" + updated_at="[null]"/> + <characteristics id="6" kee="USABILITY_COMPLIANCE" name="Usability Compliance" parent_id="3" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2015-02-15" updated_at="[null]"/> + + + <!-- New sub characteristic 'Compliance' under Reusability --> + <characteristics id="7" kee="REUSABILITY_COMPLIANCE" name="Reusability Compliance" parent_id="1" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2015-02-15" updated_at="[null]"/> + + <!-- New sub characteristic 'Compliance' under Portability --> + <characteristics id="8" kee="PORTABILITY_COMPLIANCE" name="Portability Compliance" parent_id="2" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2015-02-15" updated_at="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/insert_usability_at_the_top_if_security_does_exists.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/insert_usability_at_the_top_if_security_does_exists.xml new file mode 100644 index 00000000000..a8394be84fa --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/insert_usability_at_the_top_if_security_does_exists.xml @@ -0,0 +1,11 @@ +<dataset> + + <characteristics id="1" kee="REUSABILITY" name="Reusability" parent_id="[null]" rule_id="[null]" + characteristic_order="1" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <characteristics id="2" kee="PORTABILITY" name="Portability" parent_id="[null]" rule_id="[null]" + characteristic_order="2" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/migrate-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/migrate-result.xml new file mode 100644 index 00000000000..b677f0f351a --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/migrate-result.xml @@ -0,0 +1,94 @@ +<dataset> + + <characteristics id="1" kee="REUSABILITY" name="Reusability" parent_id="[null]" rule_id="[null]" + characteristic_order="1" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <characteristics id="2" kee="PORTABILITY" name="Portability" parent_id="[null]" rule_id="[null]" + characteristic_order="2" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <characteristics id="3" kee="MAINTAINABILITY" name="Maintainability" parent_id="[null]" rule_id="[null]" + characteristic_order="3" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <characteristics id="4" kee="SECURITY" name="Security" parent_id="[null]" rule_id="[null]" characteristic_order="4" + enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <!-- Oder has changed : this characteristic is now one step lower --> + <characteristics id="5" kee="EFFICIENCY" name="Efficiency" parent_id="[null]" rule_id="[null]" + characteristic_order="6" enabled="[true]" created_at="2013-11-20" + updated_at="2015-02-15"/> + + <!-- Oder has changed : this characteristic is now one step lower --> + <characteristics id="6" kee="CHANGEABILITY" name="Changeability" parent_id="[null]" rule_id="[null]" + characteristic_order="7" enabled="[true]" created_at="2013-11-20" + updated_at="2015-02-15"/> + + <!-- Oder has changed : this characteristic is now one step lower --> + <characteristics id="7" kee="RELIABILITY" name="Reliability" parent_id="[null]" rule_id="[null]" + characteristic_order="8" enabled="[true]" created_at="2013-11-20" + updated_at="2015-02-15"/> + + <!-- Oder has changed : this characteristic is now one step lower --> + <characteristics id="8" kee="TESTABILITY" name="Testability" parent_id="[null]" rule_id="[null]" + characteristic_order="9" enabled="[true]" created_at="2013-11-20" + updated_at="2015-02-15"/> + + <!-- New characteristic 'Usability' is after Security --> + <characteristics id="9" kee="USABILITY" name="Usability" parent_id="[null]" rule_id="[null]" characteristic_order="5" + enabled="[true]" created_at="2015-02-15" + updated_at="[null]"/> + <!-- New sub characteristics under Usability --> + <characteristics id="10" kee="USABILITY_ACCESSIBILITY" name="Accessibility" parent_id="9" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" created_at="2015-02-15" + updated_at="[null]"/> + <characteristics id="11" kee="USABILITY_EASE_OF_USE" name="Ease of Use" parent_id="9" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" created_at="2015-02-15" + updated_at="[null]"/> + <characteristics id="12" kee="USABILITY_COMPLIANCE" name="Usability Compliance" parent_id="9" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2015-02-15" updated_at="[null]"/> + + <!-- New sub characteristic 'Compliance' under Reusability --> + <characteristics id="13" kee="REUSABILITY_COMPLIANCE" name="Reusability Compliance" parent_id="1" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2015-02-15" updated_at="[null]"/> + + <!-- New sub characteristic 'Compliance' under Portability --> + <characteristics id="14" kee="PORTABILITY_COMPLIANCE" name="Portability Compliance" parent_id="2" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2015-02-15" updated_at="[null]"/> + + <!-- New sub characteristic 'Compliance' under Maintainability --> + <characteristics id="15" kee="MAINTAINABILITY_COMPLIANCE" name="Maintainability Compliance" parent_id="3" + rule_id="[null]" characteristic_order="[null]" enabled="[true]" + created_at="2015-02-15" updated_at="[null]"/> + + <!-- New sub characteristic 'Compliance' under Security --> + <characteristics id="16" kee="SECURITY_COMPLIANCE" name="Security Compliance" parent_id="4" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2015-02-15" updated_at="[null]"/> + + <!-- New sub characteristic 'Compliance' under Efficiency --> + <characteristics id="17" kee="EFFICIENCY_COMPLIANCE" name="Efficiency Compliance" parent_id="5" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2015-02-15" updated_at="[null]"/> + + <!-- New sub characteristic 'Compliance' under Changeability --> + <characteristics id="18" kee="CHANGEABILITY_COMPLIANCE" name="Changeability Compliance" parent_id="6" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2015-02-15" updated_at="[null]"/> + + <!-- New sub characteristic 'Compliance' under Reliability --> + <characteristics id="19" kee="RELIABILITY_COMPLIANCE" name="Reliability Compliance" parent_id="7" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2015-02-15" updated_at="[null]"/> + + <!-- New sub characteristic 'Compliance' under Testability --> + <characteristics id="20" kee="TESTABILITY_COMPLIANCE" name="Testability Compliance" parent_id="8" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2015-02-15" updated_at="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/migrate.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/migrate.xml new file mode 100644 index 00000000000..52505623c3d --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/migrate.xml @@ -0,0 +1,35 @@ +<dataset> + + <characteristics id="1" kee="REUSABILITY" name="Reusability" parent_id="[null]" rule_id="[null]" + characteristic_order="1" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <characteristics id="2" kee="PORTABILITY" name="Portability" parent_id="[null]" rule_id="[null]" + characteristic_order="2" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <characteristics id="3" kee="MAINTAINABILITY" name="Maintainability" parent_id="[null]" rule_id="[null]" + characteristic_order="3" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <characteristics id="4" kee="SECURITY" name="Security" parent_id="[null]" rule_id="[null]" characteristic_order="4" + enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <characteristics id="5" kee="EFFICIENCY" name="Efficiency" parent_id="[null]" rule_id="[null]" + characteristic_order="5" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <characteristics id="6" kee="CHANGEABILITY" name="Changeability" parent_id="[null]" rule_id="[null]" + characteristic_order="6" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <characteristics id="7" kee="RELIABILITY" name="Reliability" parent_id="[null]" rule_id="[null]" + characteristic_order="7" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <characteristics id="8" kee="TESTABILITY" name="Testability" parent_id="[null]" rule_id="[null]" + characteristic_order="8" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/not_fail_if_some_deprecated_requirements_still_exists_in_db.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/not_fail_if_some_deprecated_requirements_still_exists_in_db.xml new file mode 100644 index 00000000000..81050d0ee0c --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/not_fail_if_some_deprecated_requirements_still_exists_in_db.xml @@ -0,0 +1,19 @@ +<dataset> + + <characteristics id="1" kee="USABILITY" name="Usability" parent_id="[null]" rule_id="[null]" characteristic_order="1" + enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + <characteristics id="2" kee="USABILITY_ACCESSIBILITY" name="Accessibility" parent_id="1" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" created_at="2013-11-20" + updated_at="[null]"/> + <characteristics id="3" kee="USABILITY_EASE_OF_USE" name="Ease of Use" parent_id="1" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" created_at="2013-11-20" + updated_at="[null]"/> + <characteristics id="4" kee="USABILITY_COMPLIANCE" name="Usability Compliance" parent_id="1" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2013-11-20" updated_at="[null]"/> + + <characteristics id="5" kee="[null]" name="[null]" parent_id="3" rule_id="3" characteristic_order="[null]" + enabled="[true]" created_at="2013-11-20" updated_at="2013-11-22"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/schema.sql new file mode 100644 index 00000000000..98c025def6b --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/schema.sql @@ -0,0 +1,11 @@ +CREATE TABLE "CHARACTERISTICS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(100), + "NAME" VARCHAR(100), + "PARENT_ID" INTEGER, + "RULE_ID" INTEGER, + "CHARACTERISTIC_ORDER" INTEGER, + "ENABLED" BOOLEAN, + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/update_usability_if_already_exists-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/update_usability_if_already_exists-result.xml new file mode 100644 index 00000000000..86851f3d471 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/update_usability_if_already_exists-result.xml @@ -0,0 +1,38 @@ +<dataset> + + <characteristics id="1" kee="SECURITY" name="Security" parent_id="[null]" rule_id="[null]" characteristic_order="4" + enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <!-- Oder has changed : this characteristic is now one step lower --> + <characteristics id="2" kee="EFFICIENCY" name="Efficiency" parent_id="[null]" rule_id="[null]" + characteristic_order="6" enabled="[true]" created_at="2013-11-20" + updated_at="2015-02-15"/> + + <!-- Usability is moved after Security --> + <characteristics id="3" kee="USABILITY" name="Usability" parent_id="[null]" rule_id="[null]" characteristic_order="5" + enabled="[true]" created_at="2013-11-20" + updated_at="2015-02-15"/> + + <!-- New sub characteristics under Usability --> + <characteristics id="4" kee="USABILITY_ACCESSIBILITY" name="Accessibility" parent_id="3" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" created_at="2015-02-15" + updated_at="[null]"/> + <characteristics id="5" kee="USABILITY_EASE_OF_USE" name="Ease of Use" parent_id="3" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" created_at="2015-02-15" + updated_at="[null]"/> + <characteristics id="6" kee="USABILITY_COMPLIANCE" name="Usability Compliance" parent_id="3" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2015-02-15" updated_at="[null]"/> + + <!-- New sub characteristic 'Compliance' under Security --> + <characteristics id="7" kee="SECURITY_COMPLIANCE" name="Security Compliance" parent_id="1" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" created_at="2015-02-15" + updated_at="[null]"/> + + <!-- New sub characteristic 'Compliance' under Efficiency --> + <characteristics id="8" kee="EFFICIENCY_COMPLIANCE" name="Efficiency Compliance" parent_id="2" rule_id="[null]" + characteristic_order="[null]" enabled="[true]" + created_at="2015-02-15" updated_at="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/update_usability_if_already_exists.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/update_usability_if_already_exists.xml new file mode 100644 index 00000000000..2e75b7324e7 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/update_usability_if_already_exists.xml @@ -0,0 +1,16 @@ +<dataset> + + <characteristics id="1" kee="SECURITY" name="Security" parent_id="[null]" rule_id="[null]" characteristic_order="4" + enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <characteristics id="2" kee="EFFICIENCY" name="Efficiency" parent_id="[null]" rule_id="[null]" + characteristic_order="5" enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + + <!-- Usability should be move after Security --> + <characteristics id="3" kee="USABILITY" name="Usability" parent_id="[null]" rule_id="[null]" characteristic_order="6" + enabled="[true]" created_at="2013-11-20" + updated_at="2013-11-22"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/before.xml new file mode 100644 index 00000000000..0a7b5aa0cf1 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/before.xml @@ -0,0 +1,49 @@ +<dataset> + + <!-- Should contains Simon B, simon and simon@codehaus.org --> + <users id="1" login="simon" name="Simon" active="[true]" email="simon@email.com" scm_accounts="[null]" + created_at="1500000000000" updated_at="1500000000000"/> + + <!-- Authors contains login, email and fab -> SCM accounts should contains only fab --> + <users id="2" login="fabrice" name="Fabrice" active="[true]" email="fabrice@email.com" scm_accounts="[null]" + created_at="1500000000000" updated_at="1500000000000"/> + + <!-- Authors contains only login and email -> Nothing to do --> + <users id="3" login="jb" name="Jean Baptiste" active="[true]" email="jb@email.com" scm_accounts="[null]" + created_at="1500000000000" updated_at="1500000000000"/> + + <!-- Only one author row -> Nothing to do --> + <users id="4" login="julien" name="Julien" active="[true]" email="julien@email.com" scm_accounts="[null]" + created_at="1500000000000" updated_at="1500000000000"/> + + <!-- Disable user -> Nothing to do --> + <users id="5" login="disable" name="Disable" active="[false]" email="disable@email.com" scm_accounts="[null]" + created_at="1500000000000" updated_at="1500000000000"/> + + <!-- 2 users with the same email -> Nothing to do --> + <users id="6" login="teryk" name="Teryk" active="[true]" email="teryk@email.com" scm_accounts="[null]" + created_at="1500000000000" updated_at="1500000000000"/> + <users id="7" login="teryk2" name="Teryk" active="[true]" email="teryk@email.com" scm_accounts="[null]" + created_at="1500000000000" updated_at="1500000000000"/> + + + <authors id="1" person_id="1" login="Simon B" created_at="2015-01-01" updated_at="2015-01-01"/> + <authors id="2" person_id="1" login="simon" created_at="2015-01-01" updated_at="2015-01-01"/> + <authors id="3" person_id="1" login="simon@codehaus.org" created_at="2015-01-01" updated_at="2015-01-01"/> + + <authors id="4" person_id="2" login="fabrice@email.com" created_at="2015-01-01" updated_at="2015-01-01"/> + <authors id="5" person_id="2" login="fab" created_at="2015-01-01" updated_at="2015-01-01"/> + <authors id="6" person_id="2" login="fabrice" created_at="2015-01-01" updated_at="2015-01-01"/> + + <authors id="7" person_id="3" login="jb@email.com" created_at="2015-01-01" updated_at="2015-01-01"/> + <authors id="8" person_id="3" login="jb" created_at="2015-01-01" updated_at="2015-01-01"/> + + <authors id="9" person_id="4" login="julien" created_at="2015-01-01" updated_at="2015-01-01"/> + + <authors id="10" person_id="5" login="disable" created_at="2015-01-01" updated_at="2015-01-01"/> + <authors id="11" person_id="5" login="Disable user" created_at="2015-01-01" updated_at="2015-01-01"/> + + <authors id="12" person_id="6" login="teryk@email.com" created_at="2015-01-01" updated_at="2015-01-01"/> + <authors id="13" person_id="6" login="teryk_b" created_at="2015-01-01" updated_at="2015-01-01"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/no_authors.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/no_authors.xml new file mode 100644 index 00000000000..3f2da7a6af2 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/no_authors.xml @@ -0,0 +1,24 @@ +<dataset> + + <users id="1" login="simon" name="Simon" active="[true]" email="simon@email.com" scm_accounts="[null]" + created_at="1500000000000" updated_at="1500000000000"/> + + <users id="2" login="fabrice" name="Fabrice" active="[true]" email="fabrice@email.com" scm_accounts="[null]" + created_at="1500000000000" updated_at="1500000000000"/> + + <users id="3" login="jb" name="Jean Baptiste" active="[true]" email="jb@email.com" scm_accounts="[null]" + created_at="1500000000000" updated_at="1500000000000"/> + + <users id="4" login="julien" name="Julien" active="[true]" email="julien@email.com" scm_accounts="[null]" + created_at="1500000000000" updated_at="1500000000000"/> + + <users id="5" login="disable" name="Disable" active="[false]" email="disable@email.com" scm_accounts="[null]" + created_at="1500000000000" updated_at="1500000000000"/> + + <users id="6" login="teryk" name="Teryk" active="[true]" email="teryk@email.com" scm_accounts="[null]" + created_at="1500000000000" updated_at="1500000000000"/> + + <users id="7" login="teryk2" name="Teryk" active="[true]" email="teryk@email.com" scm_accounts="[null]" + created_at="1500000000000" updated_at="1500000000000"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/schema.sql new file mode 100644 index 00000000000..8dbd8b01ea9 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/schema.sql @@ -0,0 +1,22 @@ +CREATE TABLE "USERS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "LOGIN" VARCHAR(255), + "NAME" VARCHAR(200), + "EMAIL" VARCHAR(100), + "CRYPTED_PASSWORD" VARCHAR(40), + "SALT" VARCHAR(40), + "REMEMBER_TOKEN" VARCHAR(500), + "REMEMBER_TOKEN_EXPIRES_AT" TIMESTAMP, + "ACTIVE" BOOLEAN DEFAULT TRUE, + "SCM_ACCOUNTS" VARCHAR(4000), + "CREATED_AT" BIGINT, + "UPDATED_AT" BIGINT +); + +CREATE TABLE "AUTHORS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "PERSON_ID" INTEGER, + "LOGIN" VARCHAR(100), + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest/before.xml new file mode 100644 index 00000000000..c0d5b5e59ec --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest/before.xml @@ -0,0 +1,52 @@ +<dataset> + <!-- new migration --> + <analysis_reports + id="1" + project_key="123456789-987654321" + snapshot_id="123" + report_data="data-project" + report_status="WORKING" + created_at="2014-09-25" + updated_at="2014-09-24" + started_at="2014-09-23" + finished_at="2014-09-22" + created_at_ms="[null]" + updated_at_ms="[null]" + started_at_ms="[null]" + finished_at_ms="[null]" + /> + + <!-- re-entrant migration - ignore the issues that are already fed with new dates --> + <analysis_reports + id="2" + project_key="123456789-987654321" + snapshot_id="123" + report_data="data-project" + report_status="WORKING" + created_at="2014-09-25" + updated_at="2014-09-24" + started_at="2014-09-23" + finished_at="2014-09-22" + created_at_ms="1500000000000" + updated_at_ms="1500000000000" + started_at_ms="1500000000000" + finished_at_ms="1500000000000" + /> + + <!-- NULL dates --> + <analysis_reports + id="3" + project_key="123456789-987654321" + snapshot_id="123" + report_data="data-project" + report_status="WORKING" + created_at="[null]" + updated_at="[null]" + started_at="[null]" + finished_at="[null]" + created_at_ms="[null]" + updated_at_ms="[null]" + started_at_ms="[null]" + finished_at_ms="[null]" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest/schema.sql new file mode 100644 index 00000000000..c2187b6a747 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest/schema.sql @@ -0,0 +1,16 @@ +CREATE TABLE "ANALYSIS_REPORTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "PROJECT_KEY" VARCHAR(400) NOT NULL, + "PROJECT_NAME" VARCHAR(256) NULL, + "SNAPSHOT_ID" INTEGER NOT NULL, + "REPORT_STATUS" VARCHAR(20) NOT NULL, + "REPORT_DATA" BLOB(2147483647), + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP, + "STARTED_AT" TIMESTAMP, + "FINISHED_AT" TIMESTAMP, + "CREATED_AT_MS" BIGINT, + "UPDATED_AT_MS" BIGINT, + "STARTED_AT_MS" BIGINT, + "FINISHED_AT_MS" BIGINT +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedEventsLongDatesTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedEventsLongDatesTest/before.xml new file mode 100644 index 00000000000..db9753d85be --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedEventsLongDatesTest/before.xml @@ -0,0 +1,28 @@ +<dataset> + <!-- new migration --> + <events + id="1" + created_at="2014-09-25" + created_at_ms="[null]" + event_date="2014-09-25" + event_date_ms="[null]" + /> + + <!-- re-entrant migration - ignore the ones that are already fed with new dates --> + <events + id="2" + created_at="2014-09-25" + created_at_ms="1500000000" + event_date="2014-09-25" + event_date_ms="1500000000" + /> + + <!-- NULL dates --> + <events + id="3" + created_at="[null]" + created_at_ms="[null]" + event_date="[null]" + event_date_ms="[null]" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedEventsLongDatesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedEventsLongDatesTest/schema.sql new file mode 100644 index 00000000000..71ac42d40ef --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedEventsLongDatesTest/schema.sql @@ -0,0 +1,7 @@ +CREATE TABLE "EVENTS" ( + "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "CREATED_AT" TIMESTAMP, + "CREATED_AT_MS" BIGINT, + "EVENT_DATE" TIMESTAMP, + "EVENT_DATE_MS" BIGINT +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/bad_data.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/bad_data.xml new file mode 100644 index 00000000000..b4e95d8a3ea --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/bad_data.xml @@ -0,0 +1,8 @@ +<dataset> + <file_sources id="1" project_uuid="PROJECT_UUID" file_uuid="FILE1_UUID" created_at="1416238020000" + updated_at="1414770242000" + data=""missing_escape_end" + binary_data="[null]" + line_hashes="" + data_hash=""/> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/data.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/data.xml new file mode 100644 index 00000000000..df9b36ac5a2 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/data.xml @@ -0,0 +1,25 @@ +<dataset> + <!-- has data --> + <file_sources id="1" project_uuid="PROJECT_UUID" file_uuid="FILE1_UUID" created_at="1416238020000" + updated_at="1414770242000" + data="aef12a,alice,2014-04-25T12:34:56+0100,1,4,2,2,5,3,3,6,4,syntax_highlighting,symbol_refs,22,class Foo { abe465,bob,2014-07-25T12:34:56+0100,,,,,,,,,,,,2, // Empty afb789,carol,2014-03-23T12:34:56+0100,0,,,0,,,0,,,,,,} afb789,carol,2014-03-23T12:34:56+0100,,,,,,,,,,,,, " + binary_data="[null]" + line_hashes="" + data_hash=""/> + + <!-- empty fields in CSV --> + <file_sources id="2" project_uuid="PROJECT_UUID" file_uuid="FILE2_UUID" created_at="1416238020000" + updated_at="1414770242000" + data=",,,,,,,,,,,,,,, ,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,, " + binary_data="[null]" + line_hashes="" + data_hash=""/> + + <!-- null CSV --> + <file_sources id="3" project_uuid="PROJECT_UUID" file_uuid="FILE2_UUID" created_at="1416238020000" + updated_at="1414770242000" + data="[null]" + binary_data="[null]" + line_hashes="" + data_hash=""/> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/schema.sql new file mode 100644 index 00000000000..5649f795864 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/schema.sql @@ -0,0 +1,12 @@ +CREATE TABLE "FILE_SOURCES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "PROJECT_UUID" VARCHAR(50) NOT NULL, + "FILE_UUID" VARCHAR(50) NOT NULL, + "LINE_HASHES" CLOB(2147483647), + "DATA" CLOB(2147483647), + "DATA_HASH" VARCHAR(50) NOT NULL, + "SRC_HASH" VARCHAR(50) NULL, + "CREATED_AT" BIGINT NOT NULL, + "UPDATED_AT" BIGINT NOT NULL, + "BINARY_DATA" BINARY(167772150), +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest/before.xml new file mode 100644 index 00000000000..e8e59f0d053 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest/before.xml @@ -0,0 +1,31 @@ +<dataset> + + <!-- new migration --> + <issue_changes id="1" kee="ABC-DEF" issue_key="ABC" user_login="[null]" change_type="[null]" change_data="[null]" + created_at="2013-05-18" + updated_at="2013-05-18" + issue_change_creation_date="2013-05-18" + created_at_ms="[null]" + updated_at_ms="[null]" + issue_change_creation_date_ms="[null]"/> + /> + + <!-- re-entrant migration - ignore the issues that are already fed with new dates --> + <issue_changes id="2" kee="FGH-DEF" issue_key="FGH" user_login="[null]" change_type="[null]" change_data="[null]" + created_at="2013-05-18" + updated_at="2013-05-18" + issue_change_creation_date="2013-05-18" + created_at_ms="1500000000000" + updated_at_ms="1500000000000" + issue_change_creation_date_ms="1500000000000"/> + + <!-- NULL dates --> + <issue_changes id="3" kee="MISSING-DEF" issue_key="MISSING" user_login="[null]" change_type="[null]" + change_data="[null]" + created_at="[null]" + updated_at="[null]" + issue_change_creation_date="[null]" + created_at_ms="[null]" + updated_at_ms="[null]" + issue_change_creation_date_ms="[null]"/> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest/schema.sql new file mode 100644 index 00000000000..240e5cedf2d --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest/schema.sql @@ -0,0 +1,14 @@ +CREATE TABLE "ISSUE_CHANGES" ( + "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(50), + "ISSUE_KEY" VARCHAR(50) NOT NULL, + "USER_LOGIN" VARCHAR(255), + "CHANGE_TYPE" VARCHAR(40), + "CHANGE_DATA" VARCHAR(16777215), + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP, + "ISSUE_CHANGE_CREATION_DATE" TIMESTAMP, + "CREATED_AT_MS" BIGINT, + "UPDATED_AT_MS" BIGINT, + "ISSUE_CHANGE_CREATION_DATE_MS" BIGINT +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/after-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/after-result.xml new file mode 100644 index 00000000000..0422433b393 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/after-result.xml @@ -0,0 +1,22 @@ +<dataset> + <issues id="1" kee="ABC" + component_id="100" component_uuid="COMPONENTUUID" root_component_id="10" project_uuid="PROJECTUUID" + resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" author_login="[null]" checksum="[null]" effort_to_fix="[null]" technical_debt="10" + message="[null]" line="5000" rule_id="10" reporter="emmerik" issue_attributes="foo=bar" + action_plan_key="[null]" tags="[null]" + issue_creation_date="2013-05-18" issue_update_date="2013-05-18" issue_close_date="2013-05-18" + created_at="1500000000000" updated_at="1500000000000" + /> + + <!-- re-entrant migration - ignore the issues that are already fed with uuids --> + <issues id="2" kee="DEF" + component_id="101" component_uuid="ANOTHERUUID" root_component_id="11" project_uuid="ANOTHER2UUID" + resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" author_login="[null]" checksum="[null]" effort_to_fix="[null]" technical_debt="10" + message="[null]" line="5000" rule_id="10" reporter="emmerik" issue_attributes="foo=bar" + action_plan_key="[null]" tags="[null]" + issue_creation_date="2013-05-18" issue_update_date="2013-05-18" issue_close_date="2013-05-18" + created_at="1500000000000" updated_at="1500000000000" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/before.xml new file mode 100644 index 00000000000..fbcd05d6875 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/before.xml @@ -0,0 +1,30 @@ +<dataset> + <projects long_name="org.struts.RequestContext" id="100" scope="FIL" qualifier="FIL" + kee="org.struts:struts-core:src/org/struts/RequestContext.java" + uuid="COMPONENTUUID" project_uuid="PROJECTUUID" module_uuid="[null]" module_uuid_path="[null]" + name="RequestContext.java" root_id="2" + description="[null]" deprecated_kee="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" + path="src/org/struts/RequestContext.java" created_at="2014-06-18"/> + + <issues id="1" kee="ABC" + component_id="100" component_uuid="[null]" root_component_id="10" project_uuid="[null]" + resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" author_login="[null]" checksum="[null]" effort_to_fix="[null]" technical_debt="10" + message="[null]" line="5000" rule_id="10" reporter="emmerik" issue_attributes="foo=bar" + action_plan_key="[null]" tags="[null]" + issue_creation_date="2013-05-18" issue_update_date="2013-05-18" issue_close_date="2013-05-18" + created_at="1500000000000" updated_at="1500000000000" + /> + + <!-- re-entrant migration - ignore the issues that are already fed with uuids --> + <issues id="2" kee="DEF" + component_id="101" component_uuid="ANOTHERUUID" root_component_id="11" project_uuid="ANOTHER2UUID" + resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" author_login="[null]" checksum="[null]" effort_to_fix="[null]" technical_debt="10" + message="[null]" line="5000" rule_id="10" reporter="emmerik" issue_attributes="foo=bar" + action_plan_key="[null]" tags="[null]" + issue_creation_date="2013-05-18" issue_update_date="2013-05-18" issue_close_date="2013-05-18" + created_at="1500000000000" updated_at="1500000000000" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/schema.sql new file mode 100644 index 00000000000..b7157762feb --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/schema.sql @@ -0,0 +1,52 @@ +CREATE TABLE "PROJECTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(400), + "ROOT_ID" INTEGER, + "UUID" VARCHAR(50), + "PROJECT_UUID" VARCHAR(50), + "MODULE_UUID" VARCHAR(50), + "MODULE_UUID_PATH" VARCHAR(4000), + "NAME" VARCHAR(256), + "DESCRIPTION" VARCHAR(2000), + "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10), + "DEPRECATED_KEE" VARCHAR(400), + "PATH" VARCHAR(2000), + "LANGUAGE" VARCHAR(20), + "COPY_RESOURCE_ID" INTEGER, + "LONG_NAME" VARCHAR(256), + "PERSON_ID" INTEGER, + "CREATED_AT" TIMESTAMP, + "AUTHORIZATION_UPDATED_AT" BIGINT +); + +CREATE TABLE "ISSUES" ( + "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(50) UNIQUE NOT NULL, + "COMPONENT_ID" INTEGER NOT NULL, + "COMPONENT_UUID" VARCHAR(50), + "ROOT_COMPONENT_ID" INTEGER, + "PROJECT_UUID" VARCHAR(50), + "RULE_ID" INTEGER, + "SEVERITY" VARCHAR(10), + "MANUAL_SEVERITY" BOOLEAN NOT NULL, + "MESSAGE" VARCHAR(4000), + "LINE" INTEGER, + "EFFORT_TO_FIX" DOUBLE, + "TECHNICAL_DEBT" INTEGER, + "STATUS" VARCHAR(20), + "RESOLUTION" VARCHAR(20), + "CHECKSUM" VARCHAR(1000), + "REPORTER" VARCHAR(255), + "ASSIGNEE" VARCHAR(255), + "AUTHOR_LOGIN" VARCHAR(255), + "ACTION_PLAN_KEY" VARCHAR(50) NULL, + "ISSUE_ATTRIBUTES" VARCHAR(4000), + "TAGS" VARCHAR(4000), + "ISSUE_CREATION_DATE" TIMESTAMP, + "ISSUE_CLOSE_DATE" TIMESTAMP, + "ISSUE_UPDATE_DATE" TIMESTAMP, + "CREATED_AT" BIGINT, + "UPDATED_AT" BIGINT +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/after-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/after-result.xml new file mode 100644 index 00000000000..329a3f58f48 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/after-result.xml @@ -0,0 +1,135 @@ +<dataset> + + <issues id="1" kee="ABC" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" + author_login="[null]" + checksum="[null]" + effort_to_fix="[null]" + technical_debt="10" + message="[null]" + line="5000" + component_id="100" + root_component_id="10" + rule_id="10" + reporter="emmerik" + issue_attributes="foo=bar" + action_plan_key="[null]" + tags="tag1,tag2,tag3,tag4" + issue_creation_date="2013-05-18" + issue_update_date="2013-05-18" + issue_close_date="2013-05-18" + created_at="1500000000000" + updated_at="1418056380000" + /> + + <issues id="2" kee="DEF" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" + author_login="[null]" + checksum="[null]" + effort_to_fix="[null]" + technical_debt="10" + message="[null]" + line="5000" + component_id="100" + root_component_id="10" + rule_id="10" + reporter="emmerik" + issue_attributes="foo=bar" + tags="polop,palap" + action_plan_key="[null]" + issue_creation_date="2013-05-18" + issue_update_date="2013-05-18" + issue_close_date="2013-05-18" + created_at="1500000000000" + updated_at="1500000000000" + /> + + <issues id="3" kee="GHI" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" + author_login="[null]" + checksum="[null]" + effort_to_fix="[null]" + technical_debt="10" + message="[null]" + line="5000" + component_id="100" + root_component_id="10" + rule_id="20" + reporter="emmerik" + issue_attributes="foo=bar" + action_plan_key="[null]" + tags="tag3,tag4" + issue_creation_date="2013-05-18" + issue_update_date="2013-05-18" + issue_close_date="2013-05-18" + created_at="1500000000000" + updated_at="1418056380000" + /> + + <issues id="4" kee="JKL" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" + author_login="[null]" + checksum="[null]" + effort_to_fix="[null]" + technical_debt="10" + message="[null]" + line="5000" + component_id="100" + root_component_id="10" + rule_id="30" + reporter="emmerik" + issue_attributes="foo=bar" + action_plan_key="[null]" + tags="tag1,tag2" + issue_creation_date="2013-05-18" + issue_update_date="2013-05-18" + issue_close_date="2013-05-18" + created_at="1500000000000" + updated_at="1418056380000" + /> + + <issues id="5" kee="MNO" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" + author_login="[null]" + checksum="[null]" + effort_to_fix="[null]" + technical_debt="10" + message="[null]" + line="5000" + component_id="100" + root_component_id="10" + rule_id="40" + reporter="emmerik" + issue_attributes="foo=bar" + action_plan_key="[null]" + tags="[null]" + issue_creation_date="2013-05-18" + issue_update_date="2013-05-18" + issue_close_date="2013-05-18" + created_at="1500000000000" + updated_at="1500000000000" + /> + + <issues id="6" kee="PQR" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" + author_login="[null]" + checksum="[null]" + effort_to_fix="[null]" + technical_debt="10" + message="[null]" + line="5000" + component_id="100" + root_component_id="10" + rule_id="666" + reporter="emmerik" + issue_attributes="foo=bar" + action_plan_key="[null]" + tags="[null]" + issue_creation_date="2013-05-18" + issue_update_date="2013-05-18" + issue_close_date="2013-05-18" + created_at="1500000000000" + updated_at="1500000000000" + /> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/before.xml new file mode 100644 index 00000000000..63b14662f3d --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/before.xml @@ -0,0 +1,185 @@ +<dataset> + + <rules id="10" plugin_rule_key="Rule1" plugin_name="xoo" name="Rule1" description="Rule1" status="READY" priority="1" + language="xoo" + note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]" + description_format="HTML" plugin_config_key="[null]" + tags="tag3,tag4" system_tags="tag1,tag2" + characteristic_id="[null]" default_characteristic_id="[null]" + remediation_function="[null]" default_remediation_function="[null]" + remediation_coeff="[null]" default_remediation_coeff="[null]" + remediation_offset="[null]" default_remediation_offset="[null]" + effort_to_fix_description="[null]" + is_template="[false]" template_id="[null]" created_at="2014-01-01" updated_at="2014-01-01"/> + + <rules id="20" plugin_rule_key="Rule2" plugin_name="xoo" name="Rule2" description="Rule2" status="READY" priority="1" + language="xoo" + note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]" + description_format="HTML" plugin_config_key="[null]" + tags="tag3,tag4" system_tags="" + characteristic_id="[null]" default_characteristic_id="[null]" + remediation_function="[null]" default_remediation_function="[null]" + remediation_coeff="[null]" default_remediation_coeff="[null]" + remediation_offset="[null]" default_remediation_offset="[null]" + effort_to_fix_description="[null]" + is_template="[false]" template_id="[null]" created_at="2014-01-01" updated_at="2014-01-01"/> + + <rules id="30" plugin_rule_key="Rule3" plugin_name="xoo" name="Rule3" description="Rule3" status="READY" priority="1" + language="xoo" + note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]" + description_format="HTML" plugin_config_key="[null]" + tags="[null]" system_tags="tag1,tag2" + characteristic_id="[null]" default_characteristic_id="[null]" + remediation_function="[null]" default_remediation_function="[null]" + remediation_coeff="[null]" default_remediation_coeff="[null]" + remediation_offset="[null]" default_remediation_offset="[null]" + effort_to_fix_description="[null]" + is_template="[false]" template_id="[null]" created_at="2014-01-01" updated_at="2014-01-01"/> + + <rules id="40" plugin_rule_key="Rule4" plugin_name="xoo" name="Rule4" description="Rule4" status="READY" priority="1" + language="xoo" + note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]" + description_format="HTML" plugin_config_key="[null]" + tags="[null]" system_tags="[null]" + characteristic_id="[null]" default_characteristic_id="[null]" + remediation_function="[null]" default_remediation_function="[null]" + remediation_coeff="[null]" default_remediation_coeff="[null]" + remediation_offset="[null]" default_remediation_offset="[null]" + effort_to_fix_description="[null]" + is_template="[false]" template_id="[null]" created_at="2014-01-01" updated_at="2014-01-01"/> + + + <issues id="1" kee="ABC" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" + author_login="[null]" + checksum="[null]" + effort_to_fix="[null]" + technical_debt="10" + message="[null]" + line="5000" + component_id="100" + root_component_id="10" + rule_id="10" + reporter="emmerik" + issue_attributes="foo=bar" + action_plan_key="[null]" + tags="[null]" + issue_creation_date="2013-05-18" + issue_update_date="2013-05-18" + issue_close_date="2013-05-18" + created_at="1500000000000" + updated_at="1500000000000" + /> + + <!-- re-entrant migration - ignore the issues that are already fed with new dates --> + <issues id="2" kee="DEF" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" + author_login="[null]" + checksum="[null]" + effort_to_fix="[null]" + technical_debt="10" + message="[null]" + line="5000" + component_id="100" + root_component_id="10" + rule_id="10" + reporter="emmerik" + issue_attributes="foo=bar" + tags="polop,palap" + action_plan_key="[null]" + issue_creation_date="2013-05-18" + issue_update_date="2013-05-18" + issue_close_date="2013-05-18" + created_at="1500000000000" + updated_at="1500000000000" + /> + + <issues id="3" kee="GHI" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" + author_login="[null]" + checksum="[null]" + effort_to_fix="[null]" + technical_debt="10" + message="[null]" + line="5000" + component_id="100" + root_component_id="10" + rule_id="20" + reporter="emmerik" + issue_attributes="foo=bar" + action_plan_key="[null]" + tags="[null]" + issue_creation_date="2013-05-18" + issue_update_date="2013-05-18" + issue_close_date="2013-05-18" + created_at="1500000000000" + updated_at="1500000000000" + /> + + <issues id="4" kee="JKL" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" + author_login="[null]" + checksum="[null]" + effort_to_fix="[null]" + technical_debt="10" + message="[null]" + line="5000" + component_id="100" + root_component_id="10" + rule_id="30" + reporter="emmerik" + issue_attributes="foo=bar" + action_plan_key="[null]" + tags="[null]" + issue_creation_date="2013-05-18" + issue_update_date="2013-05-18" + issue_close_date="2013-05-18" + created_at="1500000000000" + updated_at="1500000000000" + /> + + <issues id="5" kee="MNO" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" + author_login="[null]" + checksum="[null]" + effort_to_fix="[null]" + technical_debt="10" + message="[null]" + line="5000" + component_id="100" + root_component_id="10" + rule_id="40" + reporter="emmerik" + issue_attributes="foo=bar" + action_plan_key="[null]" + tags="[null]" + issue_creation_date="2013-05-18" + issue_update_date="2013-05-18" + issue_close_date="2013-05-18" + created_at="1500000000000" + updated_at="1500000000000" + /> + + <issues id="6" kee="PQR" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]" + assignee="[null]" + author_login="[null]" + checksum="[null]" + effort_to_fix="[null]" + technical_debt="10" + message="[null]" + line="5000" + component_id="100" + root_component_id="10" + rule_id="666" + reporter="emmerik" + issue_attributes="foo=bar" + action_plan_key="[null]" + tags="[null]" + issue_creation_date="2013-05-18" + issue_update_date="2013-05-18" + issue_close_date="2013-05-18" + created_at="1500000000000" + updated_at="1500000000000" + /> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/schema.sql new file mode 100644 index 00000000000..a5ae2fca911 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/schema.sql @@ -0,0 +1,59 @@ +CREATE TABLE "RULES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "PLUGIN_RULE_KEY" VARCHAR(200) NOT NULL, + "PLUGIN_NAME" VARCHAR(255) NOT NULL, + "DESCRIPTION" VARCHAR(16777215), + "DESCRIPTION_FORMAT" VARCHAR(20), + "PRIORITY" INTEGER, + "IS_TEMPLATE" BOOLEAN DEFAULT FALSE, + "TEMPLATE_ID" INTEGER, + "PLUGIN_CONFIG_KEY" VARCHAR(500), + "NAME" VARCHAR(200), + "STATUS" VARCHAR(40), + "LANGUAGE" VARCHAR(20), + "NOTE_DATA" CLOB(2147483647), + "NOTE_USER_LOGIN" VARCHAR(255), + "NOTE_CREATED_AT" TIMESTAMP, + "NOTE_UPDATED_AT" TIMESTAMP, + "CHARACTERISTIC_ID" INTEGER, + "DEFAULT_CHARACTERISTIC_ID" INTEGER, + "REMEDIATION_FUNCTION" VARCHAR(20), + "DEFAULT_REMEDIATION_FUNCTION" VARCHAR(20), + "REMEDIATION_COEFF" VARCHAR(20), + "DEFAULT_REMEDIATION_COEFF" VARCHAR(20), + "REMEDIATION_OFFSET" VARCHAR(20), + "DEFAULT_REMEDIATION_OFFSET" VARCHAR(20), + "EFFORT_TO_FIX_DESCRIPTION" VARCHAR(4000), + "TAGS" VARCHAR(4000), + "SYSTEM_TAGS" VARCHAR(4000), + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP +); + +CREATE TABLE "ISSUES" ( + "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(50) UNIQUE NOT NULL, + "COMPONENT_ID" INTEGER NOT NULL, + "ROOT_COMPONENT_ID" INTEGER, + "RULE_ID" INTEGER, + "SEVERITY" VARCHAR(10), + "MANUAL_SEVERITY" BOOLEAN NOT NULL, + "MESSAGE" VARCHAR(4000), + "LINE" INTEGER, + "EFFORT_TO_FIX" DOUBLE, + "TECHNICAL_DEBT" INTEGER, + "STATUS" VARCHAR(20), + "RESOLUTION" VARCHAR(20), + "CHECKSUM" VARCHAR(1000), + "REPORTER" VARCHAR(255), + "ASSIGNEE" VARCHAR(255), + "AUTHOR_LOGIN" VARCHAR(255), + "ACTION_PLAN_KEY" VARCHAR(50) NULL, + "ISSUE_ATTRIBUTES" VARCHAR(4000), + "TAGS" VARCHAR(4000), + "ISSUE_CREATION_DATE" TIMESTAMP, + "ISSUE_CLOSE_DATE" TIMESTAMP, + "ISSUE_UPDATE_DATE" TIMESTAMP, + "CREATED_AT" BIGINT, + "UPDATED_AT" BIGINT +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssuesLongDatesTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssuesLongDatesTest/before.xml new file mode 100644 index 00000000000..be66fff5c0b --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssuesLongDatesTest/before.xml @@ -0,0 +1,34 @@ +<dataset> + <!-- new migration --> + <issues + id="1" + issue_creation_date="2014-09-25" + issue_creation_date_ms="[null]" + issue_update_date="2014-09-25" + issue_update_date_ms="[null]" + issue_close_date="2014-09-25" + issue_close_date_ms="[null]" + /> + + <!-- re-entrant migration - ignore the issues that are already fed with new dates --> + <issues + id="2" + issue_creation_date="2014-09-25" + issue_creation_date_ms="1500000000" + issue_update_date="2014-09-25" + issue_update_date_ms="1500000000" + issue_close_date="2014-09-25" + issue_close_date_ms="1500000000" + /> + + <!-- NULL dates --> + <issues + id="3" + issue_creation_date="[null]" + issue_creation_date_ms="[null]" + issue_update_date="[null]" + issue_update_date_ms="[null]" + issue_close_date="[null]" + issue_close_date_ms="[null]" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssuesLongDatesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssuesLongDatesTest/schema.sql new file mode 100644 index 00000000000..ab749851864 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssuesLongDatesTest/schema.sql @@ -0,0 +1,9 @@ +CREATE TABLE "ISSUES" ( + "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "ISSUE_CREATION_DATE" TIMESTAMP, + "ISSUE_CREATION_DATE_MS" BIGINT, + "ISSUE_CLOSE_DATE" TIMESTAMP, + "ISSUE_CLOSE_DATE_MS" BIGINT, + "ISSUE_UPDATE_DATE" TIMESTAMP, + "ISSUE_UPDATE_DATE_MS" BIGINT, +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest/before.xml new file mode 100644 index 00000000000..e90f89769b1 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest/before.xml @@ -0,0 +1,28 @@ +<dataset> + <!-- new migration --> + <manual_measures + id="1" + created_at="2014-09-25" + created_at_ms="[null]" + updated_at="2014-09-25" + updated_at_ms="[null]" + /> + + <!-- re-entrant migration - ignore the ones that are already fed with new dates --> + <manual_measures + id="2" + created_at="2014-09-25" + created_at_ms="1500000000" + updated_at="2014-09-25" + updated_at_ms="1500000000" + /> + + <!-- NULL dates --> + <manual_measures + id="3" + created_at="[null]" + created_at_ms="[null]" + updated_at="[null]" + updated_at_ms="[null]" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest/schema.sql new file mode 100644 index 00000000000..c04fbbeb80e --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest/schema.sql @@ -0,0 +1,7 @@ +CREATE TABLE "MANUAL_MEASURES" ( + "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "CREATED_AT" TIMESTAMP, + "CREATED_AT_MS" BIGINT, + "UPDATED_AT" TIMESTAMP, + "UPDATED_AT_MS" BIGINT +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest/before.xml new file mode 100644 index 00000000000..088fd0873f8 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest/before.xml @@ -0,0 +1,61 @@ +<dataset> + <!-- new migration --> + <snapshots + id="1" + project_id="1" + created_at="2014-09-25" + created_at_ms="[null]" + build_date="2014-09-25" + build_date_ms="[null]" + period1_date="2014-09-25" + period1_date_ms="[null]" + period2_date="2014-09-25" + period2_date_ms="[null]" + period3_date="2014-09-25" + period3_date_ms="[null]" + period4_date="2014-09-25" + period4_date_ms="[null]" + period5_date="2014-09-25" + period5_date_ms="[null]" + /> + + <!-- re-entrant migration - ignore the issues that are already fed with new dates --> + <snapshots + id="2" + project_id="1" + created_at="2014-09-25" + created_at_ms="1500000000" + build_date="2014-09-25" + build_date_ms="1500000000" + period1_date="2014-09-25" + period1_date_ms="1500000000" + period2_date="2014-09-25" + period2_date_ms="1500000000" + period3_date="2014-09-25" + period3_date_ms="1500000000" + period4_date="2014-09-25" + period4_date_ms="1500000000" + period5_date="2014-09-25" + period5_date_ms="1500000000" + /> + + <!-- NULL dates --> + <snapshots + id="3" + project_id="1" + created_at="[null]" + created_at_ms="[null]" + build_date="[null]" + build_date_ms="[null]" + period1_date="[null]" + period1_date_ms="[null]" + period2_date="[null]" + period2_date_ms="[null]" + period3_date="[null]" + period3_date_ms="[null]" + period4_date="[null]" + period4_date_ms="[null]" + period5_date="[null]" + period5_date_ms="[null]" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest/schema.sql new file mode 100644 index 00000000000..318169c0787 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest/schema.sql @@ -0,0 +1,18 @@ +CREATE TABLE "SNAPSHOTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "CREATED_AT" TIMESTAMP, + "CREATED_AT_MS" BIGINT, + "BUILD_DATE" TIMESTAMP, + "BUILD_DATE_MS" BIGINT, + "PROJECT_ID" INTEGER NOT NULL, + "PERIOD1_DATE" TIMESTAMP, + "PERIOD1_DATE_MS" BIGINT, + "PERIOD2_DATE" TIMESTAMP, + "PERIOD2_DATE_MS" BIGINT, + "PERIOD3_DATE" TIMESTAMP, + "PERIOD3_DATE_MS" BIGINT, + "PERIOD4_DATE" TIMESTAMP, + "PERIOD4_DATE_MS" BIGINT, + "PERIOD5_DATE" TIMESTAMP, + "PERIOD5_DATE_MS" BIGINT +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedUsersLongDatesTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedUsersLongDatesTest/before.xml new file mode 100644 index 00000000000..a4b16c1fcd2 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedUsersLongDatesTest/before.xml @@ -0,0 +1,26 @@ +<dataset> + + <users id="1" login="user1" name="User1" active="[true]" + created_at="2014-05-12" + updated_at="2014-05-13" + CREATED_AT_MS="[null]" + UPDATED_AT_MS="[null]" + /> + + <!-- re-entrant migration - ignore the issues that are already fed with new dates --> + <users id="2" login="user2" name="User2" active="[true]" + created_at="2014-05-12" + updated_at="2014-05-13" + CREATED_AT_MS="1500000000000" + UPDATED_AT_MS="1500000000000" + /> + + <!-- NULL dates --> + <users id="3" login="user3" name="User3" active="[true]" + created_at="[null]" + updated_at="[null]" + CREATED_AT_MS="[null]" + UPDATED_AT_MS="[null]" + /> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedUsersLongDatesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedUsersLongDatesTest/schema.sql new file mode 100644 index 00000000000..ba24adf3a29 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedUsersLongDatesTest/schema.sql @@ -0,0 +1,15 @@ +CREATE TABLE "USERS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "LOGIN" VARCHAR(255), + "NAME" VARCHAR(200), + "EMAIL" VARCHAR(100), + "CRYPTED_PASSWORD" VARCHAR(40), + "SALT" VARCHAR(40), + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP, + "CREATED_AT_MS" BIGINT, + "UPDATED_AT_MS" BIGINT, + "REMEMBER_TOKEN" VARCHAR(500), + "REMEMBER_TOKEN_EXPIRES_AT" TIMESTAMP, + "ACTIVE" BOOLEAN DEFAULT TRUE +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/migrate-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/migrate-result.xml new file mode 100644 index 00000000000..66bbfaf90c1 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/migrate-result.xml @@ -0,0 +1,24 @@ +<dataset> + + <projects id="100" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + description="the description" long_name="Apache Struts" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" + authorization_updated_at="123456789"/> + + <projects id="101" root_id="[null]" scope="PRJ" qualifier="BRC" kee="org.struts:struts-server" name="Struts Server" + description="the description" long_name="Apache Struts Server" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" + authorization_updated_at="123456789"/> + + <!-- Permissions on project --> + <user_roles id="1" user_id="200" resource_id="100" role="user"/> + <user_roles id="2" user_id="200" resource_id="100" role="admin"/> + <group_roles id="1" group_id="100" resource_id="100" role="codeviewer"/> + + <!-- No more permissions on module --> + + <!-- Global permissions --> + <user_roles id="10" user_id="200" resource_id="[null]" role="admin"/> + <group_roles id="10" group_id="200" resource_id="[null]" role="admin"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/migrate.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/migrate.xml new file mode 100644 index 00000000000..a209fcf9025 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/migrate.xml @@ -0,0 +1,29 @@ +<dataset> + + <projects id="100" uuid="ABCD" module_uuid="[null]" project_uuid="ABCD" module_uuid_path=".ABCD." root_id="[null]" + scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" description="the description" + long_name="Apache Struts" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" + authorization_updated_at="123456789"/> + + <projects id="101" uuid="BCDE" module_uuid="ABCD" project_uuid="ABCD" module_uuid_path=".ABCD.BCDE." root_id="100" + scope="PRJ" qualifier="BRC" kee="org.struts:struts-server" name="Struts Server" + description="the description" long_name="Apache Struts Server" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" + authorization_updated_at="123456789"/> + + <!-- Permissions on project --> + <user_roles id="1" user_id="200" resource_id="100" role="user"/> + <user_roles id="2" user_id="200" resource_id="100" role="admin"/> + <group_roles id="1" group_id="100" resource_id="100" role="codeviewer"/> + + <!-- Permissions on module : should be deleted --> + <user_roles id="3" user_id="200" resource_id="101" role="user"/> + <user_roles id="4" user_id="200" resource_id="101" role="admin"/> + <group_roles id="2" group_id="100" resource_id="101" role="codeviewer"/> + + <!-- Global permissions --> + <user_roles id="10" user_id="200" resource_id="[null]" role="admin"/> + <group_roles id="10" group_id="200" resource_id="[null]" role="admin"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/nothing_to_do_when_already_migrated.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/nothing_to_do_when_already_migrated.xml new file mode 100644 index 00000000000..8a842e7a734 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/nothing_to_do_when_already_migrated.xml @@ -0,0 +1,22 @@ +<dataset> + + <projects id="100" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + description="the description" long_name="Apache Struts" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" + authorization_updated_at="123456789"/> + + <projects id="101" root_id="[null]" scope="PRJ" qualifier="BRC" kee="org.struts:struts-server" name="Struts Server" + description="the description" long_name="Apache Struts Server" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" + authorization_updated_at="123456789"/> + + <!-- Permissions on project --> + <user_roles id="1" user_id="200" resource_id="100" role="user"/> + <user_roles id="2" user_id="200" resource_id="100" role="admin"/> + <group_roles id="1" group_id="100" resource_id="100" role="codeviewer"/> + + <!-- Global permissions --> + <user_roles id="10" user_id="200" resource_id="[null]" role="admin"/> + <group_roles id="10" group_id="200" resource_id="[null]" role="admin"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/schema.sql new file mode 100644 index 00000000000..b291cf0beea --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/schema.sql @@ -0,0 +1,49 @@ +CREATE TABLE "USER_ROLES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "USER_ID" INTEGER, + "RESOURCE_ID" INTEGER, + "ROLE" VARCHAR(64) NOT NULL +); + +CREATE INDEX "USER_ROLES_RESOURCE" ON "USER_ROLES" ("RESOURCE_ID"); + +CREATE INDEX "USER_ROLES_USER" ON "USER_ROLES" ("USER_ID"); + +CREATE TABLE "GROUP_ROLES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "GROUP_ID" INTEGER, + "RESOURCE_ID" INTEGER, + "ROLE" VARCHAR(64) NOT NULL +); + +CREATE INDEX "GROUP_ROLES_RESOURCE" ON "GROUP_ROLES" ("RESOURCE_ID"); + +CREATE INDEX "GROUP_ROLES_GROUP" ON "GROUP_ROLES" ("GROUP_ID"); + +CREATE INDEX "GROUP_ROLES_ROLE" ON "GROUP_ROLES" ("ROLE"); + +CREATE UNIQUE INDEX "UNIQ_GROUP_ROLES" ON "GROUP_ROLES" ("GROUP_ID", "RESOURCE_ID", "ROLE"); + +CREATE TABLE "PROJECTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(400), + "ROOT_ID" INTEGER, + "UUID" VARCHAR(50), + "PROJECT_UUID" VARCHAR(50), + "MODULE_UUID" VARCHAR(50), + "MODULE_UUID_PATH" VARCHAR(4000), + "NAME" VARCHAR(256), + "DESCRIPTION" VARCHAR(2000), + "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10), + "DEPRECATED_KEE" VARCHAR(400), + "PATH" VARCHAR(2000), + "LANGUAGE" VARCHAR(20), + "COPY_RESOURCE_ID" INTEGER, + "LONG_NAME" VARCHAR(256), + "PERSON_ID" INTEGER, + "CREATED_AT" TIMESTAMP, + "AUTHORIZATION_UPDATED_AT" BIGINT +); + diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/execute-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/execute-result.xml new file mode 100644 index 00000000000..a3dc90896d3 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/execute-result.xml @@ -0,0 +1,68 @@ +<dataset> + + <!-- Not updated, no concerned field --> + <issue_filters + id="1" + name="No concerned field" + user_login="stephane" + shared="[true]" + description="no not touch" + data="projectUuids=ABCD" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <!-- Not updated, projectUuids is left as is --> + <issue_filters + id="2" + name="Has projects" + user_login="michael" + shared="[false]" + description="to be updated" + data="statuses=OPEN|sort=SEVERITY|asc=true|projectUuids=ABC" + created_at="2013-06-10" + updated_at="2013-06-10 00:00:00.0"/> + + <!-- componentUuids replaced by fileUuids --> + <issue_filters + id="3" + name="Has components" + user_login="michael" + shared="[false]" + description="to be updated" + data="fileUuids=ABC|statuses=OPEN|sort=SEVERITY|asc=true" + created_at="2013-06-10" + updated_at="2014-10-29 00:00:00.0"/> + + <!-- componentRootUuids replaced by moduleUuids --> + <issue_filters + id="4" + name="Has componentRoots" + user_login="michael" + shared="[false]" + description="to be updated" + data="statuses=OPEN|sort=SEVERITY|asc=true|moduleUuids=ABC" + created_at="2013-06-10" + updated_at="2014-10-29 00:00:00.0"/> + + <!-- componentRootUuids replaced by moduleUuids (in the middle of the string) --> + <issue_filters + id="5" + name="Has projects" + user_login="michael" + shared="[false]" + description="to be updated" + data="statuses=OPEN|sort=SEVERITY|moduleUuids=ABC|asc=true" + created_at="2013-06-10" + updated_at="2014-10-29 00:00:00.0"/> + + <!-- componentUuidss replaced by fileUuids, componentRootUuids replaced by moduleUuids --> + <issue_filters + id="6" + name="Has all parameters" + user_login="michael" + shared="[false]" + description="to be updated" + data="statuses=OPEN|sort=SEVERITY|fileUuids=BCD|moduleUuids=ABC|projectUuids=CDE|asc=true" + created_at="2013-06-10" + updated_at="2014-10-29 00:00:00.0"/> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/execute.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/execute.xml new file mode 100644 index 00000000000..971334c5066 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/execute.xml @@ -0,0 +1,69 @@ +<dataset> + + <!-- Not updated, no concerned field --> + <issue_filters + id="1" + name="No concerned field" + user_login="stephane" + shared="[true]" + description="no not touch" + data="projectUuids=ABCD" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <!-- Not updated, projectUuids is left as is --> + <issue_filters + id="2" + name="Has projects" + user_login="michael" + shared="[false]" + description="to be updated" + data="statuses=OPEN|sort=SEVERITY|asc=true|projectUuids=ABC" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <!-- componentUuids replaced by fileUuids --> + <issue_filters + id="3" + name="Has components" + user_login="michael" + shared="[false]" + description="to be updated" + data="componentUuids=ABC|statuses=OPEN|sort=SEVERITY|asc=true" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <!-- componentRootUuids replaced by moduleUuids --> + <issue_filters + id="4" + name="Has componentRoots" + user_login="michael" + shared="[false]" + description="to be updated" + data="statuses=OPEN|sort=SEVERITY|asc=true|componentRootUuids=ABC" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <!-- componentRootUuids replaced by moduleUuids (in the middle of the string) --> + <issue_filters + id="5" + name="Has projects" + user_login="michael" + shared="[false]" + description="to be updated" + data="statuses=OPEN|sort=SEVERITY|componentRootUuids=ABC|asc=true" + created_at="2013-06-10" + updated_at="2013-06-10"/> + + <!-- componentUuidss replaced by fileUuids, componentRootUuids replaced by moduleUuids --> + <issue_filters + id="6" + name="Has all parameters" + user_login="michael" + shared="[false]" + description="to be updated" + data="statuses=OPEN|sort=SEVERITY|componentUuids=BCD|componentRootUuids=ABC|projectUuids=CDE|asc=true" + created_at="2013-06-10" + updated_at="2013-06-10"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/schema.sql new file mode 100644 index 00000000000..0627153a62d --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/schema.sql @@ -0,0 +1,10 @@ +CREATE TABLE "ISSUE_FILTERS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "NAME" VARCHAR(100) NOT NULL, + "SHARED" BOOLEAN NOT NULL DEFAULT FALSE, + "USER_LOGIN" VARCHAR(255), + "DESCRIPTION" VARCHAR(4000), + "DATA" CLOB(2147483647), + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/migrate_components-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/migrate_components-result.xml new file mode 100644 index 00000000000..85f8eb4b928 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/migrate_components-result.xml @@ -0,0 +1,100 @@ +<dataset> + + <!-- root project --> + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + deprecated_kee="org.struts:struts" + uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD." + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- module --> + <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" deprecated_kee="org.struts:struts-core" + uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD.EFGH." + scope="PRJ" qualifier="BRC" long_name="Struts Core" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- sub module, already has dots: only itself appended --> + <projects id="3" root_id="1" kee="org.struts:struts-data" name="Struts Data" deprecated_kee="org.struts:struts-data" + uuid="FGHI" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH.FGHI." + scope="PRJ" qualifier="BRC" long_name="Struts Data" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- directory --> + <projects id="4" root_id="3" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts" + deprecated_kee="org.struts:struts-core:src/org/struts" + uuid="GHIJ" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path=".ABCD.EFGH.FGHI." + name="src/org/struts" long_name="org.struts" + description="[null]" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- file --> + <projects id="5" root_id="3" scope="FIL" qualifier="FIL" + kee="org.struts:struts-core:src/org/struts/RequestContext.java" + deprecated_kee="org.struts:struts-core:src/org/struts/RequestContext.java" + uuid="HIJK" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path=".ABCD.EFGH.FGHI." + name="RequestContext.java" long_name="org.struts.RequestContext" + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" + path="src/org/struts/RequestContext.java" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- view --> + <projects id="6" root_id="[null]" scope="PRJ" qualifier="VW" kee="Teams" name="Teams" deprecated_kee="Teams" + uuid="MEAT" project_uuid="MEAT" module_uuid="[null]" module_uuid_path=".MEAT." + description="the description" long_name="Teams" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- sub-view --> + <projects id="7" root_id="6" scope="PRJ" qualifier="SVW" kee="Platform_Team" name="Platform Team" + deprecated_kee="Platform_Team" + uuid="PLAT" project_uuid="MEAT" module_uuid="MEAT" module_uuid_path=".MEAT.PLAT." + description="the description" long_name="Platform Team" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- view technical project - unchanged --> + <projects id="8" root_id="6" scope="FIL" qualifier="TRK" kee="Platform_Team:sonarqube" name="SonarQube" + deprecated_kee="Platform_Team:sonarqube" + uuid="SNQB" project_uuid="PLAT" module_uuid="PLAT" module_uuid_path=".MEAT.PLAT." + description="the description" long_name="Platform Team" + enabled="[true]" language="[null]" copy_resource_id="42" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- root project already has dots, appending itself --> + <projects id="9" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.sonar:sample" name="Sample" + deprecated_kee="org.sonar:sample" + uuid="WDOT" project_uuid="WDOT" module_uuid="[null]" module_uuid_path=".WDOT." + description="the description" long_name="Sample" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- root project with module_uuid_path NULL --> + <projects id="10" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.sonar:sample" name="Sample" + deprecated_kee="org.sonar:sample" + uuid="DCBA" project_uuid="DCBA" module_uuid="[null]" module_uuid_path=".DCBA." + description="the description" long_name="Sample" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- developer --> + <projects id="11" root_id="[null]" scope="PRJ" qualifier="DEV" kee="DEV:anakin.skywalker" name="Anakin Skywalker" + deprecated_kee="DEV:anakin.skywalker" + uuid="VADR" project_uuid="VADR" module_uuid="[null]" module_uuid_path=".VADR." + description="the description" long_name="Anakin Skywalker" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="1" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- developer technical project, with dots - unchanged --> + <projects id="12" root_id="11" scope="PRJ" qualifier="DEV_PRJ" kee="DEV:anakin.skywalker:Executor" + name="Executor Star Dreadnaught" deprecated_kee="DEV:anakin.skywalker:Executor" + uuid="EXCT" project_uuid="VADR" module_uuid="VADR" module_uuid_path=".VADR." + description="the description" long_name="Executor Star Dreadnaught" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/migrate_components.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/migrate_components.xml new file mode 100644 index 00000000000..ede863b4724 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/migrate_components.xml @@ -0,0 +1,100 @@ +<dataset> + + <!-- root project --> + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + deprecated_kee="org.struts:struts" + uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- module --> + <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" deprecated_kee="org.struts:struts-core" + uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="ABCD" + scope="PRJ" qualifier="BRC" long_name="Struts Core" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- sub module, already has dots: only itself appended --> + <projects id="3" root_id="1" kee="org.struts:struts-data" name="Struts Data" deprecated_kee="org.struts:struts-data" + uuid="FGHI" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH." + scope="PRJ" qualifier="BRC" long_name="Struts Data" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- directory --> + <projects id="4" root_id="3" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts" + deprecated_kee="org.struts:struts-core:src/org/struts" + uuid="GHIJ" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path="ABCD.EFGH.FGHI" + name="src/org/struts" long_name="org.struts" + description="[null]" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- file --> + <projects id="5" root_id="3" scope="FIL" qualifier="FIL" + kee="org.struts:struts-core:src/org/struts/RequestContext.java" + deprecated_kee="org.struts:struts-core:src/org/struts/RequestContext.java" + uuid="HIJK" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path="ABCD.EFGH.FGHI" + name="RequestContext.java" long_name="org.struts.RequestContext" + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" + path="src/org/struts/RequestContext.java" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- view --> + <projects id="6" root_id="[null]" scope="PRJ" qualifier="VW" kee="Teams" name="Teams" deprecated_kee="Teams" + uuid="MEAT" project_uuid="MEAT" module_uuid="[null]" module_uuid_path="" + description="the description" long_name="Teams" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- sub-view --> + <projects id="7" root_id="6" scope="PRJ" qualifier="SVW" kee="Platform_Team" name="Platform Team" + deprecated_kee="Platform_Team" + uuid="PLAT" project_uuid="MEAT" module_uuid="MEAT" module_uuid_path="MEAT" + description="the description" long_name="Platform Team" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- view technical project, already has dots - unchanged --> + <projects id="8" root_id="6" scope="FIL" qualifier="TRK" kee="Platform_Team:sonarqube" name="SonarQube" + deprecated_kee="Platform_Team:sonarqube" + uuid="SNQB" project_uuid="PLAT" module_uuid="PLAT" module_uuid_path=".MEAT.PLAT." + description="the description" long_name="Platform Team" + enabled="[true]" language="[null]" copy_resource_id="42" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- root project already has dots, appending itself --> + <projects id="9" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.sonar:sample" name="Sample" + deprecated_kee="org.sonar:sample" + uuid="WDOT" project_uuid="WDOT" module_uuid="[null]" module_uuid_path="." + description="the description" long_name="Sample" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- root project with module_uuid_path NULL --> + <projects id="10" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.sonar:sample" name="Sample" + deprecated_kee="org.sonar:sample" + uuid="DCBA" project_uuid="DCBA" module_uuid="[null]" module_uuid_path="[null]" + description="the description" long_name="Sample" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- developer --> + <projects id="11" root_id="[null]" scope="PRJ" qualifier="DEV" kee="DEV:anakin.skywalker" name="Anakin Skywalker" + deprecated_kee="DEV:anakin.skywalker" + uuid="VADR" project_uuid="VADR" module_uuid="[null]" module_uuid_path="" + description="the description" long_name="Anakin Skywalker" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="1" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- developer technical project, with dots - unchanged --> + <projects id="12" root_id="11" scope="PRJ" qualifier="DEV_PRJ" kee="DEV:anakin.skywalker:Executor" + name="Executor Star Dreadnaught" deprecated_kee="DEV:anakin.skywalker:Executor" + uuid="EXCT" project_uuid="VADR" module_uuid="VADR" module_uuid_path=".VADR." + description="the description" long_name="Executor Star Dreadnaught" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/not_migrate_already_migrated_components.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/not_migrate_already_migrated_components.xml new file mode 100644 index 00000000000..547192c2bbf --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/not_migrate_already_migrated_components.xml @@ -0,0 +1,100 @@ +<dataset> + + <!-- root project --> + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + deprecated_kee="org.struts:struts" + uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD." + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- module --> + <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" deprecated_kee="org.struts:struts-core" + uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD.EFGH." + scope="PRJ" qualifier="BRC" long_name="Struts Core" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- sub module --> + <projects id="3" root_id="1" kee="org.struts:struts-data" name="Struts Data" deprecated_kee="org.struts:struts-data" + uuid="FGHI" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH.FGHI." + scope="PRJ" qualifier="BRC" long_name="Struts Data" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- directory --> + <projects id="4" root_id="3" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts" + deprecated_kee="org.struts:struts-core:src/org/struts" + uuid="GHIJ" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path=".ABCD.EFGH.FGHI." + name="src/org/struts" long_name="org.struts" + description="[null]" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- file --> + <projects id="5" root_id="3" scope="FIL" qualifier="FIL" + kee="org.struts:struts-core:src/org/struts/RequestContext.java" + deprecated_kee="org.struts:struts-core:src/org/struts/RequestContext.java" + uuid="HIJK" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path=".ABCD.EFGH.FGHI." + name="RequestContext.java" long_name="org.struts.RequestContext" + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" + path="src/org/struts/RequestContext.java" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- view --> + <projects id="6" root_id="[null]" scope="PRJ" qualifier="VW" kee="Teams" name="Teams" deprecated_kee="Teams" + uuid="MEAT" project_uuid="MEAT" module_uuid="[null]" module_uuid_path=".MEAT." + description="the description" long_name="Teams" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- sub-view --> + <projects id="7" root_id="[null]" scope="PRJ" qualifier="SVW" kee="Platform_Team" name="Platform Team" + deprecated_kee="Platform_Team" + uuid="PLAT" project_uuid="MEAT" module_uuid="MEAT" module_uuid_path=".MEAT.PLAT." + description="the description" long_name="Platform Team" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- view technical project, already has dots - unchanged --> + <projects id="8" root_id="[null]" scope="FIL" qualifier="TRK" kee="Platform_Team:sonarqube" name="SonarQube" + deprecated_kee="Platform_Team:sonarqube" + uuid="SNQB" project_uuid="PLAT" module_uuid="PLAT" module_uuid_path=".MEAT.PLAT." + description="the description" long_name="Platform Team" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- root project already has dots, appending itself --> + <projects id="9" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.sonar:sample" name="Sample" + deprecated_kee="org.sonar:sample" + uuid="WDOT" project_uuid="WDOT" module_uuid="[null]" module_uuid_path=".WDOT." + description="the description" long_name="Sample" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- root project with module_uuid_path NULL --> + <projects id="10" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.sonar:sample" name="Sample" + deprecated_kee="org.sonar:sample" + uuid="DCBA" project_uuid="DCBA" module_uuid="[null]" module_uuid_path=".DCBA." + description="the description" long_name="Sample" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- developer --> + <projects id="11" root_id="[null]" scope="PRJ" qualifier="DEV" kee="DEV:anakin.skywalker" name="Anakin Skywalker" + deprecated_kee="DEV:anakin.skywalker" + uuid="VADR" project_uuid="VADR" module_uuid="[null]" module_uuid_path=".VADR." + description="the description" long_name="Anakin Skywalker" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="1" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- developer technical project, with dots - unchanged --> + <projects id="12" root_id="11" scope="PRJ" qualifier="DEV_PRJ" kee="DEV:anakin.skywalker:Executor" + name="Executor Star Dreadnaught" deprecated_kee="DEV:anakin.skywalker:Executor" + uuid="EXCT" project_uuid="VADR" module_uuid="VADR" module_uuid_path=".VADR." + description="the description" long_name="Executor Star Dreadnaught" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/schema.sql new file mode 100644 index 00000000000..b7307a0902a --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/schema.sql @@ -0,0 +1,22 @@ +CREATE TABLE "PROJECTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(400), + "ROOT_ID" INTEGER, + "UUID" VARCHAR(50), + "PROJECT_UUID" VARCHAR(50), + "MODULE_UUID" VARCHAR(50), + "MODULE_UUID_PATH" VARCHAR(4000), + "NAME" VARCHAR(256), + "DESCRIPTION" VARCHAR(2000), + "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10), + "DEPRECATED_KEE" VARCHAR(400), + "PATH" VARCHAR(2000), + "LANGUAGE" VARCHAR(20), + "COPY_RESOURCE_ID" INTEGER, + "LONG_NAME" VARCHAR(256), + "PERSON_ID" INTEGER, + "CREATED_AT" TIMESTAMP, + "AUTHORIZATION_UPDATED_AT" BIGINT +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/AddManualMeasuresComponentUuidColumnTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/AddManualMeasuresComponentUuidColumnTest/schema.sql new file mode 100644 index 00000000000..6fa4c32a970 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/AddManualMeasuresComponentUuidColumnTest/schema.sql @@ -0,0 +1,11 @@ +CREATE TABLE "MANUAL_MEASURES" ( + "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "METRIC_ID" INTEGER NOT NULL, + "RESOURCE_ID" INTEGER, + "VALUE" DOUBLE, + "TEXT_VALUE" VARCHAR(4000), + "USER_LOGIN" VARCHAR(255), + "DESCRIPTION" VARCHAR(4000), + "CREATED_AT" BIGINT, + "UPDATED_AT" BIGINT +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/migrate-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/migrate-result.xml new file mode 100644 index 00000000000..2f6d90c92cb --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/migrate-result.xml @@ -0,0 +1,6 @@ +<dataset> + + <events id="1" name="1.0" resource_id="1" component_uuid="ABCD" snapshot_id="1000" category="Version" + event_date="1225630680000" created_at="1225630680000" description="" event_data="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/migrate.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/migrate.xml new file mode 100644 index 00000000000..38cd3d20e3a --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/migrate.xml @@ -0,0 +1,13 @@ +<dataset> + + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + deprecated_kee="org.struts:struts" + uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <events id="1" name="1.0" resource_id="1" component_uuid="[null]" snapshot_id="1000" category="Version" + event_date="1225630680000" created_at="1225630680000" description="" event_data="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/not_migrate_already_migrated_data.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/not_migrate_already_migrated_data.xml new file mode 100644 index 00000000000..afecdb23d15 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/not_migrate_already_migrated_data.xml @@ -0,0 +1,13 @@ +<dataset> + + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + deprecated_kee="org.struts:struts" + uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <events id="1" name="1.0" resource_id="1" component_uuid="ABCD" snapshot_id="1000" category="Version" + event_date="1225630680000" created_at="1225630680000" description="" event_data="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/schema.sql new file mode 100644 index 00000000000..e4ca540f2f2 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/schema.sql @@ -0,0 +1,35 @@ +CREATE TABLE "PROJECTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(400), + "ROOT_ID" INTEGER, + "UUID" VARCHAR(50), + "PROJECT_UUID" VARCHAR(50), + "MODULE_UUID" VARCHAR(50), + "MODULE_UUID_PATH" VARCHAR(4000), + "NAME" VARCHAR(256), + "DESCRIPTION" VARCHAR(2000), + "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10), + "DEPRECATED_KEE" VARCHAR(400), + "PATH" VARCHAR(2000), + "LANGUAGE" VARCHAR(20), + "COPY_RESOURCE_ID" INTEGER, + "LONG_NAME" VARCHAR(256), + "PERSON_ID" INTEGER, + "CREATED_AT" TIMESTAMP, + "AUTHORIZATION_UPDATED_AT" BIGINT +); + +CREATE TABLE "EVENTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "NAME" VARCHAR(400), + "RESOURCE_ID" INTEGER, + "COMPONENT_UUID" VARCHAR(50), + "SNAPSHOT_ID" INTEGER, + "CATEGORY" VARCHAR(50), + "EVENT_DATE" BIGINT NOT NULL, + "CREATED_AT" BIGINT NOT NULL, + "DESCRIPTION" VARCHAR(4000), + "EVENT_DATA" VARCHAR(4000) +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/migrate-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/migrate-result.xml new file mode 100644 index 00000000000..3788fbf38ef --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/migrate-result.xml @@ -0,0 +1,10 @@ +<dataset> + + <file_sources id="1" project_uuid="project-1" file_uuid="file-1" data_type="SOURCE" created_at="123456789" + updated_at="456456456"/> + <file_sources id="2" project_uuid="project-2" file_uuid="file-2" data_type="SOURCE" created_at="123456789" + updated_at="456456456"/> + <file_sources id="3" project_uuid="project-3" file_uuid="file-3" data_type="SOURCE" created_at="123456789" + updated_at="456456456"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/migrate.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/migrate.xml new file mode 100644 index 00000000000..2282a9bb4c0 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/migrate.xml @@ -0,0 +1,10 @@ +<dataset> + + <file_sources id="1" project_uuid="project-1" file_uuid="file-1" data_type="[null]" created_at="123456789" + updated_at="456456456"/> + <file_sources id="2" project_uuid="project-2" file_uuid="file-2" data_type="SOURCE" created_at="123456789" + updated_at="456456456"/> + <file_sources id="3" project_uuid="project-3" file_uuid="file-3" data_type="[null]" created_at="123456789" + updated_at="456456456"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/schema.sql new file mode 100644 index 00000000000..84eb7749817 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/schema.sql @@ -0,0 +1,8 @@ +CREATE TABLE "FILE_SOURCES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "PROJECT_UUID" VARCHAR(50) NOT NULL, + "FILE_UUID" VARCHAR(50) NOT NULL, + "DATA_TYPE" VARCHAR(20), + "CREATED_AT" BIGINT NOT NULL, + "UPDATED_AT" BIGINT NOT NULL +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/migrate-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/migrate-result.xml new file mode 100644 index 00000000000..2dd0252cb3c --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/migrate-result.xml @@ -0,0 +1,6 @@ +<dataset> + + <manual_measures id="1" resource_id="10" component_uuid="ABCD"/> + <manual_measures id="2" resource_id="20" component_uuid="EFGH"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/migrate.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/migrate.xml new file mode 100644 index 00000000000..2a36c383c69 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/migrate.xml @@ -0,0 +1,9 @@ +<dataset> + + <projects id="10" uuid="ABCD"/> + <projects id="20" uuid="EFGH"/> + + <manual_measures id="1" resource_id="10" component_uuid="[null]"/> + <manual_measures id="2" resource_id="20" component_uuid="EFGH"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/schema.sql new file mode 100644 index 00000000000..bc2c66dc238 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/schema.sql @@ -0,0 +1,10 @@ +CREATE TABLE "MANUAL_MEASURES" ( + "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "RESOURCE_ID" INTEGER, + "COMPONENT_UUID" VARCHAR(50), +); + +CREATE TABLE "PROJECTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "UUID" VARCHAR(50), +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/migrate-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/migrate-result.xml new file mode 100644 index 00000000000..dd63f7edb36 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/migrate-result.xml @@ -0,0 +1,9 @@ +<dataset> + + <metrics id="1" user_managed="[true]" optimized_best_value="[false]" hidden="[false]" + delete_historical_data="[false]"/> + <metrics id="2" user_managed="[false]" optimized_best_value="[true]" hidden="[true]" delete_historical_data="[true]"/> + <metrics id="3" user_managed="[false]" optimized_best_value="[false]" hidden="[false]" + delete_historical_data="[false]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/migrate.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/migrate.xml new file mode 100644 index 00000000000..7fee0be9b77 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/migrate.xml @@ -0,0 +1,7 @@ +<dataset> + + <metrics id="1" user_managed="[true]" optimized_best_value="[null]" hidden="[null]" delete_historical_data="[null]"/> + <metrics id="2" user_managed="[false]" optimized_best_value="[true]" hidden="[true]" delete_historical_data="[true]"/> + <metrics id="3" user_managed="[false]" optimized_best_value="[null]" hidden="[null]" delete_historical_data="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/schema.sql new file mode 100644 index 00000000000..d65487d7677 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/schema.sql @@ -0,0 +1,7 @@ +CREATE TABLE "METRICS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "USER_MANAGED" BOOLEAN DEFAULT FALSE, + "OPTIMIZED_BEST_VALUE" BOOLEAN, + "HIDDEN" BOOLEAN, + "DELETE_HISTORICAL_DATA" BOOLEAN +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/migrate-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/migrate-result.xml new file mode 100644 index 00000000000..e46458a32e7 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/migrate-result.xml @@ -0,0 +1,28 @@ +<dataset> + + <!-- root project --> + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + deprecated_kee="org.struts:struts" + uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- Both links now contains component uuid--> + <project_links id="1" project_id="1" component_uuid="ABCD" link_type="homepage" name="Home" + href="http://www.struts.org"/> + <project_links id="2" project_id="1" component_uuid="ABCD" link_type="scm" name="Sources" + href="https://github.com/Struts"/> + + <!-- module --> + <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" deprecated_kee="org.struts:struts-core" + uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="ABCD" + scope="PRJ" qualifier="BRC" long_name="Struts Core" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- Link now contains component uuid--> + <project_links id="3" project_id="2" component_uuid="EFGH" link_type="scm" name="Sources" + href="https://github.com/Struts/struts-core"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/migrate.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/migrate.xml new file mode 100644 index 00000000000..a1de6ecdf02 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/migrate.xml @@ -0,0 +1,26 @@ +<dataset> + + <!-- root project --> + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + deprecated_kee="org.struts:struts" + uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <project_links id="1" project_id="1" component_uuid="[null]" link_type="homepage" name="Home" + href="http://www.struts.org"/> + <project_links id="2" project_id="1" component_uuid="[null]" link_type="scm" name="Sources" + href="https://github.com/Struts"/> + + <!-- module --> + <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" deprecated_kee="org.struts:struts-core" + uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="ABCD" + scope="PRJ" qualifier="BRC" long_name="Struts Core" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <project_links id="3" project_id="2" component_uuid="[null]" link_type="scm" name="Sources" + href="https://github.com/Struts/struts-core"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/not_migrate_already_migrated_data.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/not_migrate_already_migrated_data.xml new file mode 100644 index 00000000000..fc7f64f6e9c --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/not_migrate_already_migrated_data.xml @@ -0,0 +1,28 @@ +<dataset> + + <!-- root project --> + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + deprecated_kee="org.struts:struts" + uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- Links already contains component uuid--> + <project_links id="1" project_id="1" component_uuid="ABCD" link_type="homepage" name="Home" + href="http://www.struts.org"/> + <project_links id="2" project_id="1" component_uuid="ABCD" link_type="scm" name="Sources" + href="https://github.com/Struts"/> + + <!-- module --> + <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" deprecated_kee="org.struts:struts-core" + uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="ABCD" + scope="PRJ" qualifier="BRC" long_name="Struts Core" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- Link already contains component uuid--> + <project_links id="3" project_id="2" component_uuid="EFGH" link_type="scm" name="Sources" + href="https://github.com/Struts/struts-core"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/schema.sql new file mode 100644 index 00000000000..f04590ffebd --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/schema.sql @@ -0,0 +1,31 @@ +CREATE TABLE "PROJECT_LINKS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "PROJECT_ID" INTEGER NOT NULL, + "COMPONENT_UUID" VARCHAR(50), + "LINK_TYPE" VARCHAR(20), + "NAME" VARCHAR(128), + "HREF" VARCHAR(2048) NOT NULL +); + +CREATE TABLE "PROJECTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(400), + "ROOT_ID" INTEGER, + "UUID" VARCHAR(50), + "PROJECT_UUID" VARCHAR(50), + "MODULE_UUID" VARCHAR(50), + "MODULE_UUID_PATH" VARCHAR(4000), + "NAME" VARCHAR(256), + "DESCRIPTION" VARCHAR(2000), + "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10), + "DEPRECATED_KEE" VARCHAR(400), + "PATH" VARCHAR(2000), + "LANGUAGE" VARCHAR(20), + "COPY_RESOURCE_ID" INTEGER, + "LONG_NAME" VARCHAR(256), + "PERSON_ID" INTEGER, + "CREATED_AT" TIMESTAMP, + "AUTHORIZATION_UPDATED_AT" BIGINT +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/migrate-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/migrate-result.xml new file mode 100644 index 00000000000..2a5da2677cc --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/migrate-result.xml @@ -0,0 +1,29 @@ +<dataset> + + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + deprecated_kee="org.struts:struts" + uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- Default Java profile, will be set as default --> + <rules_profiles id="1" name="Java One" language="java" parent_kee="[null]" kee="java-one" is_default="[true]" + created_at="[null]" updated_at="[null]" rules_updated_at="[null]"/> + + <rules_profiles id="2" name="Java Two" language="java" parent_kee="[null]" kee="java-two" is_default="[false]" + created_at="[null]" updated_at="[null]" rules_updated_at="[null]"/> + + <rules_profiles id="3" name="Php One" language="php" parent_kee="[null]" kee="php-one" is_default="[false]" + created_at="[null]" updated_at="[null]" rules_updated_at="[null]"/> + + <rules_profiles id="4" name="Cobol One" language="cbl" parent_kee="[null]" kee="cobol-one" is_default="[false]" + created_at="[null]" updated_at="[null]" rules_updated_at="[null]"/> + + <!-- Unmodified property --> + <properties id="1" prop_key="polop.palap" text_value="Untouched" resource_id="[null]" user_id="[null]"/> + + <!-- Project 'Struts' uses profile 'Java Two', moved to association table --> + <project_qprofiles id="1" project_uuid="ABCD" profile_key="java-two"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/migrate.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/migrate.xml new file mode 100644 index 00000000000..98849222aa9 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/migrate.xml @@ -0,0 +1,41 @@ +<dataset> + + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + deprecated_kee="org.struts:struts" + uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- Default Java profile, will be set as default --> + <rules_profiles id="1" name="Java One" language="java" parent_kee="[null]" kee="java-one" is_default="[false]" + created_at="[null]" updated_at="[null]" rules_updated_at="[null]"/> + + <rules_profiles id="2" name="Java Two" language="java" parent_kee="[null]" kee="java-two" is_default="[false]" + created_at="[null]" updated_at="[null]" rules_updated_at="[null]"/> + + <rules_profiles id="3" name="Php One" language="php" parent_kee="[null]" kee="php-one" is_default="[false]" + created_at="[null]" updated_at="[null]" rules_updated_at="[null]"/> + + <rules_profiles id="4" name="Cobol One" language="cbl" parent_kee="[null]" kee="cobol-one" is_default="[false]" + created_at="[null]" updated_at="[null]" rules_updated_at="[null]"/> + + <!-- Unmodified property --> + <properties id="1" prop_key="polop.palap" text_value="Untouched" resource_id="[null]" user_id="[null]"/> + + <!-- Default Java profile, will be set as default --> + <properties id="2" prop_key="sonar.profile.java" text_value="Java One" resource_id="[null]" user_id="[null]"/> + + <!-- Project 'Struts' uses profile 'Java Two', will be moved to association table --> + <properties id="3" prop_key="sonar.profile.java" text_value="Java Two" resource_id="1" user_id="[null]"/> + + <!-- Property on unknown language, will be ignored --> + <properties id="4" prop_key="sonar.profile.xoo" text_value="Xoo One" resource_id="[null]" user_id="[null]"/> + + <!-- Property on unknown profile, will be ignored --> + <properties id="5" prop_key="sonar.profile.php" text_value="Php Two" resource_id="[null]" user_id="[null]"/> + + <!-- Property on unknown project, will be ignored --> + <properties id="6" prop_key="sonar.profile.php" text_value="Php One" resource_id="2" user_id="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/schema.sql new file mode 100644 index 00000000000..004569aacfe --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/schema.sql @@ -0,0 +1,48 @@ +CREATE TABLE "PROJECTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(400), + "ROOT_ID" INTEGER, + "UUID" VARCHAR(50), + "PROJECT_UUID" VARCHAR(50), + "MODULE_UUID" VARCHAR(50), + "MODULE_UUID_PATH" VARCHAR(4000), + "NAME" VARCHAR(256), + "DESCRIPTION" VARCHAR(2000), + "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10), + "DEPRECATED_KEE" VARCHAR(400), + "PATH" VARCHAR(2000), + "LANGUAGE" VARCHAR(20), + "COPY_RESOURCE_ID" INTEGER, + "LONG_NAME" VARCHAR(256), + "PERSON_ID" INTEGER, + "CREATED_AT" TIMESTAMP, + "AUTHORIZATION_UPDATED_AT" BIGINT +); + +CREATE TABLE "RULES_PROFILES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "NAME" VARCHAR(100) NOT NULL, + "LANGUAGE" VARCHAR(20), + "KEE" VARCHAR(255) NOT NULL, + "PARENT_KEE" VARCHAR(255), + "RULES_UPDATED_AT" VARCHAR(100), + "IS_DEFAULT" BOOLEAN NOT NULL DEFAULT FALSE, + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP +); + +CREATE TABLE "PROPERTIES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "PROP_KEY" VARCHAR(512), + "RESOURCE_ID" INTEGER, + "TEXT_VALUE" CLOB(2147483647), + "USER_ID" INTEGER +); + +CREATE TABLE "PROJECT_QPROFILES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "PROJECT_UUID" VARCHAR(50) NOT NULL, + "PROFILE_KEY" VARCHAR(255) NOT NULL +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/remove_libraries-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/remove_libraries-result.xml new file mode 100644 index 00000000000..8c9f5d38dfb --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/remove_libraries-result.xml @@ -0,0 +1,17 @@ +<dataset> + + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + deprecated_kee="org.struts:struts" + uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- Removed --> + <!--<projects id="2" root_id="[null]" scope="PRJ" qualifier="LIB" kee="org.hamcrest:hamcrest-library" name="org.hamcrest:hamcrest-library"--> + <!--uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"--> + <!--description="[null]" long_name="org.hamcrest:hamcrest-library"--> + <!--enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]"--> + <!--created_at="2014-06-18" />--> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/remove_libraries.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/remove_libraries.xml new file mode 100644 index 00000000000..59392a2b98c --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/remove_libraries.xml @@ -0,0 +1,19 @@ +<dataset> + + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" + deprecated_kee="org.struts:struts" + uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="" + description="the description" long_name="Apache Struts" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> + + <!-- Should be removed --> + <projects id="2" root_id="[null]" scope="PRJ" qualifier="LIB" kee="org.hamcrest:hamcrest-library" + name="org.hamcrest:hamcrest-library" + uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]" + description="[null]" long_name="org.hamcrest:hamcrest-library" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" + deprecated_kee="[null]" + created_at="2014-06-18"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/schema.sql new file mode 100644 index 00000000000..b7307a0902a --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/schema.sql @@ -0,0 +1,22 @@ +CREATE TABLE "PROJECTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(400), + "ROOT_ID" INTEGER, + "UUID" VARCHAR(50), + "PROJECT_UUID" VARCHAR(50), + "MODULE_UUID" VARCHAR(50), + "MODULE_UUID_PATH" VARCHAR(4000), + "NAME" VARCHAR(256), + "DESCRIPTION" VARCHAR(2000), + "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10), + "DEPRECATED_KEE" VARCHAR(400), + "PATH" VARCHAR(2000), + "LANGUAGE" VARCHAR(20), + "COPY_RESOURCE_ID" INTEGER, + "LONG_NAME" VARCHAR(256), + "PERSON_ID" INTEGER, + "CREATED_AT" TIMESTAMP, + "AUTHORIZATION_UPDATED_AT" BIGINT +); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_enable_component-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_enable_component-result.xml new file mode 100644 index 00000000000..a103099ddf4 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_enable_component-result.xml @@ -0,0 +1,20 @@ +<dataset> + + <!-- root project --> + <projects id="1" uuid="PROJECT" project_uuid="PROJECT" kee="org.struts:struts" enabled="[true]"/> + + <!-- module --> + <projects id="10" uuid="MODULE" project_uuid="PROJECT" kee="org.struts:struts-core" enabled="[true]"/> + + <!-- sub modules --> + <projects id="21" uuid="SUB_MODULE_2" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[true]"/> + + <!-- directories --> + <projects id="31" uuid="DIRECTORY_2" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts" + enabled="[true]"/> + + <!-- files --> + <projects id="40" uuid="FILE_1" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java" + enabled="[true]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_enable_component.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_enable_component.xml new file mode 100644 index 00000000000..893efe4fd15 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_enable_component.xml @@ -0,0 +1,31 @@ +<dataset> + + <!-- root project --> + <projects id="1" uuid="PROJECT" project_uuid="PROJECT" kee="org.struts:struts" enabled="[true]"/> + + <!-- module --> + <projects id="10" uuid="MODULE" project_uuid="PROJECT" kee="org.struts:struts-core" enabled="[true]"/> + + <!-- sub modules --> + <projects id="20" uuid="SUB_MODULE_1" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[false]"/> + <!-- Only this component must be kept, as it's enabled --> + <projects id="21" uuid="SUB_MODULE_2" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[true]"/> + <projects id="22" uuid="SUB_MODULE_3" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[false]"/> + + <!-- directories --> + <projects id="30" uuid="DIRECTORY_1" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts" + enabled="[false]"/> + <!-- Only this component must be kept, as it's enabled --> + <projects id="31" uuid="DIRECTORY_2" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts" + enabled="[true]"/> + + <!-- files --> + <!-- Only this component must be kept, as it's enabled --> + <projects id="40" uuid="FILE_1" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java" + enabled="[true]"/> + <projects id="41" uuid="FILE_2" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java" + enabled="[false]"/> + <projects id="42" uuid="FILE_3" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java" + enabled="[false]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_last_component-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_last_component-result.xml new file mode 100644 index 00000000000..cd86088d452 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_last_component-result.xml @@ -0,0 +1,20 @@ +<dataset> + + <!-- root project --> + <projects id="1" uuid="PROJECT" project_uuid="PROJECT" kee="org.struts:struts" enabled="[true]"/> + + <!-- module --> + <projects id="10" uuid="MODULE" project_uuid="PROJECT" kee="org.struts:struts-core" enabled="[true]"/> + + <!-- sub modules --> + <projects id="22" uuid="SUB_MODULE_3" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[false]"/> + + <!-- directories --> + <projects id="31" uuid="DIRECTORY_2" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts" + enabled="[false]"/> + + <!-- files --> + <projects id="42" uuid="FILE_3" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java" + enabled="[false]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_last_component.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_last_component.xml new file mode 100644 index 00000000000..72f1bea892e --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_last_component.xml @@ -0,0 +1,31 @@ +<dataset> + + <!-- root project --> + <projects id="1" uuid="PROJECT" project_uuid="PROJECT" kee="org.struts:struts" enabled="[true]"/> + + <!-- module --> + <projects id="10" uuid="MODULE" project_uuid="PROJECT" kee="org.struts:struts-core" enabled="[true]"/> + + <!-- sub modules --> + <projects id="20" uuid="SUB_MODULE_1" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[false]"/> + <projects id="21" uuid="SUB_MODULE_2" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[false]"/> + <!-- Only this component must be kept, as it's the last one --> + <projects id="22" uuid="SUB_MODULE_3" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[false]"/> + + <!-- directories --> + <projects id="30" uuid="DIRECTORY_1" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts" + enabled="[false]"/> + <!-- Only this component must be kept, as it's the last one --> + <projects id="31" uuid="DIRECTORY_2" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts" + enabled="[false]"/> + + <!-- files --> + <projects id="40" uuid="FILE_1" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java" + enabled="[false]"/> + <projects id="41" uuid="FILE_2" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java" + enabled="[false]"/> + <!-- Only this component must be kept, as it's the last one --> + <projects id="42" uuid="FILE_3" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java" + enabled="[false]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/migrate-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/migrate-result.xml new file mode 100644 index 00000000000..75d7c73b2f6 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/migrate-result.xml @@ -0,0 +1,26 @@ +<dataset> + + <!-- root project --> + <projects id="1" uuid="PROJECT" project_uuid="PROJECT" kee="org.struts:struts" enabled="[true]"/> + <issues id="1" component_uuid="PROJECT" project_uuid="PROJECT"/> + + <!-- module --> + <projects id="10" uuid="MODULE" project_uuid="PROJECT" kee="org.struts:struts-core" enabled="[true]"/> + + <!-- sub module --> + <projects id="21" uuid="SUB_MODULE_2" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[true]"/> + <issues id="20" component_uuid="SUB_MODULE_2" project_uuid="PROJECT"/> + <issues id="21" component_uuid="SUB_MODULE_2" project_uuid="PROJECT"/> + <issues id="22" component_uuid="SUB_MODULE_2" project_uuid="PROJECT"/> + + <!-- removed directory --> + <projects id="31" uuid="DIRECTORY_2" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts" + enabled="[false]"/> + + <!-- removed file --> + <projects id="42" uuid="FILE_3" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java" + enabled="[false]"/> + <issues id="40" component_uuid="FILE_3" project_uuid="PROJECT"/> + <issues id="41" component_uuid="FILE_3" project_uuid="PROJECT"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/migrate.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/migrate.xml new file mode 100644 index 00000000000..e4a4ea22046 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/migrate.xml @@ -0,0 +1,35 @@ +<dataset> + + <!-- root project --> + <projects id="1" uuid="PROJECT" project_uuid="PROJECT" kee="org.struts:struts" enabled="[true]"/> + <issues id="1" component_uuid="PROJECT" project_uuid="PROJECT"/> + + <!-- module --> + <projects id="10" uuid="MODULE" project_uuid="PROJECT" kee="org.struts:struts-core" enabled="[true]"/> + + <!-- disabled sub module -> should be removed and its issues should be attached to the enabled one --> + <projects id="20" uuid="SUB_MODULE_1" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[false]"/> + <issues id="20" component_uuid="SUB_MODULE_1" project_uuid="PROJECT"/> + <issues id="21" component_uuid="SUB_MODULE_1" project_uuid="PROJECT"/> + + <!-- enabled sub module -> issues from disabled should be attached to it --> + <projects id="21" uuid="SUB_MODULE_2" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[true]"/> + <issues id="22" component_uuid="SUB_MODULE_2" project_uuid="PROJECT"/> + + <!-- disabled directories, only one should be kept --> + <projects id="30" uuid="DIRECTORY_1" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts" + enabled="[false]"/> + <projects id="31" uuid="DIRECTORY_2" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts" + enabled="[false]"/> + + <!-- disabled files -> only one should be kept and issue from removed one should be attached to the remaining one --> + <projects id="40" uuid="FILE_1" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java" + enabled="[false]"/> + <projects id="41" uuid="FILE_2" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java" + enabled="[false]"/> + <projects id="42" uuid="FILE_3" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java" + enabled="[false]"/> + <issues id="40" component_uuid="FILE_1" project_uuid="PROJECT"/> + <issues id="41" component_uuid="FILE_3" project_uuid="PROJECT"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/schema.sql new file mode 100644 index 00000000000..19915dfd3b0 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/schema.sql @@ -0,0 +1,17 @@ +CREATE TABLE "PROJECTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(400), + "UUID" VARCHAR(50), + "PROJECT_UUID" VARCHAR(50), + "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE +); + +CREATE INDEX "PROJECTS_KEE" ON "PROJECTS" ("KEE", "ENABLED"); + +CREATE TABLE "ISSUES" ( + "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "COMPONENT_UUID" VARCHAR(50), + "PROJECT_UUID" VARCHAR(50) +); + +CREATE INDEX "ISSUES_COMPONENT_UUID" ON "ISSUES" ("COMPONENT_UUID"); diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/remove_libraries-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/remove_libraries-result.xml new file mode 100644 index 00000000000..d9ebf91906c --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/remove_libraries-result.xml @@ -0,0 +1,24 @@ +<dataset> + + <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="TRK" created_at="1228222680000" build_date="1228222680000" + version="[null]" path=""/> + + <!-- Removed --> + <!--<snapshots id="10" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"--> + <!--status="P" islast="[false]" purge_status="[null]"--> + <!--period1_mode="[null]" period1_param="[null]" period1_date="[null]"--> + <!--period2_mode="[null]" period2_param="[null]" period2_date="[null]"--> + <!--period3_mode="[null]" period3_param="[null]" period3_date="[null]"--> + <!--period4_mode="[null]" period4_param="[null]" period4_date="[null]"--> + <!--period5_mode="[null]" period5_param="[null]" period5_date="[null]"--> + <!--depth="[null]" scope="PRJ" qualifier="LIB" created_at="1228136280000" build_date="1228136280000"--> + <!--version="[null]" path=""/>--> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/remove_libraries.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/remove_libraries.xml new file mode 100644 index 00000000000..3cba1535e62 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/remove_libraries.xml @@ -0,0 +1,24 @@ +<dataset> + + <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="TRK" created_at="1228222680000" build_date="1228222680000" + version="[null]" path=""/> + + <!-- Should be removed --> + <snapshots id="10" project_id="10" parent_snapshot_id="[null]" root_project_id="10" root_snapshot_id="[null]" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="LIB" created_at="1228136280000" build_date="1228136280000" + version="[null]" path=""/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/schema.sql new file mode 100644 index 00000000000..832463b246c --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/schema.sql @@ -0,0 +1,32 @@ +CREATE TABLE "SNAPSHOTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "CREATED_AT" BIGINT, + "BUILD_DATE" BIGINT, + "PROJECT_ID" INTEGER NOT NULL, + "PARENT_SNAPSHOT_ID" INTEGER, + "STATUS" VARCHAR(4) NOT NULL DEFAULT 'U', + "PURGE_STATUS" INTEGER, + "ISLAST" BOOLEAN NOT NULL DEFAULT FALSE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10), + "ROOT_SNAPSHOT_ID" INTEGER, + "VERSION" VARCHAR(500), + "PATH" VARCHAR(500), + "DEPTH" INTEGER, + "ROOT_PROJECT_ID" INTEGER, + "PERIOD1_MODE" VARCHAR(100), + "PERIOD1_PARAM" VARCHAR(100), + "PERIOD1_DATE" BIGINT, + "PERIOD2_MODE" VARCHAR(100), + "PERIOD2_PARAM" VARCHAR(100), + "PERIOD2_DATE" BIGINT, + "PERIOD3_MODE" VARCHAR(100), + "PERIOD3_PARAM" VARCHAR(100), + "PERIOD3_DATE" BIGINT, + "PERIOD4_MODE" VARCHAR(100), + "PERIOD4_PARAM" VARCHAR(100), + "PERIOD4_DATE" BIGINT, + "PERIOD5_MODE" VARCHAR(100), + "PERIOD5_PARAM" VARCHAR(100), + "PERIOD5_DATE" BIGINT +); |