]> source.dussan.org Git - sonarqube.git/commitdiff
Add ConvertProfileMeasuresMigrationTest
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Mon, 30 Jun 2014 09:13:13 +0000 (11:13 +0200)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Mon, 30 Jun 2014 09:13:13 +0000 (11:13 +0200)
sonar-server/src/main/java/org/sonar/server/db/migrations/DatabaseMigrations.java
sonar-server/src/main/java/org/sonar/server/db/migrations/v44/ConvertProfileMeasures.java [deleted file]
sonar-server/src/main/java/org/sonar/server/db/migrations/v44/ConvertProfileMeasuresMigration.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/db/migrations/v44/FeedQProfileDatesMigration.java
sonar-server/src/main/java/org/sonar/server/db/migrations/v44/IssueActionPlanKeyMigration.java
sonar-server/src/main/webapp/WEB-INF/db/migrate/550_convert_profile_measures.rb
sonar-server/src/test/java/org/sonar/server/db/migrations/v44/ConvertProfileMeasuresMigrationTest.java [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/db/migrations/v44/ConvertProfileMeasuresMigrationTest/before.xml [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/db/migrations/v44/ConvertProfileMeasuresMigrationTest/schema.sql [new file with mode: 0644]

index bc1e543c2d1313a00d3cf1b668d9cabe607f9803..fc1413fd316b44e47e5e7a83e4a6da8119eedf0f 100644 (file)
@@ -30,7 +30,7 @@ import org.sonar.server.db.migrations.v43.NotResolvedIssuesOnRemovedComponentsMi
 import org.sonar.server.db.migrations.v43.RequirementMeasuresMigration;
 import org.sonar.server.db.migrations.v43.TechnicalDebtMeasuresMigration;
 import org.sonar.server.db.migrations.v44.ChangeLogMigration;
-import org.sonar.server.db.migrations.v44.ConvertProfileMeasures;
+import org.sonar.server.db.migrations.v44.ConvertProfileMeasuresMigration;
 import org.sonar.server.db.migrations.v44.FeedQProfileDatesMigration;
 import org.sonar.server.db.migrations.v44.FeedQProfileKeysMigration;
 import org.sonar.server.db.migrations.v44.IssueActionPlanKeyMigration;
@@ -61,7 +61,7 @@ public interface DatabaseMigrations {
     FeedQProfileKeysMigration.class,
     FeedQProfileDatesMigration.class,
     ChangeLogMigration.class,
-    ConvertProfileMeasures.class
+    ConvertProfileMeasuresMigration.class
   );
 
 }
diff --git a/sonar-server/src/main/java/org/sonar/server/db/migrations/v44/ConvertProfileMeasures.java b/sonar-server/src/main/java/org/sonar/server/db/migrations/v44/ConvertProfileMeasures.java
deleted file mode 100644 (file)
index 8b2f6c3..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.server.db.migrations.v44;
-
-import org.apache.commons.lang.ObjectUtils;
-import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.core.UtcDateUtils;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.migration.v44.Migration44Mapper;
-import org.sonar.core.persistence.migration.v44.ProfileMeasure;
-import org.sonar.core.persistence.migration.v44.QProfileDto44;
-import org.sonar.server.db.DbClient;
-import org.sonar.server.db.migrations.DatabaseMigration;
-
-import java.io.StringWriter;
-import java.util.Date;
-
-/**
- * Feed the new columns RULES_PROFILE.KEE and PARENT_KEE.
- * 
- * @since 4.4
- */
-public class ConvertProfileMeasures implements DatabaseMigration {
-
-  private final DbClient db;
-
-  public ConvertProfileMeasures(DbClient db) {
-    this.db = db;
-  }
-
-  @Override
-  public void execute() {
-    DbSession session = db.openSession(false);
-    try {
-      int i = 0;
-      Migration44Mapper mapper = session.getMapper(Migration44Mapper.class);
-      for (ProfileMeasure profileMeasure : mapper.selectProfileMeasures()) {
-        int version = mapper.selectProfileVersion(profileMeasure.getSnapshotId());
-        QProfileDto44 profile = mapper.selectProfileById(profileMeasure.getProfileId());
-        if (profile != null) {
-          Date date = (Date)ObjectUtils.defaultIfNull(mapper.selectProfileVersionDate(profileMeasure.getProfileId(), version),
-            new Date());
-          // see format of JSON in org.sonar.batch.rule.UsedQProfiles
-          StringWriter writer = new StringWriter();
-          JsonWriter json = JsonWriter.of(writer);
-          json
-            .beginArray()
-            .beginObject()
-            .prop("key", profile.getKee())
-            .prop("language", profile.getLanguage())
-            .prop("name", profile.getName())
-            .prop("rulesUpdatedAt", UtcDateUtils.formatDateTime(date))
-            .endObject()
-            .endArray()
-            .close();
-          mapper.updateProfileMeasure(profileMeasure.getId(), writer.toString());
-          if (i % 100 == 0) {
-            session.commit();
-            i++;
-          }
-        }
-      }
-      session.commit();
-    } finally {
-      session.close();
-    }
-  }
-}
diff --git a/sonar-server/src/main/java/org/sonar/server/db/migrations/v44/ConvertProfileMeasuresMigration.java b/sonar-server/src/main/java/org/sonar/server/db/migrations/v44/ConvertProfileMeasuresMigration.java
new file mode 100644 (file)
index 0000000..79d8212
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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.server.db.migrations.v44;
+
+import org.apache.commons.lang.ObjectUtils;
+import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.core.UtcDateUtils;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.migration.v44.Migration44Mapper;
+import org.sonar.core.persistence.migration.v44.ProfileMeasure;
+import org.sonar.core.persistence.migration.v44.QProfileDto44;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.db.migrations.DatabaseMigration;
+
+import java.io.StringWriter;
+import java.util.Date;
+
+/**
+ * Feed the new columns RULES_PROFILE.KEE and PARENT_KEE.
+ * 
+ * @since 4.4
+ */
+public class ConvertProfileMeasuresMigration implements DatabaseMigration {
+
+  private final DbClient db;
+
+  public ConvertProfileMeasuresMigration(DbClient db) {
+    this.db = db;
+  }
+
+  @Override
+  public void execute() {
+    DbSession session = db.openSession(false);
+    try {
+      int i = 0;
+      Migration44Mapper mapper = session.getMapper(Migration44Mapper.class);
+      for (ProfileMeasure profileMeasure : mapper.selectProfileMeasures()) {
+        int version = mapper.selectProfileVersion(profileMeasure.getSnapshotId());
+        QProfileDto44 profile = mapper.selectProfileById(profileMeasure.getProfileId());
+        if (profile != null) {
+          Date date = (Date)ObjectUtils.defaultIfNull(mapper.selectProfileVersionDate(profileMeasure.getProfileId(), version),
+            new Date());
+          // see format of JSON in org.sonar.batch.rule.UsedQProfiles
+          StringWriter writer = new StringWriter();
+          JsonWriter json = JsonWriter.of(writer);
+          json
+            .beginArray()
+            .beginObject()
+            .prop("key", profile.getKee())
+            .prop("language", profile.getLanguage())
+            .prop("name", profile.getName())
+            .prop("rulesUpdatedAt", UtcDateUtils.formatDateTime(date))
+            .endObject()
+            .endArray()
+            .close();
+          mapper.updateProfileMeasure(profileMeasure.getId(), writer.toString());
+          if (i % 100 == 0) {
+            session.commit();
+            i++;
+          }
+        }
+      }
+      session.commit();
+    } finally {
+      session.close();
+    }
+  }
+}
index 640fbbb7ca956fc2d24176ba2f62277374a525a5..8194061fee4351fbd9a45937ce147ec6ca822eb5 100644 (file)
@@ -43,16 +43,11 @@ public class FeedQProfileDatesMigration implements DatabaseMigration {
   private final DbClient db;
   private final System2 system;
 
-  @VisibleForTesting
-  FeedQProfileDatesMigration(DbClient db, System2 system) {
+  public FeedQProfileDatesMigration(DbClient db, System2 system) {
     this.db = db;
     this.system = system;
   }
 
-  public FeedQProfileDatesMigration(DbClient db) {
-    this(db, System2.INSTANCE);
-  }
-
   @Override
   public void execute() {
     DbSession session = db.openSession(false);
index b085c9ee1195efe084fa9513063edbe765834298..fa015613f033a518aa7afda1d69ed77110f99c17 100644 (file)
@@ -44,12 +44,7 @@ public class IssueActionPlanKeyMigration implements DatabaseMigration {
   private final System2 system2;
   private final Database db;
 
-  public IssueActionPlanKeyMigration(Database database) {
-    this(database, System2.INSTANCE);
-  }
-
-  @VisibleForTesting
-  IssueActionPlanKeyMigration(Database database, System2 system2) {
+  public IssueActionPlanKeyMigration(Database database, System2 system2) {
     this.db = database;
     this.system2 = system2;
   }
index 427a7703a4a3439fe93b9ee1b9327ecca17b244c..a6f357c405b716b530e8d73d9ea2d0fba455cd52 100644 (file)
@@ -28,7 +28,7 @@ class ConvertProfileMeasures < ActiveRecord::Migration
   end
 
   def self.up
-    execute_java_migration('org.sonar.server.db.migrations.v44.ConvertProfileMeasures')
+    execute_java_migration('org.sonar.server.db.migrations.v44.ConvertProfileMeasuresMigration')
 
     Metric.reset_column_information
     metric = Metric.find_by_name('profile')
diff --git a/sonar-server/src/test/java/org/sonar/server/db/migrations/v44/ConvertProfileMeasuresMigrationTest.java b/sonar-server/src/test/java/org/sonar/server/db/migrations/v44/ConvertProfileMeasuresMigrationTest.java
new file mode 100644 (file)
index 0000000..0d78372
--- /dev/null
@@ -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.server.db.migrations.v44;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.core.persistence.TestDatabase;
+import org.sonar.server.db.DbClient;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class ConvertProfileMeasuresMigrationTest {
+
+  @ClassRule
+  public static TestDatabase db = new TestDatabase().schema(ConvertProfileMeasuresMigrationTest.class, "schema.sql");
+
+  ConvertProfileMeasuresMigration migration;
+
+  @Before
+  public void setUp() throws Exception {
+    DbClient dbClient = new DbClient(db.database(), db.myBatis());
+    migration = new ConvertProfileMeasuresMigration(dbClient);
+  }
+
+  @Test
+  public void generate_profiles_measure_as_json() throws Exception {
+    db.prepareDbUnit(getClass(), "before.xml");
+
+    migration.execute();
+
+    Connection connection = db.openConnection();
+    Statement stmt = connection.createStatement();
+    ResultSet rs = stmt.executeQuery("select text_value from project_measures where id=2");
+    try {
+      rs.next();
+      // pb of comparison of timezones..., so using startsWith instead of equals
+      assertThat(rs.getString(1)).startsWith("[{\"key\":\"java-sonar-way\",\"language\":\"java\",\"name\":\"Sonar way\",\"rulesUpdatedAt\":\"2014-01-04T");
+    } finally {
+      rs.close();
+      stmt.close();
+      connection.close();
+    }
+  }
+}
diff --git a/sonar-server/src/test/resources/org/sonar/server/db/migrations/v44/ConvertProfileMeasuresMigrationTest/before.xml b/sonar-server/src/test/resources/org/sonar/server/db/migrations/v44/ConvertProfileMeasuresMigrationTest/before.xml
new file mode 100644 (file)
index 0000000..92cf512
--- /dev/null
@@ -0,0 +1,56 @@
+<dataset>
+  <metrics id="1" name="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]"  domain="[null]" short_name=""
+           enabled="[true]" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="[false]" delete_historical_data="[null]" />
+  <metrics  id="2" name="profile" 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]"/>
+  <metrics  id="3" name="profile_version" VAL_TYPE="INT" 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 snapshot -->
+  <snapshots purge_status="[null]" id="1000" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" build_date="2008-11-01 13:58:00.00" version="[null]" path=""
+             status="P" islast="[false]" 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]" />
+
+  <!-- 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]" />
+
+
+  <!-- last measures : ncloc, profile and profile_version -->
+  <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]"/>
+
+  <project_measures id="2" VALUE="20" text_value="Sonar way" METRIC_ID="2" 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]"/>
+
+  <project_measures id="3" VALUE="3" METRIC_ID="3" 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]"/>
+
+
+  <!-- quality profiles -->
+  <rules_profiles id="20" name="Sonar way" language="java" kee="java-sonar-way" parent_kee="[null]"/>
+  <rules_profiles id="21" name="Other way" language="java" kee="java-other-way" parent_kee="[null]" />
+
+  <!-- quality profile changes -->
+  <active_rule_changes id="1" profile_id="20" profile_version="2" rule_id="1" change_date="2011-11-03 20:20:05.158"
+                       enabled="true" old_severity="[null]" new_severity="1" username="Administrator"/>
+
+  <active_rule_changes id="2" profile_id="20" profile_version="3" rule_id="1" change_date="2011-12-04 10:20:05.158"
+                       enabled="[null]" old_severity="1" new_severity="4" username="asdasads"/>
+
+  <!-- this is the latest change to be used -->
+  <active_rule_changes id="3" profile_id="20" profile_version="3" rule_id="1" change_date="2014-01-04 12:20:05.158"
+                       enabled="[null]" old_severity="[null]" new_severity="[null]" username="Administrator"/>
+
+</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/db/migrations/v44/ConvertProfileMeasuresMigrationTest/schema.sql b/sonar-server/src/test/resources/org/sonar/server/db/migrations/v44/ConvertProfileMeasuresMigrationTest/schema.sql
new file mode 100644 (file)
index 0000000..4736d0c
--- /dev/null
@@ -0,0 +1,108 @@
+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(1000) NOT NULL,
+  "PARENT_KEE" VARCHAR(1000),
+  "RULES_UPDATED_AT" VARCHAR(100),
+  "CREATED_AT" TIMESTAMP,
+  "UPDATED_AT" TIMESTAMP
+);
+
+CREATE TABLE "ACTIVE_RULE_CHANGES" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "USERNAME" VARCHAR(255),
+  "PROFILE_ID" INTEGER NOT NULL,
+  "PROFILE_VERSION" INTEGER NOT NULL,
+  "RULE_ID" INTEGER NOT NULL,
+  "CHANGE_DATE" TIMESTAMP NOT NULL,
+  "ENABLED" BOOLEAN,
+  "OLD_SEVERITY" INTEGER,
+  "NEW_SEVERITY" INTEGER
+);
+
+CREATE TABLE "ACTIVE_RULE_PARAM_CHANGES" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "ACTIVE_RULE_CHANGE_ID" INTEGER NOT NULL,
+  "RULES_PARAMETER_ID" INTEGER NOT NULL,
+  "OLD_VALUE" VARCHAR(4000),
+  "NEW_VALUE" VARCHAR(4000)
+  );
+
+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
+);