From: Simon Brandhof Date: Mon, 23 Jun 2014 22:15:21 +0000 (+0200) Subject: SONAR-5007 add EVENTS.EVENT_DATA to store links on quality profile changes X-Git-Tag: 4.4-RC1~197 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=5470fe5d8afd1f29980312dcd90eaf8ecb873155;p=sonarqube.git SONAR-5007 add EVENTS.EVENT_DATA to store links on quality profile changes --- diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/events.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/events.html.erb index 6cdfe968f91..e1cf3f78383 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/events.html.erb +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/events.html.erb @@ -82,11 +82,19 @@ <% events.each do |event| categ = event.category + profile_data={} + if categ=='Profile' && event.event_data + profile_data=Hash[*(event.event_data.split(';').map { |elt| elt.split('=') }.flatten)] + end %> <%= l(event.event_date.to_date) %> <%= h message('event.category.' + categ, :default => categ) %> - <%= event.name %> + + <%= link_to_if profile_data['key'] && profile_data['from'] && profile_data['to'], event.name, + :controller => 'profiles', :action => 'changelog', :key => profile_data['key'], + :since => profile_data['from'], :to => profile_data['to'] -%> + <% unless event.description.blank? %> diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileEventsDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileEventsDecorator.java index 68aa7d907cd..3774f9f1b5e 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileEventsDecorator.java +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileEventsDecorator.java @@ -19,6 +19,7 @@ */ package org.sonar.batch.rule; +import com.google.common.collect.ImmutableSortedMap; import org.sonar.api.batch.Decorator; import org.sonar.api.batch.DecoratorContext; import org.sonar.api.batch.DependsUpon; @@ -33,6 +34,9 @@ import org.sonar.api.resources.Languages; import org.sonar.api.resources.Project; import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Resource; +import org.sonar.api.utils.KeyValueFormat; +import org.sonar.batch.index.PersistenceManager; +import org.sonar.core.UtcDateUtils; import javax.annotation.CheckForNull; @@ -43,10 +47,12 @@ public class QProfileEventsDecorator implements Decorator { private final TimeMachine timeMachine; private final Languages languages; + private final PersistenceManager persistenceManager; - public QProfileEventsDecorator(TimeMachine timeMachine, Languages languages) { + public QProfileEventsDecorator(TimeMachine timeMachine, Languages languages, PersistenceManager pm) { this.timeMachine = timeMachine; this.languages = languages; + this.persistenceManager = pm; } @DependsUpon @@ -81,31 +87,40 @@ public class QProfileEventsDecorator implements Decorator { QProfile previousProfile = previousProfiles.get(profile.getKey()); if (previousProfile != null) { if (profile.getRulesUpdatedAt().after(previousProfile.getRulesUpdatedAt())) { - markAsUsed(context, profile); + markAsChanged(context, previousProfile, profile); } } else { - markAsUsed(context, profile); + markAsAdded(context, profile); } } // Detect profiles that are not used anymore for (QProfile previousProfile : previousProfiles.values()) { if (!currentProfiles.containsKey(previousProfile.getKey())) { - markAsUnused(context, previousProfile); + markAsRemoved(context, previousProfile); } } } - private void markAsUnused(DecoratorContext context, QProfile profile) { - Language language = languages.get(profile.getLanguage()); - String languageName = language != null ? language.getName() : profile.getLanguage(); - context.createEvent("Stop using " + profile.getName() + " (" + languageName + ")", profile.getName() + " no more used for " + languageName, Event.CATEGORY_PROFILE, null); + private void markAsChanged(DecoratorContext context, QProfile previousProfile, QProfile profile) { + // DecoratorContext does not allow to set event data, so SonarIndex must be used + Event event = new Event(); + event.setName(String.format("Changes in %s", profileLabel(profile))); + event.setCategory(Event.CATEGORY_PROFILE); + String data = KeyValueFormat.format(ImmutableSortedMap.of( + "key", profile.getKey(), + "from", UtcDateUtils.formatDateTime(previousProfile.getRulesUpdatedAt()), + "to", UtcDateUtils.formatDateTime(profile.getRulesUpdatedAt()))); + event.setData(data); + persistenceManager.saveEvent(context.getResource(), event); } - private void markAsUsed(DecoratorContext context, QProfile profile) { - Language language = languages.get(profile.getLanguage()); - String languageName = language != null ? language.getName() : profile.getLanguage(); - context.createEvent("Use " + profile.getName() + " (" + languageName + ")", profile.getName() + " used for " + languageName, Event.CATEGORY_PROFILE, null); + private void markAsRemoved(DecoratorContext context, QProfile profile) { + context.createEvent(String.format("Stop using %s", profileLabel(profile)), null, Event.CATEGORY_PROFILE, null); + } + + private void markAsAdded(DecoratorContext context, QProfile profile) { + context.createEvent(String.format("Use %s", profileLabel(profile)), null, Event.CATEGORY_PROFILE, null); } @CheckForNull @@ -120,6 +135,12 @@ public class QProfileEventsDecorator implements Decorator { return measures.get(0); } + private String profileLabel(QProfile profile) { + Language language = languages.get(profile.getLanguage()); + String languageName = language != null ? language.getName() : profile.getLanguage(); + return String.format("'%s' (%s)", profile.getName(), languageName); + } + @Override public String toString() { return getClass().getSimpleName(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileEventsDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileEventsDecoratorTest.java index c0010d823f0..c1afcb1e2ee 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileEventsDecoratorTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileEventsDecoratorTest.java @@ -38,6 +38,8 @@ */ package org.sonar.batch.rule; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; import org.junit.Test; import org.sonar.api.batch.DecoratorContext; import org.sonar.api.batch.Event; @@ -48,6 +50,8 @@ import org.sonar.api.measures.Measure; import org.sonar.api.resources.Java; import org.sonar.api.resources.Languages; import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.batch.index.PersistenceManager; import java.util.Arrays; import java.util.Date; @@ -58,6 +62,7 @@ import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.same; import static org.mockito.Mockito.*; +import static org.mockito.Mockito.argThat; public class QProfileEventsDecoratorTest { @@ -69,11 +74,14 @@ public class QProfileEventsDecoratorTest { DecoratorContext decoratorContext = mock(DecoratorContext.class); TimeMachine timeMachine = mock(TimeMachine.class); Languages languages = mock(Languages.class); - QProfileEventsDecorator decorator = new QProfileEventsDecorator(timeMachine, languages); + PersistenceManager persistenceManager = mock(PersistenceManager.class); + QProfileEventsDecorator decorator = new QProfileEventsDecorator(timeMachine, languages, persistenceManager); @Test - public void execute_on_all_projects() { + public void basic_tests() { assertThat(decorator.shouldExecuteOnProject(project)).isTrue(); + assertThat(decorator.toString()).isEqualTo("QProfileEventsDecorator"); + assertThat(decorator.dependsUpon()).isNotNull(); } @Test @@ -104,17 +112,26 @@ public class QProfileEventsDecoratorTest { decorator.decorate(project, decoratorContext); - verify(decoratorContext).createEvent( - eq("Use Java One (Java)"), - eq("Java One used for Java"), - same(Event.CATEGORY_PROFILE), any(Date.class)); + verify(persistenceManager).saveEvent(any(Resource.class), argThat(new BaseMatcher() { + @Override + public void describeTo(Description description) { + } + + @Override + public boolean matches(Object item) { + Event event = (Event) item; + return event.getCategory().equals(Event.CATEGORY_PROFILE) && + "Changes in 'Java One' (Java)".equals(event.getName()) && + "from=2014-01-15T12:00:00+0000;key=J1;to=2014-02-20T12:00:00+0000".equals(event.getData()); + } + })); } @Test public void generate_event_if_profile_not_used_anymore() { Measure previousMeasure = new Measure(CoreMetrics.QUALITY_PROFILES, "[" + JAVA_V1_JSON + "]"); // Different profile - Measure newMeasure = new Measure(CoreMetrics.QUALITY_PROFILES, "[" + JAVA_OTHER_JSON + "]"); + Measure newMeasure = new Measure(CoreMetrics.QUALITY_PROFILES, "[" + JAVA_OTHER_JSON + "]"); when(timeMachine.getMeasures(any(TimeMachineQuery.class))) .thenReturn(Arrays.asList(previousMeasure)); @@ -125,8 +142,8 @@ public class QProfileEventsDecoratorTest { decorator.decorate(project, decoratorContext); verify(decoratorContext).createEvent( - eq("Stop using Java One (Java)"), - eq("Java One no more used for Java"), + eq("Stop using 'Java One' (Java)"), + eq((String) null), same(Event.CATEGORY_PROFILE), any(Date.class)); } diff --git a/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByPreviousVersionTest/no-previous-version.xml b/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByPreviousVersionTest/no-previous-version.xml index 08566ee2bf1..eca7da3d444 100644 --- a/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByPreviousVersionTest/no-previous-version.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByPreviousVersionTest/no-previous-version.xml @@ -30,9 +30,13 @@ scope="PRJ" qualifier="TRK" created_at="2008-11-09 13:58:00.00" build_date="2008-11-09 13:58:00.00" version="1.2-SNAPSHOT" path="" status="U" islast="true" depth="0" /> - - - - + + + + - \ No newline at end of file + diff --git a/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByPreviousVersionTest/with-previous-version-deleted.xml b/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByPreviousVersionTest/with-previous-version-deleted.xml index 6c282cf30e3..0612f65e11f 100644 --- a/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByPreviousVersionTest/with-previous-version-deleted.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByPreviousVersionTest/with-previous-version-deleted.xml @@ -30,12 +30,17 @@ scope="PRJ" qualifier="TRK" created_at="2008-11-09 13:58:00.00" build_date="2008-11-09 13:58:00.00" version="1.2-SNAPSHOT" path="" status="U" islast="true" depth="0" /> - - + + - - - + + + - \ No newline at end of file + diff --git a/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByPreviousVersionTest/with-previous-version.xml b/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByPreviousVersionTest/with-previous-version.xml index 077b4eea7f0..a708a476c07 100644 --- a/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByPreviousVersionTest/with-previous-version.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByPreviousVersionTest/with-previous-version.xml @@ -30,11 +30,11 @@ scope="PRJ" qualifier="TRK" created_at="2008-11-09 13:58:00.00" build_date="2008-11-09 13:58:00.00" version="1.2-SNAPSHOT" path="" status="U" islast="true" depth="0" /> - - - - - - + + + + + + - \ No newline at end of file + diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java index bfc0a38e095..c7ff86a5f0c 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java @@ -33,7 +33,7 @@ import java.util.List; */ public class DatabaseVersion implements BatchComponent, ServerComponent { - public static final int LAST_VERSION = 554; + public static final int LAST_VERSION = 555; public static enum Status { UP_TO_DATE, REQUIRES_UPGRADE, REQUIRES_DOWNGRADE, FRESH_INSTALL diff --git a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql index 0acc327fe71..e93794de62f 100644 --- a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql +++ b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql @@ -247,6 +247,7 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('551'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('552'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('553'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('554'); +INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('555'); INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '2011-09-26 22:27:48.0', '2011-09-26 22:27:48.0', null, null); ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2; diff --git a/sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl b/sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl index d9335527a23..a740173f02b 100644 --- a/sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl +++ b/sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl @@ -177,7 +177,8 @@ CREATE TABLE "EVENTS" ( "CATEGORY" VARCHAR(50), "EVENT_DATE" TIMESTAMP, "CREATED_AT" TIMESTAMP, - "DESCRIPTION" VARCHAR(4000) + "DESCRIPTION" VARCHAR(4000), + "EVENT_DATA" VARCHAR(4000) ); CREATE TABLE "QUALITY_GATES" ( diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index e7362ab8fcd..01b31759a94 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -387,7 +387,7 @@ project_links.scm_dev=Developer connection event.category.Version=Version event.category.Alert=Quality Gate -event.category.Profile=Profile +event.category.Profile=Quality Profile event.category.Other=Other diff --git a/sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/should_create_database.xml b/sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/should_create_database.xml index 897c196100f..abae88d3a70 100644 --- a/sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/should_create_database.xml +++ b/sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/should_create_database.xml @@ -22,9 +22,9 @@ - - - + + + diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteResource.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteResource.xml index 2827a85e45f..17cab18f334 100644 --- a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteResource.xml +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteResource.xml @@ -16,7 +16,7 @@ version="[null]" path="[null]"/> + event_date="2008-12-02 13:58:00.00" created_at="[null]" event_data="[null]"/> - \ No newline at end of file + diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteSnapshot-result.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteSnapshot-result.xml index dbbab34b4f9..9987056896c 100644 --- a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteSnapshot-result.xml +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteSnapshot-result.xml @@ -27,7 +27,7 @@ parent_dependency_id="[null]" project_snapshot_id="1" dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="LIB"/> + event_date="2008-12-02 13:58:00.00" created_at="[null]" event_data="[null]"/> diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteSnapshot.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteSnapshot.xml index bfdbc9c5f63..501a124192c 100644 --- a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteSnapshot.xml +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteSnapshot.xml @@ -25,7 +25,7 @@ parent_dependency_id="[null]" project_snapshot_id="1" dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="LIB"/> + event_date="2008-12-02 13:58:00.00" created_at="[null]" event_data="[null]"/> @@ -58,7 +58,7 @@ parent_dependency_id="[null]" project_snapshot_id="5" dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="LIB"/> + event_date="2008-12-02 13:58:00.00" created_at="[null]" event_data="[null]"/> diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldPurgeSnapshot-result.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldPurgeSnapshot-result.xml index 54257ab7f5d..f2ab60752db 100644 --- a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldPurgeSnapshot-result.xml +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldPurgeSnapshot-result.xml @@ -40,7 +40,8 @@ Note that measures, events and reviews are not deleted. + category="VERSION" description="[null]" name="Version 1.0" event_date="2008-12-02 13:58:00.00" created_at="[null]" + event_data="[null]"/> @@ -74,7 +75,8 @@ Note that measures, events and reviews are not deleted. dep_usage="USES" dep_weight="1" from_scope="LIB" to_scope="PRJ"/> + category="VERSION" description="[null]" name="Version 1.0" event_date="2008-12-02 13:58:00.00" created_at="[null]" + event_data="[null]"/> diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldPurgeSnapshot.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldPurgeSnapshot.xml index 4a2123e1412..5b651f5ea32 100644 --- a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldPurgeSnapshot.xml +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldPurgeSnapshot.xml @@ -27,7 +27,8 @@ dep_usage="USES" dep_weight="1" from_scope="LIB" to_scope="PRJ"/> + category="VERSION" description="[null]" name="Version 1.0" event_date="2008-12-02 13:58:00.00" created_at="[null]" + event_data="[null]"/> @@ -63,7 +64,8 @@ dep_usage="USES" dep_weight="1" from_scope="LIB" to_scope="PRJ"/> + category="VERSION" description="[null]" name="Version 1.0" event_date="2008-12-02 13:58:00.00" created_at="[null]" + event_data="[null]"/> diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldSelectPurgeableSnapshots.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldSelectPurgeableSnapshots.xml index 4ea5c8e1726..bd873bcdc57 100644 --- a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldSelectPurgeableSnapshots.xml +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldSelectPurgeableSnapshots.xml @@ -56,6 +56,7 @@ 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="[null]"/> + category="Version" description="[null]" name="Version 1.0" event_date="2008-12-02 13:58:00.00" created_at="[null]" + event_data="[null]"/> - \ No newline at end of file + diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/Event.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/Event.java index 9ca3c52b180..01d17a9fbe8 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/Event.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/Event.java @@ -52,6 +52,9 @@ public class Event extends BaseIdentifiable { @Column(name = "created_at", updatable = true, nullable = true) private Date createdAt; + @Column(name = "event_data", updatable = true, nullable = true) + private String data; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "snapshot_id", updatable = true, nullable = true) private Snapshot snapshot; @@ -160,6 +163,14 @@ public class Event extends BaseIdentifiable { return this; } + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + @Override public String toString() { return new ToStringBuilder(this) @@ -170,8 +181,4 @@ public class Event extends BaseIdentifiable { .append("resource", resourceId) .toString(); } - - public boolean isLinkedToSnapshot() { - return snapshot != null; - } } diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/555_add_event_data_column.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/555_add_event_data_column.rb new file mode 100644 index 00000000000..117b1c5cd42 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/555_add_event_data_column.rb @@ -0,0 +1,30 @@ +# +# 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 4.4 +# +class AddEventDataColumn < ActiveRecord::Migration + + def self.up + add_column :events, :event_data, :string, :null => true, :limit => 4000 + end + +end