<%
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
%>
<tr class="<%= cycle 'even','odd' -%> event cat_<%= categ.parameterize -%>">
<td x="<%= event.event_date -%>"><%= l(event.event_date.to_date) %></td>
<td><%= h message('event.category.' + categ, :default => categ) %></td>
- <td><%= event.name %></td>
+ <td>
+ <%= 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'] -%>
+ </td>
<td>
<% unless event.description.blank? %>
<i class="icon-info" title="<%= h event.description -%>"></i>
*/
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;
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;
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
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
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();
*/
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;
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;
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 {
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
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<Event>() {
+ @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));
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));
}
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" />
- <events id="2" name="Foo" resource_id="1" snapshot_id="1000" category="Other" event_date="2008-11-03 13:58:00.00" created_at="2008-11-03 13:58:00.00" description=""/>
- <events id="4" name="Bar" resource_id="1" snapshot_id="1001" category="Other" event_date="2008-11-05 13:58:00.00" created_at="2008-11-05 13:58:00.00" description=""/>
- <events id="5" name="Uhh" resource_id="1" snapshot_id="1002" category="Other" event_date="2008-11-07 13:58:00.00" created_at="2008-11-07 13:58:00.00" description=""/>
- <events id="6" name="1.2-SNAPSHOT" resource_id="1" snapshot_id="1003" category="Version" event_date="2008-11-09 13:58:00.00" created_at="2008-11-09 13:58:00.00" description=""/>
+ <events id="2" name="Foo" resource_id="1" snapshot_id="1000" category="Other" event_date="2008-11-03 13:58:00.00" created_at="2008-11-03 13:58:00.00" description=""
+ event_data="[null]"/>
+ <events id="4" name="Bar" resource_id="1" snapshot_id="1001" category="Other" event_date="2008-11-05 13:58:00.00" created_at="2008-11-05 13:58:00.00" description=""
+ event_data="[null]"/>
+ <events id="5" name="Uhh" resource_id="1" snapshot_id="1002" category="Other" event_date="2008-11-07 13:58:00.00" created_at="2008-11-07 13:58:00.00" description=""
+ event_data="[null]"/>
+ <events id="6" name="1.2-SNAPSHOT" resource_id="1" snapshot_id="1003" category="Version" event_date="2008-11-09 13:58:00.00" created_at="2008-11-09 13:58:00.00" description=""
+ event_data="[null]"/>
-</dataset>
\ No newline at end of file
+</dataset>
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" />
- <events id="1" name="1.0" resource_id="1" snapshot_id="1000" category="Version" event_date="2008-11-02 13:58:00.00" created_at="2008-11-02 13:58:00.00" description=""/>
- <events id="2" name="Foo" resource_id="1" snapshot_id="1000" category="Other" event_date="2008-11-03 13:58:00.00" created_at="2008-11-03 13:58:00.00" description=""/>
+ <events id="1" name="1.0" resource_id="1" snapshot_id="1000" category="Version" event_date="2008-11-02 13:58:00.00" created_at="2008-11-02 13:58:00.00" description=""
+ event_data="[null]"/>
+ <events id="2" name="Foo" resource_id="1" snapshot_id="1000" category="Other" event_date="2008-11-03 13:58:00.00" created_at="2008-11-03 13:58:00.00" description=""
+ event_data="[null]"/>
<!-- The "1.1" version was deleted from the history : -->
<!-- events id="3" name="1.1" resource_id="1" snapshot_id="1001" category="Version" event_date="2008-11-04 13:58:00.00" created_at="2008-11-04 13:58:00.00" description=""/-->
- <events id="4" name="Bar" resource_id="1" snapshot_id="1001" category="Other" event_date="2008-11-05 13:58:00.00" created_at="2008-11-05 13:58:00.00" description=""/>
- <events id="5" name="Uhh" resource_id="1" snapshot_id="1002" category="Other" event_date="2008-11-07 13:58:00.00" created_at="2008-11-07 13:58:00.00" description=""/>
- <events id="6" name="1.2-SNAPSHOT" resource_id="1" snapshot_id="1003" category="Version" event_date="2008-11-09 13:58:00.00" created_at="2008-11-09 13:58:00.00" description=""/>
+ <events id="4" name="Bar" resource_id="1" snapshot_id="1001" category="Other" event_date="2008-11-05 13:58:00.00" created_at="2008-11-05 13:58:00.00" description=""
+ event_data="[null]"/>
+ <events id="5" name="Uhh" resource_id="1" snapshot_id="1002" category="Other" event_date="2008-11-07 13:58:00.00" created_at="2008-11-07 13:58:00.00" description=""
+ event_data="[null]"/>
+ <events id="6" name="1.2-SNAPSHOT" resource_id="1" snapshot_id="1003" category="Version" event_date="2008-11-09 13:58:00.00" created_at="2008-11-09 13:58:00.00" description=""
+ event_data="[null]"/>
-</dataset>
\ No newline at end of file
+</dataset>
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" />
- <events id="1" name="1.0" resource_id="1" snapshot_id="1000" category="Version" event_date="2008-11-02 13:58:00.00" created_at="2008-11-02 13:58:00.00" description=""/>
- <events id="2" name="Foo" resource_id="1" snapshot_id="1000" category="Other" event_date="2008-11-03 13:58:00.00" created_at="2008-11-03 13:58:00.00" description=""/>
- <events id="3" name="1.1" resource_id="1" snapshot_id="1001" category="Version" event_date="2008-11-04 13:58:00.00" created_at="2008-11-04 13:58:00.00" description=""/>
- <events id="4" name="Bar" resource_id="1" snapshot_id="1001" category="Other" event_date="2008-11-05 13:58:00.00" created_at="2008-11-05 13:58:00.00" description=""/>
- <events id="5" name="Uhh" resource_id="1" snapshot_id="1002" category="Other" event_date="2008-11-07 13:58:00.00" created_at="2008-11-07 13:58:00.00" description=""/>
- <events id="6" name="1.2-SNAPSHOT" resource_id="1" snapshot_id="1003" category="Version" event_date="2008-11-09 13:58:00.00" created_at="2008-11-09 13:58:00.00" description=""/>
+ <events id="1" name="1.0" resource_id="1" snapshot_id="1000" category="Version" event_date="2008-11-02 13:58:00.00" created_at="2008-11-02 13:58:00.00" description="" event_data="[null]"/>
+ <events id="2" name="Foo" resource_id="1" snapshot_id="1000" category="Other" event_date="2008-11-03 13:58:00.00" created_at="2008-11-03 13:58:00.00" description="" event_data="[null]"/>
+ <events id="3" name="1.1" resource_id="1" snapshot_id="1001" category="Version" event_date="2008-11-04 13:58:00.00" created_at="2008-11-04 13:58:00.00" description="" event_data="[null]"/>
+ <events id="4" name="Bar" resource_id="1" snapshot_id="1001" category="Other" event_date="2008-11-05 13:58:00.00" created_at="2008-11-05 13:58:00.00" description="" event_data="[null]"/>
+ <events id="5" name="Uhh" resource_id="1" snapshot_id="1002" category="Other" event_date="2008-11-07 13:58:00.00" created_at="2008-11-07 13:58:00.00" description="" event_data="[null]"/>
+ <events id="6" name="1.2-SNAPSHOT" resource_id="1" snapshot_id="1003" category="Version" event_date="2008-11-09 13:58:00.00" created_at="2008-11-09 13:58:00.00" description="" event_data="[null]"/>
-</dataset>
\ No newline at end of file
+</dataset>
*/
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
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;
"CATEGORY" VARCHAR(50),
"EVENT_DATE" TIMESTAMP,
"CREATED_AT" TIMESTAMP,
- "DESCRIPTION" VARCHAR(4000)
+ "DESCRIPTION" VARCHAR(4000),
+ "EVENT_DATA" VARCHAR(4000)
);
CREATE TABLE "QUALITY_GATES" (
event.category.Version=Version
event.category.Alert=Quality Gate
-event.category.Profile=Profile
+event.category.Profile=Quality Profile
event.category.Other=Other
<project_measures id="1" value="10" metric_id="1" snapshot_id="1000" />
- <events id="1" name="1.0-SNAPSHOT" resource_id="123" />
- <events id="2" name="2.0-SNAPSHOT" resource_id="123" />
- <events id="3" name="1.0-SNAPSHOT" resource_id="456" />
+ <events id="1" name="1.0-SNAPSHOT" resource_id="123" event_data="[null]"/>
+ <events id="2" name="2.0-SNAPSHOT" resource_id="123" event_data="[null]" />
+ <events id="3" name="1.0-SNAPSHOT" resource_id="456" event_data="[null]" />
<users id="1" login="julien" name="Julien" crypted_password="foo" active="1" />
<users id="2" login="simon" name="Simon" active="1" />
version="[null]" path="[null]"/>
<events id="1" name="Version 1.0" resource_id="1" snapshot_id="1" category="VERSION" description="[null]"
- event_date="2008-12-02 13:58:00.00" created_at="[null]"/>
+ event_date="2008-12-02 13:58:00.00" created_at="[null]" event_data="[null]"/>
<issues id="1" kee="ABCDE" component_id="1" status="CLOSED" resolution="[null]" line="200" severity="BLOCKER"
reporter="perceval" assignee="arthur" rule_id="500"
<authors id="1" person_id="1" login="tartanpion" created_at="[null]" updated_at="[null]" />
<authors id="2" person_id="1" login="fanfoue" created_at="[null]" updated_at="[null]" />
-</dataset>
\ No newline at end of file
+</dataset>
parent_dependency_id="[null]" project_snapshot_id="1"
dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="LIB"/>
<events id="1" name="Version 1.0" resource_id="1" snapshot_id="1" category="VERSION" description="[null]"
- event_date="2008-12-02 13:58:00.00" created_at="[null]"/>
+ event_date="2008-12-02 13:58:00.00" created_at="[null]" event_data="[null]"/>
<duplications_index id="1" project_snapshot_id="1" snapshot_id="1" hash="bb" index_in_file="0" start_line="0" end_line="0"/>
<snapshot_data id="1" resource_id="1" snapshot_id="1" snapshot_data="0,10,k" data_type="highlight_syntax" created_at="[null]" updated_at="[null]" />
parent_dependency_id="[null]" project_snapshot_id="1"
dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="LIB"/>
<events id="1" name="Version 1.0" resource_id="1" snapshot_id="1" category="VERSION" description="[null]"
- event_date="2008-12-02 13:58:00.00" created_at="[null]"/>
+ event_date="2008-12-02 13:58:00.00" created_at="[null]" event_data="[null]"/>
<duplications_index id="1" project_snapshot_id="1" snapshot_id="1" hash="bb" index_in_file="0" start_line="0" end_line="0"/>
<snapshot_data id="1" resource_id="1" snapshot_id="1" snapshot_data="0,10,k" data_type="highlight_syntax" created_at="[null]" updated_at="[null]" />
parent_dependency_id="[null]" project_snapshot_id="5"
dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="LIB"/>
<events id="2" name="Version 1.0" resource_id="5" snapshot_id="5" category="VERSION" description="[null]"
- event_date="2008-12-02 13:58:00.00" created_at="[null]"/>
+ event_date="2008-12-02 13:58:00.00" created_at="[null]" event_data="[null]"/>
<duplications_index id="2" project_snapshot_id="5" snapshot_id="5" hash="bb" index_in_file="0" start_line="0" end_line="0"/>
<snapshot_data id="2" resource_id="5" snapshot_id="5" snapshot_data="0,10,k" data_type="highlight_syntax" created_at="[null]" updated_at="[null]" />
<!--dep_usage="USES" dep_weight="1" from_scope="LIB" to_scope="PRJ"/>-->
<events id="1" resource_id="1" snapshot_id="1"
- category="VERSION" description="[null]" name="Version 1.0" event_date="2008-12-02 13:58:00.00" created_at="[null]"/>
+ category="VERSION" description="[null]" name="Version 1.0" event_date="2008-12-02 13:58:00.00" created_at="[null]"
+ event_data="[null]"/>
<!--<duplications_index id="1" project_snapshot_id="1" snapshot_id="1"-->
<!--hash="bb" index_in_file="0" start_line="0" end_line="0"/>-->
dep_usage="USES" dep_weight="1" from_scope="LIB" to_scope="PRJ"/>
<events id="2" resource_id="2" snapshot_id="2"
- category="VERSION" description="[null]" name="Version 1.0" event_date="2008-12-02 13:58:00.00" created_at="[null]"/>
+ category="VERSION" description="[null]" name="Version 1.0" event_date="2008-12-02 13:58:00.00" created_at="[null]"
+ event_data="[null]"/>
<duplications_index id="2" project_snapshot_id="2" snapshot_id="2"
hash="bb" index_in_file="0" start_line="0" end_line="0"/>
dep_usage="USES" dep_weight="1" from_scope="LIB" to_scope="PRJ"/>
<events id="1" resource_id="1" snapshot_id="1"
- category="VERSION" description="[null]" name="Version 1.0" event_date="2008-12-02 13:58:00.00" created_at="[null]"/>
+ category="VERSION" description="[null]" name="Version 1.0" event_date="2008-12-02 13:58:00.00" created_at="[null]"
+ event_data="[null]"/>
<duplications_index id="1" project_snapshot_id="1" snapshot_id="1"
hash="bb" index_in_file="0" start_line="0" end_line="0"/>
dep_usage="USES" dep_weight="1" from_scope="LIB" to_scope="PRJ"/>
<events id="2" resource_id="2" snapshot_id="2"
- category="VERSION" description="[null]" name="Version 1.0" event_date="2008-12-02 13:58:00.00" created_at="[null]"/>
+ category="VERSION" description="[null]" name="Version 1.0" event_date="2008-12-02 13:58:00.00" created_at="[null]"
+ event_data="[null]"/>
<duplications_index id="2" project_snapshot_id="2" snapshot_id="2"
hash="bb" index_in_file="0" start_line="0" end_line="0"/>
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]"/>
<events id="2" resource_id="1" snapshot_id="5"
- category="Version" description="[null]" name="Version 1.0" event_date="2008-12-02 13:58:00.00" created_at="[null]"/>
+ category="Version" description="[null]" name="Version 1.0" event_date="2008-12-02 13:58:00.00" created_at="[null]"
+ event_data="[null]"/>
-</dataset>
\ No newline at end of file
+</dataset>
@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;
return this;
}
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
@Override
public String toString() {
return new ToStringBuilder(this)
.append("resource", resourceId)
.toString();
}
-
- public boolean isLinkedToSnapshot() {
- return snapshot != null;
- }
}
--- /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 4.4
+#
+class AddEventDataColumn < ActiveRecord::Migration
+
+ def self.up
+ add_column :events, :event_data, :string, :null => true, :limit => 4000
+ end
+
+end