--- /dev/null
+#
+# 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.
+#
+
+#
+# SonarQube 6.0
+#
+class AddUuidColumnsToSnapshots < ActiveRecord::Migration
+
+ def self.up
+ execute_java_migration('org.sonar.db.version.v60.AddUuidColumnsToSnapshots')
+ end
+end
--- /dev/null
+#
+# 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.
+#
+
+#
+# SonarQube 6.0
+#
+class PopulateUuidColumnsOfSnapshots < ActiveRecord::Migration
+
+ def self.up
+ execute_java_migration('org.sonar.db.version.v60.PopulateUuidColumnsOfSnapshots')
+ end
+end
--- /dev/null
+#
+# 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.
+#
+
+#
+# SonarQube 6.0
+#
+class CleanOrphanRowsInSnapshots < ActiveRecord::Migration
+
+ def self.up
+ execute_java_migration('org.sonar.db.version.v60.CleanOrphanRowsInSnapshots')
+ end
+end
--- /dev/null
+#
+# 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.
+#
+
+#
+# SonarQube 6.0
+#
+class MakeUuidColumnsNotNullOnSnapshots < ActiveRecord::Migration
+
+ def self.up
+ execute_java_migration('org.sonar.db.version.v60.MakeUuidColumnsNotNullOnSnapshots')
+
+ add_index :snapshots, :component_uuid, :name => 'snapshot_component'
+ add_index :snapshots, :root_component_uuid, :name => 'snapshot_root_component'
+ end
+end
--- /dev/null
+#
+# 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.
+#
+
+#
+# SonarQube 6.0
+#
+class DropSnapshotProjectIdFromSnapshots < ActiveRecord::Migration
+
+ def self.up
+ remove_index :snapshots, :name => 'snapshot_project_id'
+ remove_index :snapshots, :name => 'snapshots_root_project_id'
+ end
+end
--- /dev/null
+#
+# 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.
+#
+
+#
+# SonarQube 6.0
+#
+class DropIdColumnsFromSnapshots < ActiveRecord::Migration
+
+ def self.up
+ execute_java_migration('org.sonar.db.version.v60.DropIdColumnsFromSnapshots')
+ end
+end
public class DatabaseVersion {
- public static final int LAST_VERSION = 1_207;
+ public static final int LAST_VERSION = 1_213;
/**
* The minimum supported version which can be upgraded. Lower
import java.sql.Connection;
import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import org.sonar.core.util.ProgressLogger;
import org.sonar.db.Database;
+import static com.google.common.base.Preconditions.checkState;
+
public class MassUpdate {
+ @FunctionalInterface
public interface Handler {
/**
* Convert some column values of a given row.
boolean handle(Select.Row row, SqlStatement update) throws SQLException;
}
+ @FunctionalInterface
+ public interface MultiHandler {
+ /**
+ * Convert some column values of a given row.
+ *
+ * @param updateIndex 0-based
+ * @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, int updateIndex) throws SQLException;
+ }
+
private final Database db;
private final Connection readConnection;
private final Connection writeConnection;
private final ProgressLogger progress = ProgressLogger.create(getClass(), counter);
private Select select;
- private Upsert update;
+ private List<UpsertImpl> updates = new ArrayList<>(1);
MassUpdate(Database db, Connection readConnection, Connection writeConnection) {
this.db = db;
}
public MassUpdate update(String sql) throws SQLException {
- this.update = UpsertImpl.create(writeConnection, sql);
+ this.updates.add(UpsertImpl.create(writeConnection, sql));
return this;
}
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");
+ public void execute(Handler handler) throws SQLException {
+ checkState(select != null && !updates.isEmpty(), "SELECT or UPDATE requests are not defined");
+ checkState(updates.size() == 1, "There should be only one update when using a " + Handler.class.getName());
+
+ progress.start();
+ try {
+ select.scroll(row -> callSingleHandler(handler, updates.iterator().next(), row));
+ closeUpdates();
+
+ // log the total number of processed rows
+ progress.log();
+ } finally {
+ progress.stop();
}
+ }
+
+ public void execute(MultiHandler handler) throws SQLException {
+ checkState(select != null && !updates.isEmpty(), "SELECT or UPDATE(s) 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();
+ select.scroll(row -> callMultiHandler(handler, updates, row));
+ closeUpdates();
// log the total number of processed rows
progress.log();
}
}
+ private void callSingleHandler(Handler handler, Upsert update, Select.Row row) throws SQLException {
+ if (handler.handle(row, update)) {
+ update.addBatch();
+ }
+ counter.getAndIncrement();
+ }
+
+ private void callMultiHandler(MultiHandler handler, List<UpsertImpl> updates, Select.Row row) throws SQLException {
+ int i = 0;
+ for (UpsertImpl update : updates) {
+ if (handler.handle(row, update, i)) {
+ update.addBatch();
+ }
+ i++;
+ }
+ counter.getAndIncrement();
+ }
+
+ private void closeUpdates() throws SQLException {
+ for (UpsertImpl update : updates) {
+ if (update.getBatchCount() > 0L) {
+ update.execute().commit();
+ }
+ update.close();
+ }
+ }
+
}
import org.sonar.db.version.v56.FixLengthOfIssuesMessageOnOracle;
import org.sonar.db.version.v56.FixTypeOfRuleTypeOnMysql;
import org.sonar.db.version.v60.AddUuidColumnsToResourceIndex;
+import org.sonar.db.version.v60.AddUuidColumnsToSnapshots;
import org.sonar.db.version.v60.CleanOrphanRowsInResourceIndex;
+import org.sonar.db.version.v60.CleanOrphanRowsInSnapshots;
import org.sonar.db.version.v60.DropIdColumnsFromResourceIndex;
import org.sonar.db.version.v60.DropUnusedMeasuresColumns;
+import org.sonar.db.version.v60.DropIdColumnsFromSnapshots;
import org.sonar.db.version.v60.MakeUuidColumnsNotNullOnResourceIndex;
+import org.sonar.db.version.v60.MakeUuidColumnsNotNullOnSnapshots;
import org.sonar.db.version.v60.PopulateUuidColumnsOfResourceIndex;
+import org.sonar.db.version.v60.PopulateUuidColumnsOfSnapshots;
public class MigrationStepModule extends Module {
@Override
CleanOrphanRowsInResourceIndex.class,
MakeUuidColumnsNotNullOnResourceIndex.class,
DropIdColumnsFromResourceIndex.class,
- DropUnusedMeasuresColumns.class);
+ DropUnusedMeasuresColumns.class,
+ AddUuidColumnsToSnapshots.class,
+ PopulateUuidColumnsOfSnapshots.class,
+ CleanOrphanRowsInSnapshots.class,
+ MakeUuidColumnsNotNullOnSnapshots.class,
+ DropIdColumnsFromSnapshots.class);
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v60;
+
+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.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public class AddUuidColumnsToSnapshots extends DdlChange {
+
+ private static final String TABLE_SNAPSHOTS = "snapshots";
+
+ private final Database db;
+
+ public AddUuidColumnsToSnapshots(Database db) {
+ super(db);
+ this.db = db;
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(new AddColumnsBuilder(db.getDialect(), TABLE_SNAPSHOTS)
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("component_uuid").setLimit(UUID_VARCHAR_SIZE).setIsNullable(true).build())
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("root_component_uuid").setLimit(UUID_VARCHAR_SIZE).setIsNullable(true).build())
+ .build());
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v60;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.version.BaseDataChange;
+import org.sonar.db.version.MassUpdate;
+
+public class CleanOrphanRowsInSnapshots extends BaseDataChange {
+
+ public CleanOrphanRowsInSnapshots(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ MassUpdate massUpdate = context.prepareMassUpdate();
+ massUpdate.select("SELECT sn.id, sn.project_id, sn.root_project_id from snapshots sn where sn.component_uuid is null or sn.root_component_uuid is null");
+ massUpdate.update("DELETE from duplications_index WHERE snapshot_id=? or project_snapshot_id=?");
+ massUpdate.update("DELETE from project_measures WHERE snapshot_id=?");
+ massUpdate.update("DELETE from ce_activity WHERE snapshot_id=?");
+ massUpdate.update("DELETE from events WHERE snapshot_id=?");
+ massUpdate.update("DELETE from snapshots WHERE id=?");
+ massUpdate.rowPluralName("snapshots");
+ massUpdate.execute((row, update, updateIndex) -> {
+ long snapshotId = row.getLong(1);
+ switch (updateIndex) {
+ case 0:
+ update.setLong(1, snapshotId);
+ update.setLong(2, snapshotId);
+ return true;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ update.setLong(1, snapshotId);
+ return true;
+ default:
+ throw new IllegalArgumentException("Unsupported update index " + updateIndex);
+ }
+ });
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v60;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.version.DdlChange;
+import org.sonar.db.version.DropColumnsBuilder;
+
+public class DropIdColumnsFromSnapshots extends DdlChange {
+
+ private static final String TABLE_SNAPSHOTS = "snapshots";
+
+ private final Database db;
+
+ public DropIdColumnsFromSnapshots(Database db) {
+ super(db);
+ this.db = db;
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(
+ new DropColumnsBuilder(
+ db.getDialect(), TABLE_SNAPSHOTS,
+ "project_id", "root_project_id")
+ .build());
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v60;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.version.AlterColumnsBuilder;
+import org.sonar.db.version.DdlChange;
+
+import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public class MakeUuidColumnsNotNullOnSnapshots extends DdlChange {
+
+ private static final String TABLE_SNAPSHOTS = "snapshots";
+
+ private final Database db;
+
+ public MakeUuidColumnsNotNullOnSnapshots(Database db) {
+ super(db);
+ this.db = db;
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(new AlterColumnsBuilder(db.getDialect(), TABLE_SNAPSHOTS)
+ .updateColumn(newVarcharColumnDefBuilder().setColumnName("component_uuid").setLimit(UUID_VARCHAR_SIZE).setIsNullable(false).build())
+ .updateColumn(newVarcharColumnDefBuilder().setColumnName("root_component_uuid").setLimit(UUID_VARCHAR_SIZE).setIsNullable(false).build())
+ .build());
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v60;
+
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+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 PopulateUuidColumnsOfSnapshots extends BaseDataChange {
+
+ public PopulateUuidColumnsOfSnapshots(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ Map<Long, String> componentUuidById = buildComponentUuidMap(context);
+ if (componentUuidById.isEmpty()) {
+ return;
+ }
+
+ populateUuidColumns(context, componentUuidById);
+ }
+
+ private Map<Long, String> buildComponentUuidMap(Context context) throws SQLException {
+ Map<Long, String> componentUuidById = new HashMap<>();
+ context.prepareSelect("select distinct p.id, p.uuid from projects p" +
+ " join snapshots sn1 on sn1.project_id = p.id and sn1.component_uuid is null")
+ .scroll(row -> componentUuidById.put(row.getLong(1), row.getString(2)));
+ context.prepareSelect("select distinct p.id, p.uuid from projects p" +
+ " join snapshots sn2 on sn2.root_project_id = p.id and sn2.root_component_uuid is null")
+ .scroll(row -> componentUuidById.put(row.getLong(1), row.getString(2)));
+ return componentUuidById;
+ }
+
+ private void populateUuidColumns(Context context, Map<Long, String> componentUuidById) throws SQLException {
+ MassUpdate massUpdate = context.prepareMassUpdate();
+ massUpdate.select("SELECT sn.id, sn.project_id, sn.root_project_id from snapshots sn where sn.component_uuid is null or sn.root_component_uuid is null");
+ massUpdate.update("UPDATE snapshots SET component_uuid=?, root_component_uuid=? WHERE id=?");
+ massUpdate.rowPluralName("snapshots");
+ massUpdate.execute((row, update) -> this.handle(componentUuidById, row, update));
+ }
+
+ private boolean handle(Map<Long, String> componentUuidById, Select.Row row, SqlStatement update) throws SQLException {
+ long id = row.getLong(1);
+ long componentId = row.getLong(2);
+ long rootProjectId = row.getLong(3);
+
+ String componentUuid = componentUuidById.get(componentId);
+ String rootComponentUuid = componentUuidById.get(rootProjectId);
+
+ if (componentUuid == null && rootComponentUuid == null) {
+ return false;
+ }
+
+ update.setString(1, componentUuid);
+ update.setString(2, rootComponentUuid);
+ update.setLong(3, id);
+
+ return true;
+ }
+
+}
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1205');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1206');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1207');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1208');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1209');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1210');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1211');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1212');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1213');
INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, EXTERNAL_IDENTITY, EXTERNAL_IDENTITY_PROVIDER, USER_LOCAL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'admin', 'sonarqube', true, 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '1418215735482', '1418215735482', null, null);
ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2;
"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,
+ "COMPONENT_UUID" VARCHAR(50) NOT NULL,
"PARENT_SNAPSHOT_ID" INTEGER,
"STATUS" VARCHAR(4) NOT NULL DEFAULT 'U',
"PURGE_STATUS" INTEGER,
"VERSION" VARCHAR(500),
"PATH" VARCHAR(500),
"DEPTH" INTEGER,
- "ROOT_PROJECT_ID" INTEGER,
+ "ROOT_COMPONENT_UUID" VARCHAR(50) NOT NULL,
"PERIOD1_MODE" VARCHAR(100),
"PERIOD1_PARAM" VARCHAR(100),
"PERIOD1_DATE" BIGINT,
CREATE INDEX "SNAPSHOTS_PARENT" ON "SNAPSHOTS" ("PARENT_SNAPSHOT_ID");
-CREATE INDEX "SNAPSHOT_PROJECT_ID" ON "SNAPSHOTS" ("PROJECT_ID");
+CREATE INDEX "SNAPSHOT_COMPONENT" ON "SNAPSHOTS" ("COMPONENT_UUID");
CREATE INDEX "RULES_PARAMETERS_RULE_ID" ON "RULES_PARAMETERS" ("RULE_ID");
CREATE INDEX "USERS_UPDATED_AT" ON "USERS" ("UPDATED_AT");
-CREATE INDEX "SNAPSHOTS_ROOT_PROJECT_ID" ON "SNAPSHOTS" ("ROOT_PROJECT_ID");
+CREATE INDEX "SNAPSHOTS_ROOT_COMPONENT" ON "SNAPSHOTS" ("ROOT_COMPONENT_UUID");
CREATE UNIQUE INDEX "UNIQ_GROUP_ROLES" ON "GROUP_ROLES" ("GROUP_ID", "RESOURCE_ID", "ROLE");
/**
* Very simple helper method to insert some data into a table.
* It's the responsibility of the caller to convert column values to string.
+ *
+ * @param valuesByColumn column name and value pairs, if any value is null, the associated column won't be inserted
*/
public void executeInsert(String table, String... valuesByColumn) {
executeInsert(table, mapOf(valuesByColumn));
private static Map<String, String> mapOf(String... values) {
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
for (int i = 0; i < values.length; i++) {
- builder.put(values[i], values[i + 1]);
+ String key = values[i];
+ String value = values[i + 1];
+ if (value != null) {
+ builder.put(key, value);
+ }
i++;
}
return builder.build();
public void verify_count_of_added_MigrationStep_types() {
ComponentContainer container = new ComponentContainer();
new MigrationStepModule().configure(container);
- assertThat(container.size()).isEqualTo(71);
+ assertThat(container.size()).isEqualTo(76);
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v60;
+
+import java.sql.SQLException;
+import java.sql.Types;
+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 static java.lang.String.valueOf;
+
+public class AddUuidColumnsToSnapshotsTest {
+
+ public static final String SNAPSHOTS_TABLE = "snapshots";
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, AddUuidColumnsToSnapshotsTest.class, "old_snapshots.sql");
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private AddUuidColumnsToSnapshots underTest = new AddUuidColumnsToSnapshots(db.database());
+
+ @Test
+ public void migration_adds_columns_to_empty_table() throws SQLException {
+ underTest.execute();
+
+ verifyAddedColumns();
+ }
+
+ @Test
+ public void migration_adds_columns_to_populated_table() throws SQLException {
+ for (int i = 0; i < 9; i++) {
+ db.executeInsert(
+ SNAPSHOTS_TABLE,
+ "PROJECT_ID", valueOf(i),
+ "ISLAST", "TRUE");
+ }
+ db.commit();
+
+ underTest.execute();
+
+ verifyAddedColumns();
+ }
+
+ private void verifyAddedColumns() {
+ db.assertColumnDefinition(SNAPSHOTS_TABLE, "component_uuid", Types.VARCHAR, 50, true);
+ db.assertColumnDefinition(SNAPSHOTS_TABLE, "root_component_uuid", Types.VARCHAR, 50, true);
+ }
+
+ @Test
+ public void migration_is_not_reentrant() throws SQLException {
+ underTest.execute();
+
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Fail to execute ");
+ underTest.execute();
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v60;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+
+import static java.lang.String.valueOf;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class CleanOrphanRowsInSnapshotsTest {
+
+ public static final String SNAPSHOTS_TABLE = "snapshots";
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, CleanOrphanRowsInSnapshotsTest.class,
+ "in_progress_snapshots_and_children_tables.sql");
+
+ private CleanOrphanRowsInSnapshots underTest = new CleanOrphanRowsInSnapshots(db.database());
+
+ @Test
+ public void migration_has_no_effect_on_empty_table() throws SQLException {
+ underTest.execute();
+
+ assertThat(db.countRowsOfTable(SNAPSHOTS_TABLE)).isEqualTo(0);
+ }
+
+ @Test
+ public void migration_deletes_any_row_with_a_null_uuid() throws SQLException {
+ insertSnapshots(1, true, true);
+ insertSnapshots(2, false, false);
+ insertSnapshots(3, true, false);
+ insertSnapshots(4, false, true);
+ insertSnapshots(5, true, true);
+ db.commit();
+
+ underTest.execute();
+
+ assertThat(idsOfRowsInSnapshots()).containsOnly(1l, 5l);
+ }
+
+ @Test
+ public void migration_deletes_rows_in_children_tables_referencing_snapshots_with_at_least_null_uuid() throws SQLException {
+ insertSnapshots(1, true, true);
+ insertSnapshots(2, false, true);
+ insertSnapshots(3, true, false);
+ insertDuplicationIndex(1, 1);
+ insertDuplicationIndex(30, 1);
+ insertDuplicationIndex(1, 40);
+ insertDuplicationIndex(50, 2);
+ insertDuplicationIndex(2, 2);
+ insertDuplicationIndex(2, 60);
+ insertDuplicationIndex(3, 3);
+ insertDuplicationIndex(70, 3);
+ insertDuplicationIndex(3, 90);
+ insertProjectMeasure(1);
+ insertProjectMeasure(2);
+ insertProjectMeasure(3);
+ insertCeActivity(1);
+ insertCeActivity(2);
+ insertCeActivity(3);
+ insertEvents(1);
+ insertEvents(2);
+ insertEvents(3);
+ db.commit();
+
+ underTest.execute();
+
+ verifyLineCountsPerSnapshot(1, 1, 3, 1, 1, 1);
+ verifyLineCountsPerSnapshot(2, 0, 0, 0, 0, 0);
+ verifyLineCountsPerSnapshot(3, 0, 0, 0, 0, 0);
+ }
+
+ private void verifyLineCountsPerSnapshot(int snapshotId, int snapshotCount, int duplicationIndexCount, int projectMeasureCount, int ceActivityCount, int eventCount) {
+ assertThat(count("SNAPSHOTS where id=" + snapshotId)).isEqualTo(snapshotCount);
+ assertThat(count("DUPLICATIONS_INDEX where snapshot_id=" + snapshotId + " or project_snapshot_id=" +snapshotId)).isEqualTo(duplicationIndexCount);
+ assertThat(count("PROJECT_MEASURES where snapshot_id=" + snapshotId)).isEqualTo(projectMeasureCount);
+ assertThat(count("CE_ACTIVITY where snapshot_id=" + snapshotId)).isEqualTo(ceActivityCount);
+ assertThat(count("EVENTS where snapshot_id=" + snapshotId)).isEqualTo(eventCount);
+ }
+
+ private long count(String tableAndWhereClause) {
+ return (Long) db.selectFirst("select count(*) from " + tableAndWhereClause).entrySet().iterator().next().getValue();
+ }
+
+
+ private void insertDuplicationIndex(int snapshotId, int parentSnapshotId) {
+ db.executeInsert(
+ "DUPLICATIONS_INDEX",
+ "SNAPSHOT_ID", valueOf(snapshotId),
+ "PROJECT_SNAPSHOT_ID", valueOf(parentSnapshotId),
+ "HASH", "hash_" + snapshotId + "-" + parentSnapshotId,
+ "INDEX_IN_FILE", valueOf(snapshotId + parentSnapshotId),
+ "START_LINE", "1",
+ "END_LINE", "1");
+ }
+
+ private void insertProjectMeasure(int snapshotId) {
+ db.executeInsert(
+ "PROJECT_MEASURES",
+ "SNAPSHOT_ID", valueOf(snapshotId),
+ "METRIC_ID", "111");
+ }
+
+ private void insertCeActivity(int snapshotId) {
+ db.executeInsert(
+ "CE_ACTIVITY",
+ "UUID", valueOf(snapshotId + 10),
+ "TASK_TYPE", "REPORT",
+ "STATUS", "OK",
+ "COMPONENT_UUID", valueOf(snapshotId + 20),
+ "SNAPSHOT_ID", valueOf(snapshotId),
+ "IS_LAST", "true",
+ "IS_LAST_KEY", "key",
+ "SUBMITTED_AT", "984651",
+ "CREATED_AT", "984651",
+ "UPDATED_AT", "984651");
+ }
+
+ private void insertEvents(int snapshotId) {
+ db.executeInsert(
+ "EVENTS",
+ "SNAPSHOT_ID", valueOf(snapshotId),
+ "EVENT_DATE", "984651",
+ "CREATED_AT", "984651");
+ }
+
+ private void insertSnapshots(long id, boolean hasComponentUiid, boolean hasRootComponentUuid) {
+ db.executeInsert(
+ SNAPSHOTS_TABLE,
+ "ID", valueOf(id),
+ "ISLAST", "TRUE",
+ "PROJECT_ID", valueOf(id + 300),
+ "COMPONENT_UUID", hasComponentUiid ? "uuid_" + id : null,
+ "ROOT_COMPONENT_UUID", hasRootComponentUuid ? "root_uuid_" + id : null);
+ }
+
+ private List<Long> idsOfRowsInSnapshots() {
+ return db.select("select ID from snapshots").stream().map(map -> (Long) map.get("ID")).collect(Collectors.toList());
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v60;
+
+import java.sql.SQLException;
+import org.junit.Test;
+import org.sonar.db.Database;
+import org.sonar.db.dialect.PostgreSql;
+import org.sonar.db.version.DdlChange;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class DropIdColumnsFromSnapshotsTest {
+
+ private Database database = mock(Database.class);
+
+ private DropIdColumnsFromSnapshots underTest = new DropIdColumnsFromSnapshots(database);
+
+ @Test
+ public void verify_generated_sql_on_postgresql() throws SQLException {
+ when(database.getDialect()).thenReturn(new PostgreSql());
+
+ DdlChange.Context context = mock(DdlChange.Context.class);
+ underTest.execute(context);
+
+ verify(context).execute("ALTER TABLE snapshots DROP COLUMN project_id, DROP COLUMN root_project_id");
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v60;
+
+import java.sql.SQLException;
+import java.sql.Types;
+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 static java.lang.String.valueOf;
+
+public class MakeUuidColumnsNotNullOnSnapshotsTest {
+
+ private static final String SNAPSHOTS_TABLE = "snapshots";
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, MakeUuidColumnsNotNullOnSnapshotsTest.class,
+ "in_progress_snapshots.sql");
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private MakeUuidColumnsNotNullOnSnapshots underTest = new MakeUuidColumnsNotNullOnSnapshots(db.database());
+
+ @Test
+ public void migration_sets_uuid_columns_not_nullable_on_empty_table() throws SQLException {
+ underTest.execute();
+
+ verifyColumnDefinitions();
+ }
+
+ @Test
+ public void migration_sets_uuid_columns_not_nullable_on_populated_table() throws SQLException {
+ insertSnapshots(1, true, true);
+ insertSnapshots(2, true, true);
+
+ underTest.execute();
+
+ verifyColumnDefinitions();
+ }
+
+ @Test
+ public void migration_fails_if_some_uuid_columns_are_null() throws SQLException {
+ insertSnapshots(1, false, true);
+
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Fail to execute");
+
+ underTest.execute();
+ }
+
+ private void verifyColumnDefinitions() {
+ db.assertColumnDefinition(SNAPSHOTS_TABLE, "component_uuid", Types.VARCHAR, 50, false);
+ db.assertColumnDefinition(SNAPSHOTS_TABLE, "root_component_uuid", Types.VARCHAR, 50, false);
+ }
+
+ private void insertSnapshots(long id, boolean hasComponentUiid, boolean hasRootComponentUuid) {
+ db.executeInsert(
+ SNAPSHOTS_TABLE,
+ "ID", valueOf(id),
+ "ISLAST", "TRUE",
+ "PROJECT_ID", valueOf(id + 300),
+ "COMPONENT_UUID", hasComponentUiid ? "uuid_" + id : null,
+ "ROOT_COMPONENT_UUID", hasRootComponentUuid ? "root_uuid_" + id : null);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v60;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Nullable;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+
+import static java.lang.String.valueOf;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class PopulateUuidColumnsOfSnapshotsTest {
+
+ private static final String SNAPSHOTS_TABLE = "snapshots";
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, PopulateUuidColumnsOfSnapshotsTest.class,
+ "in_progress_snapshots_with_projects.sql");
+
+ private PopulateUuidColumnsOfSnapshots underTest = new PopulateUuidColumnsOfSnapshots(db.database());
+
+ @Test
+ public void migration_has_no_effect_on_empty_tables() throws SQLException {
+ underTest.execute();
+
+ assertThat(db.countRowsOfTable(SNAPSHOTS_TABLE)).isEqualTo(0);
+ assertThat(db.countRowsOfTable("projects")).isEqualTo(0);
+ }
+
+ @Test
+ public void migration_updates_uuid_columns_with_values_from_table_projects_when_they_exist() throws SQLException {
+ String uuid1 = insertComponent(40);
+ String uuid2 = insertComponent(50);
+ String uuid3 = insertComponent(60);
+ String uuid4 = insertComponent(70);
+ String uuid5 = insertComponent(80);
+
+ insertSnapshots(1, 40, 50L);
+ insertSnapshots(2, 60, 70L);
+ insertSnapshots(3, 90, 70L); // 90 does not exist
+ insertSnapshots(4, 40, 100L); // 100 does not exist
+ insertSnapshots(5, 110, 100L); // 110 and 100 do not exist
+ insertSnapshots(6, 80, null); // no root
+ insertSnapshots(7, 120, null); // no root and 120 does not exist
+ db.commit();
+
+ underTest.execute();
+
+ verifySnapshots(1, 40, uuid1, 50L, uuid2);
+ verifySnapshots(2, 60, uuid3, 70L, uuid4);
+ verifySnapshots(3, 90, null, 70L, uuid4);
+ verifySnapshots(4, 40, uuid1, 100L, null);
+ verifySnapshots(5, 110, null, 100L, null);
+ verifySnapshots(6, 80, uuid5, null, null);
+ verifySnapshots(7, 120, null, null, null);
+ }
+
+ @Test
+ public void migration_is_reentrant() throws SQLException {
+ String uuid1 = insertComponent(40);
+ String uuid2 = insertComponent(50);
+ insertSnapshots(1, 40, 50L);
+
+ underTest.execute();
+ verifySnapshots(1, 40, uuid1, 50L, uuid2);
+
+ underTest.execute();
+ verifySnapshots(1, 40, uuid1, 50L, uuid2);
+ }
+
+ private void insertSnapshots(long id, long projectId, @Nullable Long rootId) {
+ db.executeInsert(
+ SNAPSHOTS_TABLE,
+ "ID", valueOf(id),
+ "ISLAST", "TRUE",
+ "PROJECT_ID", valueOf(projectId),
+ "ROOT_PROJECT_ID", rootId == null ? null : valueOf(rootId));
+ }
+
+ private String insertComponent(long id) {
+ String uuid = "uuid_" + id;
+ db.executeInsert(
+ "projects",
+ "ID", valueOf(id),
+ "UUID", uuid);
+ return uuid;
+ }
+
+ private void verifySnapshots(long id, long resourceId, @Nullable String componentUuid, @Nullable Long rootProjectId, @Nullable String rootComponentUuid) {
+ List<Map<String, Object>> rows = db.select("select PROJECT_ID, COMPONENT_UUID, ROOT_PROJECT_ID, ROOT_COMPONENT_UUID from snapshots where ID=" + id);
+ assertThat(rows).hasSize(1);
+ Map<String, Object> row = rows.get(0);
+ assertThat(row.get("PROJECT_ID")).isEqualTo(resourceId);
+ assertThat(row.get("COMPONENT_UUID")).isEqualTo(componentUuid);
+ assertThat(row.get("ROOT_PROJECT_ID")).isEqualTo(rootProjectId);
+ assertThat(row.get("ROOT_COMPONENT_UUID")).isEqualTo(rootComponentUuid);
+ }
+
+
+}
--- /dev/null
+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
+);
--- /dev/null
+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,
+ "COMPONENT_UUID" VARCHAR(50),
+ "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,
+ "ROOT_COMPONENT_UUID" VARCHAR(50),
+ "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
+);
+
+CREATE TABLE "DUPLICATIONS_INDEX" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "PROJECT_SNAPSHOT_ID" INTEGER NOT NULL,
+ "SNAPSHOT_ID" INTEGER NOT NULL,
+ "HASH" VARCHAR(50) NOT NULL,
+ "INDEX_IN_FILE" INTEGER NOT NULL,
+ "START_LINE" INTEGER NOT NULL,
+ "END_LINE" INTEGER NOT NULL
+);
+
+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 "CE_ACTIVITY" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "UUID" VARCHAR(40) NOT NULL,
+ "TASK_TYPE" VARCHAR(15) NOT NULL,
+ "COMPONENT_UUID" VARCHAR(40) NULL,
+ "SNAPSHOT_ID" INTEGER NULL,
+ "STATUS" VARCHAR(15) NOT NULL,
+ "IS_LAST" BOOLEAN NOT NULL,
+ "IS_LAST_KEY" VARCHAR(55) NOT NULL,
+ "SUBMITTER_LOGIN" VARCHAR(255) NULL,
+ "SUBMITTED_AT" BIGINT NOT NULL,
+ "STARTED_AT" BIGINT NULL,
+ "EXECUTED_AT" BIGINT NULL,
+ "CREATED_AT" BIGINT NOT NULL,
+ "UPDATED_AT" BIGINT NOT NULL,
+ "EXECUTION_TIME_MS" BIGINT NULL
+);
+
+CREATE TABLE "EVENTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "NAME" VARCHAR(400),
+ "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)
+);
+
--- /dev/null
+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,
+ "COMPONENT_UUID" VARCHAR(50),
+ "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,
+ "ROOT_COMPONENT_UUID" VARCHAR(50),
+ "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
+);
--- /dev/null
+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,
+ "COMPONENT_UUID" VARCHAR(50),
+ "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,
+ "ROOT_COMPONENT_UUID" VARCHAR(50),
+ "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
+);
+
+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(2000),
+ "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(2000),
+ "PERSON_ID" INTEGER,
+ "CREATED_AT" TIMESTAMP,
+ "AUTHORIZATION_UPDATED_AT" BIGINT
+);