@@ -1,8 +1,8 @@ | |||
<% | |||
if @resource.scope=='PRJ' | |||
conditions = "resource_id=:resource_id" | |||
values = {:resource_id => @resource.id} | |||
conditions = "component_uuid=:component_uuid" | |||
values = {:component_uuid => @resource.uuid} | |||
# in order to not display events linked to deleted snapshot, we build the SQL request with 'NOT IN' as most of the time, there won't be unprocessed snapshots | |||
snapshots_to_be_deleted = Snapshot.find(:all, :conditions => ["status='U' AND project_id=?", @resource.id]) | |||
unless snapshots_to_be_deleted.empty? |
@@ -101,7 +101,7 @@ | |||
from_date = first_date if !from_date || from_date > first_date | |||
end | |||
end | |||
Event.find(:all, :conditions => ["resource_id=? AND event_date>=?", @resource.id, from_date.to_i*1000], :order => 'event_date').each() do |event| | |||
Event.find(:all, :conditions => ["component_uuid=? AND event_date>=?", @resource.uuid, from_date.to_i*1000], :order => 'event_date').each() do |event| | |||
if events[event.event_date] | |||
events[event.event_date] << event | |||
else |
@@ -0,0 +1,129 @@ | |||
/* | |||
* 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.computation.step; | |||
import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.batch.protocol.Constants; | |||
import org.sonar.batch.protocol.output.BatchReport; | |||
import org.sonar.batch.protocol.output.BatchReportReader; | |||
import org.sonar.core.event.EventDto; | |||
import org.sonar.core.persistence.DbSession; | |||
import org.sonar.core.persistence.MyBatis; | |||
import org.sonar.server.computation.ComputationContext; | |||
import org.sonar.server.db.DbClient; | |||
import java.util.List; | |||
public class PersistEventsStep implements ComputationStep { | |||
private final DbClient dbClient; | |||
private final System2 system2; | |||
public PersistEventsStep(DbClient dbClient, System2 system2) { | |||
this.dbClient = dbClient; | |||
this.system2 = system2; | |||
} | |||
@Override | |||
public String[] supportedProjectQualifiers() { | |||
return new String[] {Qualifiers.PROJECT}; | |||
} | |||
@Override | |||
public void execute(ComputationContext context) { | |||
DbSession session = dbClient.openSession(false); | |||
try { | |||
int rootComponentRef = context.getReportMetadata().getRootComponentRef(); | |||
recursivelyProcessComponent(session, context, rootComponentRef); | |||
session.commit(); | |||
} finally { | |||
MyBatis.closeQuietly(session); | |||
} | |||
} | |||
private void recursivelyProcessComponent(DbSession session, ComputationContext context, int componentRef) { | |||
BatchReportReader reportReader = context.getReportReader(); | |||
BatchReport.Component component = reportReader.readComponent(componentRef); | |||
processEvents(session, component, context.getReportMetadata().getAnalysisDate()); | |||
createVersionEvent(session, component, context.getReportMetadata().getAnalysisDate()); | |||
for (Integer childRef : component.getChildRefsList()) { | |||
recursivelyProcessComponent(session, context, childRef); | |||
} | |||
} | |||
private void processEvents(DbSession session, BatchReport.Component component, Long analysisDate) { | |||
List<BatchReport.Event> events = component.getEventsList(); | |||
if (!events.isEmpty()) { | |||
for (BatchReport.Event event : component.getEventsList()) { | |||
dbClient.eventDao().insert(session, createBaseEvent(component, analysisDate) | |||
.setName(event.getName()) | |||
.setCategory(convertCategory(event.getCategory())) | |||
.setDescription(event.hasDescription() ? event.getDescription() : null) | |||
.setData(event.hasEventData() ? event.getEventData() : null) | |||
); | |||
} | |||
} | |||
} | |||
private void createVersionEvent(DbSession session, BatchReport.Component component, Long analysisDate) { | |||
if (component.hasVersion()) { | |||
deletePreviousEventsHavingSameVersion(session, component); | |||
dbClient.eventDao().insert(session, createBaseEvent(component, analysisDate) | |||
.setName(component.getVersion()) | |||
.setCategory(EventDto.CATEGORY_VERSION) | |||
); | |||
} | |||
} | |||
private void deletePreviousEventsHavingSameVersion(DbSession session, BatchReport.Component component){ | |||
for (EventDto dto : dbClient.eventDao().selectByComponentUuid(session, component.getUuid())) { | |||
if (dto.getCategory().equals(EventDto.CATEGORY_VERSION) && dto.getName().equals(component.getVersion())) { | |||
dbClient.eventDao().delete(session, dto.getId()); | |||
} | |||
} | |||
} | |||
private EventDto createBaseEvent(BatchReport.Component component, Long analysisDate) { | |||
return new EventDto() | |||
.setComponentUuid(component.getUuid()) | |||
.setSnapshotId(component.getSnapshotId()) | |||
.setCreatedAt(system2.now()) | |||
.setDate(analysisDate); | |||
} | |||
private static String convertCategory(Constants.EventCategory category) { | |||
switch (category) { | |||
case ALERT: | |||
return EventDto.CATEGORY_ALERT; | |||
case PROFILE: | |||
return EventDto.CATEGORY_PROFILE; | |||
default: | |||
throw new IllegalArgumentException(String.format("Unsupported category %s", category.name())); | |||
} | |||
} | |||
@Override | |||
public String getDescription() { | |||
return "Persist component links"; | |||
} | |||
} |
@@ -43,6 +43,7 @@ import org.sonar.server.computation.db.AnalysisReportDao; | |||
import org.sonar.server.dashboard.db.DashboardDao; | |||
import org.sonar.server.dashboard.db.WidgetDao; | |||
import org.sonar.server.dashboard.db.WidgetPropertyDao; | |||
import org.sonar.server.event.db.EventDao; | |||
import org.sonar.server.issue.db.IssueDao; | |||
import org.sonar.server.measure.persistence.MeasureDao; | |||
import org.sonar.server.measure.persistence.MetricDao; | |||
@@ -91,6 +92,7 @@ public class DbClient implements ServerComponent { | |||
private final AuthorDao authorDao; | |||
private final ComponentIndexDao componentIndexDao; | |||
private final ComponentLinkDao componentLinkDao; | |||
private final EventDao eventDao; | |||
public DbClient(Database db, MyBatis myBatis, DaoComponent... daoComponents) { | |||
this.db = db; | |||
@@ -126,6 +128,7 @@ public class DbClient implements ServerComponent { | |||
authorDao = getDao(map, AuthorDao.class); | |||
componentIndexDao = getDao(map, ComponentIndexDao.class); | |||
componentLinkDao = getDao(map, ComponentLinkDao.class); | |||
eventDao = getDao(map, EventDao.class); | |||
} | |||
public Database database() { | |||
@@ -240,6 +243,10 @@ public class DbClient implements ServerComponent { | |||
return componentLinkDao; | |||
} | |||
public EventDao eventDao() { | |||
return eventDao; | |||
} | |||
private <K> K getDao(Map<Class, DaoComponent> map, Class<K> clazz) { | |||
return (K) map.get(clazz); | |||
} |
@@ -31,6 +31,7 @@ import org.sonar.server.db.migrations.v451.AddMissingCustomRuleParametersMigrati | |||
import org.sonar.server.db.migrations.v451.DeleteUnescapedActivities; | |||
import org.sonar.server.db.migrations.v50.*; | |||
import org.sonar.server.db.migrations.v51.*; | |||
import org.sonar.server.db.migrations.v52.FeedEventsComponentUuid; | |||
import org.sonar.server.db.migrations.v52.FeedProjectLinksComponentUuid; | |||
import java.util.List; | |||
@@ -97,6 +98,7 @@ public interface DatabaseMigrations { | |||
RemovePermissionsOnModulesMigration.class, | |||
// 5.2 | |||
FeedProjectLinksComponentUuid.class | |||
FeedProjectLinksComponentUuid.class, | |||
FeedEventsComponentUuid.class | |||
); | |||
} |
@@ -0,0 +1,55 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.db.migrations.v52; | |||
import org.sonar.core.persistence.Database; | |||
import org.sonar.server.db.migrations.BaseDataChange; | |||
import org.sonar.server.db.migrations.MassUpdate; | |||
import org.sonar.server.db.migrations.Select; | |||
import org.sonar.server.db.migrations.SqlStatement; | |||
import java.sql.SQLException; | |||
public class FeedEventsComponentUuid extends BaseDataChange { | |||
public FeedEventsComponentUuid(Database db) { | |||
super(db); | |||
} | |||
@Override | |||
public void execute(Context context) throws SQLException { | |||
MassUpdate update = context.prepareMassUpdate().rowPluralName("events"); | |||
update.select( | |||
"SELECT p.uuid, event.id " + | |||
"FROM events event " + | |||
"INNER JOIN projects p ON p.id=event.resource_id " + | |||
"WHERE event.component_uuid is null"); | |||
update.update("UPDATE events SET component_uuid=? WHERE id=?"); | |||
update.execute(new MassUpdate.Handler() { | |||
@Override | |||
public boolean handle(Select.Row row, SqlStatement update) throws SQLException { | |||
update.setString(1, row.getString(1)); | |||
update.setLong(2, row.getLong(2)); | |||
return true; | |||
} | |||
}); | |||
} | |||
} |
@@ -0,0 +1,45 @@ | |||
/* | |||
* 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.event.db; | |||
import org.sonar.api.ServerComponent; | |||
import org.sonar.core.event.EventDto; | |||
import org.sonar.core.event.db.EventMapper; | |||
import org.sonar.core.persistence.DaoComponent; | |||
import org.sonar.core.persistence.DbSession; | |||
import java.util.List; | |||
public class EventDao implements ServerComponent, DaoComponent { | |||
public List<EventDto> selectByComponentUuid(DbSession session, String componentUuid) { | |||
return session.getMapper(EventMapper.class).selectByComponentUuid(componentUuid); | |||
} | |||
public void insert(DbSession session, EventDto dto) { | |||
session.getMapper(EventMapper.class).insert(dto); | |||
} | |||
public void delete(DbSession session, Long id) { | |||
session.getMapper(EventMapper.class).delete(id); | |||
} | |||
} |
@@ -0,0 +1,24 @@ | |||
/* | |||
* 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. | |||
*/ | |||
@ParametersAreNonnullByDefault | |||
package org.sonar.server.event.db; | |||
import javax.annotation.ParametersAreNonnullByDefault; |
@@ -0,0 +1,193 @@ | |||
/* | |||
* 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.computation.step; | |||
import org.junit.*; | |||
import org.junit.experimental.categories.Category; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.batch.protocol.Constants; | |||
import org.sonar.batch.protocol.output.BatchReport; | |||
import org.sonar.batch.protocol.output.BatchReportReader; | |||
import org.sonar.batch.protocol.output.BatchReportWriter; | |||
import org.sonar.core.component.ComponentDto; | |||
import org.sonar.core.persistence.DbSession; | |||
import org.sonar.core.persistence.DbTester; | |||
import org.sonar.server.computation.ComputationContext; | |||
import org.sonar.server.db.DbClient; | |||
import org.sonar.server.event.db.EventDao; | |||
import org.sonar.test.DbTests; | |||
import java.io.File; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
@Category(DbTests.class) | |||
public class PersistEventsStepTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
@ClassRule | |||
public static DbTester dbTester = new DbTester(); | |||
DbSession session; | |||
EventDao dao; | |||
System2 system2; | |||
PersistEventsStep step; | |||
@Before | |||
public void setup() throws Exception { | |||
session = dbTester.myBatis().openSession(false); | |||
dao = new EventDao(); | |||
DbClient dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), dao); | |||
system2 = mock(System2.class); | |||
when(system2.now()).thenReturn(1225630680000L); | |||
step = new PersistEventsStep(dbClient, system2); | |||
} | |||
@After | |||
public void tearDown() throws Exception { | |||
session.close(); | |||
} | |||
@Test | |||
public void execute_only_on_projects() throws Exception { | |||
assertThat(step.supportedProjectQualifiers()).containsOnly("TRK"); | |||
} | |||
@Test | |||
public void nothing_to_do_when_no_events_in_report() throws Exception { | |||
dbTester.prepareDbUnit(getClass(), "nothing_to_do_when_no_events_in_report.xml"); | |||
File reportDir = temp.newFolder(); | |||
BatchReportWriter writer = new BatchReportWriter(reportDir); | |||
writer.writeMetadata(BatchReport.Metadata.newBuilder() | |||
.setRootComponentRef(1) | |||
.setProjectKey("PROJECT_KEY") | |||
.setAnalysisDate(150000000L) | |||
.build()); | |||
writer.writeComponent(BatchReport.Component.newBuilder() | |||
.setRef(1) | |||
.setType(Constants.ComponentType.PROJECT) | |||
.setUuid("ABCD") | |||
.build()); | |||
step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class))); | |||
dbTester.assertDbUnit(getClass(), "nothing_to_do_when_no_events_in_report.xml", "events"); | |||
} | |||
@Test | |||
public void persist_report_events() throws Exception { | |||
dbTester.prepareDbUnit(getClass(), "empty.xml"); | |||
File reportDir = temp.newFolder(); | |||
BatchReportWriter writer = new BatchReportWriter(reportDir); | |||
writer.writeMetadata(BatchReport.Metadata.newBuilder() | |||
.setRootComponentRef(1) | |||
.setProjectKey("PROJECT_KEY") | |||
.setAnalysisDate(150000000L) | |||
.build()); | |||
writer.writeComponent(BatchReport.Component.newBuilder() | |||
.setRef(1) | |||
.setType(Constants.ComponentType.PROJECT) | |||
.setUuid("ABCD") | |||
.setSnapshotId(1000L) | |||
.addEvents(BatchReport.Event.newBuilder() | |||
.setName("Red (was Orange)") | |||
.setCategory(Constants.EventCategory.ALERT) | |||
.setDescription("Open issues > 0") | |||
.build() | |||
) | |||
.addEvents(BatchReport.Event.newBuilder() | |||
.setName("Changes in 'Default' (Java)") | |||
.setCategory(Constants.EventCategory.PROFILE) | |||
.setEventData("from=2014-10-12T08:36:25+0000;key=java-default;to=2014-10-12T10:36:25+0000") | |||
.build() | |||
) | |||
.build()); | |||
step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class))); | |||
dbTester.assertDbUnit(getClass(), "add_events-result.xml", "events"); | |||
} | |||
@Test | |||
public void create_version_event() throws Exception { | |||
dbTester.prepareDbUnit(getClass(), "empty.xml"); | |||
File reportDir = temp.newFolder(); | |||
BatchReportWriter writer = new BatchReportWriter(reportDir); | |||
writer.writeMetadata(BatchReport.Metadata.newBuilder() | |||
.setRootComponentRef(1) | |||
.setProjectKey("PROJECT_KEY") | |||
.setAnalysisDate(150000000L) | |||
.build()); | |||
writer.writeComponent(BatchReport.Component.newBuilder() | |||
.setRef(1) | |||
.setType(Constants.ComponentType.PROJECT) | |||
.setUuid("ABCD") | |||
.setSnapshotId(1000L) | |||
.setVersion("1.0") | |||
.build()); | |||
step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class))); | |||
dbTester.assertDbUnit(getClass(), "add_version_event-result.xml", "events"); | |||
} | |||
@Test | |||
public void keep_one_event_by_version() throws Exception { | |||
dbTester.prepareDbUnit(getClass(), "keep_one_event_by_version.xml"); | |||
File reportDir = temp.newFolder(); | |||
BatchReportWriter writer = new BatchReportWriter(reportDir); | |||
writer.writeMetadata(BatchReport.Metadata.newBuilder() | |||
.setRootComponentRef(1) | |||
.setProjectKey("PROJECT_KEY") | |||
.setAnalysisDate(150000000L) | |||
.build()); | |||
writer.writeComponent(BatchReport.Component.newBuilder() | |||
.setRef(1) | |||
.setType(Constants.ComponentType.PROJECT) | |||
.setUuid("ABCD") | |||
.setSnapshotId(1001L) | |||
.setVersion("1.5-SNAPSHOT") | |||
.build()); | |||
step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class))); | |||
dbTester.assertDbUnit(getClass(), "keep_one_event_by_version-result.xml", "events"); | |||
} | |||
} |
@@ -0,0 +1,63 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.db.migrations.v52; | |||
import org.junit.Before; | |||
import org.junit.ClassRule; | |||
import org.junit.Test; | |||
import org.sonar.core.persistence.DbTester; | |||
import org.sonar.server.db.migrations.DatabaseMigration; | |||
public class FeedEventsComponentUuidTest { | |||
@ClassRule | |||
public static DbTester db = new DbTester().schema(FeedEventsComponentUuidTest.class, "schema.sql"); | |||
DatabaseMigration migration; | |||
@Before | |||
public void setUp() throws Exception { | |||
db.executeUpdateSql("truncate table events"); | |||
db.executeUpdateSql("truncate table projects"); | |||
migration = new FeedEventsComponentUuid(db.database()); | |||
} | |||
@Test | |||
public void migrate_empty_db() throws Exception { | |||
migration.execute(); | |||
} | |||
@Test | |||
public void migrate() throws Exception { | |||
db.prepareDbUnit(this.getClass(), "migrate.xml"); | |||
migration.execute(); | |||
db.assertDbUnit(this.getClass(), "migrate-result.xml", "events"); | |||
} | |||
@Test | |||
public void not_migrate_already_migrated_data() throws Exception { | |||
db.prepareDbUnit(this.getClass(), "not_migrate_already_migrated_data.xml"); | |||
migration.execute(); | |||
db.assertDbUnit(this.getClass(), "not_migrate_already_migrated_data.xml", "events"); | |||
} | |||
} |
@@ -0,0 +1,117 @@ | |||
/* | |||
* 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.event.db; | |||
import org.junit.After; | |||
import org.junit.Before; | |||
import org.junit.ClassRule; | |||
import org.junit.Test; | |||
import org.junit.experimental.categories.Category; | |||
import org.sonar.core.event.EventDto; | |||
import org.sonar.core.persistence.DbSession; | |||
import org.sonar.core.persistence.DbTester; | |||
import org.sonar.test.DbTests; | |||
import java.util.List; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
@Category(DbTests.class) | |||
public class EventDaoTest { | |||
@ClassRule | |||
public static DbTester dbTester = new DbTester(); | |||
DbSession session; | |||
EventDao dao; | |||
@Before | |||
public void setup() throws Exception { | |||
session = dbTester.myBatis().openSession(false); | |||
dao = new EventDao(); | |||
} | |||
@After | |||
public void tearDown() throws Exception { | |||
session.close(); | |||
} | |||
@Test | |||
public void select_by_component_uuid() throws Exception { | |||
dbTester.prepareDbUnit(getClass(), "shared.xml"); | |||
List<EventDto> dtos = dao.selectByComponentUuid(session, "ABCD"); | |||
assertThat(dtos).hasSize(3); | |||
dtos = dao.selectByComponentUuid(session, "BCDE"); | |||
assertThat(dtos).hasSize(1); | |||
EventDto dto = dtos.get(0); | |||
assertThat(dto.getId()).isEqualTo(4L); | |||
assertThat(dto.getComponentUuid()).isEqualTo("BCDE"); | |||
assertThat(dto.getSnapshotId()).isEqualTo(1000L); | |||
assertThat(dto.getName()).isEqualTo("1.0"); | |||
assertThat(dto.getCategory()).isEqualTo("Version"); | |||
assertThat(dto.getDescription()).isEqualTo("Version 1.0"); | |||
assertThat(dto.getData()).isEqualTo("some data"); | |||
assertThat(dto.getDate()).isEqualTo(1413407091086L); | |||
assertThat(dto.getCreatedAt()).isEqualTo(1225630680000L); | |||
} | |||
@Test | |||
public void return_different_categories() throws Exception { | |||
dbTester.prepareDbUnit(getClass(), "shared.xml"); | |||
List<EventDto> dtos = dao.selectByComponentUuid(session, "ABCD"); | |||
assertThat(dtos).extracting("category").containsOnly(EventDto.CATEGORY_ALERT, EventDto.CATEGORY_PROFILE, EventDto.CATEGORY_VERSION); | |||
} | |||
@Test | |||
public void insert() throws Exception { | |||
dbTester.prepareDbUnit(getClass(), "empty.xml"); | |||
dao.insert(session, new EventDto() | |||
.setName("1.0") | |||
.setCategory(EventDto.CATEGORY_VERSION) | |||
.setDescription("Version 1.0") | |||
.setData("some data") | |||
.setDate(1413407091086L) | |||
.setComponentUuid("ABCD") | |||
.setSnapshotId(1000L) | |||
.setCreatedAt(1225630680000L) | |||
); | |||
session.commit(); | |||
dbTester.assertDbUnit(getClass(), "insert-result.xml", "events"); | |||
} | |||
@Test | |||
public void delete() throws Exception { | |||
dbTester.prepareDbUnit(getClass(), "delete.xml"); | |||
dao.delete(session, 1L); | |||
session.commit(); | |||
assertThat(dbTester.countRowsOfTable("events")).isEqualTo(0); | |||
} | |||
} |
@@ -0,0 +1,10 @@ | |||
<dataset> | |||
<events id="1" name="Red (was Orange)" category="Alert" description="Open issues > 0" | |||
event_data="[null]" | |||
event_date="150000000" component_uuid="ABCD" snapshot_id="1000" created_at="1225630680000" /> | |||
<events id="2" name="Changes in 'Default' (Java)" category="Profile" description="[null]" | |||
event_data="from=2014-10-12T08:36:25+0000;key=java-default;to=2014-10-12T10:36:25+0000" | |||
event_date="150000000" component_uuid="ABCD" snapshot_id="1000" created_at="1225630680000" /> | |||
</dataset> |
@@ -0,0 +1,6 @@ | |||
<dataset> | |||
<events id="1" name="1.0" category="Version" description="[null]" event_data="[null]" event_date="150000000" | |||
component_uuid="ABCD" snapshot_id="1000" created_at="1225630680000" /> | |||
</dataset> |
@@ -0,0 +1,3 @@ | |||
<dataset> | |||
</dataset> |
@@ -0,0 +1,14 @@ | |||
<dataset> | |||
<events id="1" name="1.3-SNAPSHOT" category="Version" description="[null]" event_data="[null]" event_date="120000000" | |||
component_uuid="ABCD" snapshot_id="1000" created_at="120000000" /> | |||
<events id="2" name="1.4" category="Version" description="[null]" event_data="[null]" event_date="130000000" | |||
component_uuid="ABCD" snapshot_id="1000" created_at="130000000" /> | |||
<!-- Has been removed --> | |||
<!--<events id="3" name="1.5-SNAPSHOT" category="Version" description="[null]" event_data="[null]" event_date="140000000"--> | |||
<!--component_uuid="ABCD" snapshot_id="1000" created_at="140000000" />--> | |||
<events id="4" name="1.5-SNAPSHOT" category="Version" description="[null]" event_data="[null]" event_date="150000000" | |||
component_uuid="ABCD" snapshot_id="1001" created_at="1225630680000" /> | |||
</dataset> |
@@ -0,0 +1,10 @@ | |||
<dataset> | |||
<events id="1" name="1.3-SNAPSHOT" category="Version" description="[null]" event_data="[null]" event_date="120000000" | |||
component_uuid="ABCD" snapshot_id="1000" created_at="120000000" /> | |||
<events id="2" name="1.4" category="Version" description="[null]" event_data="[null]" event_date="130000000" | |||
component_uuid="ABCD" snapshot_id="1000" created_at="130000000" /> | |||
<events id="3" name="1.5-SNAPSHOT" category="Version" description="[null]" event_data="[null]" event_date="140000000" | |||
component_uuid="ABCD" snapshot_id="1000" created_at="140000000" /> | |||
</dataset> |
@@ -0,0 +1,13 @@ | |||
<dataset> | |||
<events id="1" name="1.0" category="Version" description="Version 1.0" event_data="some data" event_date="1413407091086" | |||
component_uuid="ABCD" snapshot_id="1000" created_at="1225630680000" /> | |||
<events id="2" name="Red (was Orange)" category="Alert" description="Critical issues variation > 0 since previous version (1.0 - 2015 Feb 09), Open issues > 0" | |||
event_data="[null]" event_date="1413407091086" component_uuid="ABCD" snapshot_id="1000" created_at="1225630680000" /> | |||
<events id="3" name="Changes in 'Default' (Java)" category="Profile" description="Version 1.0" event_data="from=2014-10-12T08:36:25+0000;key=java-default;to=2014-10-12T10:36:25+0000" | |||
event_date="1413407091086" component_uuid="ABCD" snapshot_id="1000" created_at="1225630680000" /> | |||
<events id="4" name="1.0" category="Version" description="Version 1.0" event_data="some data" event_date="1413407091086" | |||
component_uuid="BCDE" snapshot_id="1000" created_at="1225630680000" /> | |||
</dataset> |
@@ -0,0 +1,5 @@ | |||
<dataset> | |||
<events id="1" name="1.0" resource_id="1" component_uuid="ABCD" snapshot_id="1000" category="Version" event_date="1225630680000" created_at="1225630680000" description="" event_data="[null]"/> | |||
</dataset> |
@@ -0,0 +1,11 @@ | |||
<dataset> | |||
<projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" deprecated_kee="org.struts:struts" | |||
uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="" | |||
description="the description" long_name="Apache Struts" | |||
enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" | |||
created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> | |||
<events id="1" name="1.0" resource_id="1" component_uuid="[null]" snapshot_id="1000" category="Version" event_date="1225630680000" created_at="1225630680000" description="" event_data="[null]"/> | |||
</dataset> |
@@ -0,0 +1,11 @@ | |||
<dataset> | |||
<projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" deprecated_kee="org.struts:struts" | |||
uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="" | |||
description="the description" long_name="Apache Struts" | |||
enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" | |||
created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/> | |||
<events id="1" name="1.0" resource_id="1" component_uuid="ABCD" snapshot_id="1000" category="Version" event_date="1225630680000" created_at="1225630680000" description="" event_data="[null]"/> | |||
</dataset> |
@@ -0,0 +1,35 @@ | |||
CREATE TABLE "PROJECTS" ( | |||
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), | |||
"KEE" VARCHAR(400), | |||
"ROOT_ID" INTEGER, | |||
"UUID" VARCHAR(50), | |||
"PROJECT_UUID" VARCHAR(50), | |||
"MODULE_UUID" VARCHAR(50), | |||
"MODULE_UUID_PATH" VARCHAR(4000), | |||
"NAME" VARCHAR(256), | |||
"DESCRIPTION" VARCHAR(2000), | |||
"ENABLED" BOOLEAN NOT NULL DEFAULT TRUE, | |||
"SCOPE" VARCHAR(3), | |||
"QUALIFIER" VARCHAR(10), | |||
"DEPRECATED_KEE" VARCHAR(400), | |||
"PATH" VARCHAR(2000), | |||
"LANGUAGE" VARCHAR(20), | |||
"COPY_RESOURCE_ID" INTEGER, | |||
"LONG_NAME" VARCHAR(256), | |||
"PERSON_ID" INTEGER, | |||
"CREATED_AT" TIMESTAMP, | |||
"AUTHORIZATION_UPDATED_AT" BIGINT | |||
); | |||
CREATE TABLE "EVENTS" ( | |||
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), | |||
"NAME" VARCHAR(400), | |||
"RESOURCE_ID" INTEGER, | |||
"COMPONENT_UUID" VARCHAR(50), | |||
"SNAPSHOT_ID" INTEGER, | |||
"CATEGORY" VARCHAR(50), | |||
"EVENT_DATE" BIGINT NOT NULL, | |||
"CREATED_AT" BIGINT NOT NULL, | |||
"DESCRIPTION" VARCHAR(4000), | |||
"EVENT_DATA" VARCHAR(4000) | |||
); |
@@ -0,0 +1,6 @@ | |||
<dataset> | |||
<events id="1" name="1.0" category="Version" description="Version 1.0" event_data="some data" event_date="1225630680000" | |||
component_uuid="ABCD" snapshot_id="1000" created_at="1225630680000" /> | |||
</dataset> |
@@ -0,0 +1,3 @@ | |||
<dataset> | |||
</dataset> |
@@ -0,0 +1,6 @@ | |||
<dataset> | |||
<events id="1" name="1.0" category="Version" description="Version 1.0" event_data="some data" event_date="1413407091086" | |||
component_uuid="ABCD" snapshot_id="1000" created_at="1225630680000" /> | |||
</dataset> |
@@ -0,0 +1,13 @@ | |||
<dataset> | |||
<events id="1" name="1.0" category="Version" description="Version 1.0" event_data="some data" event_date="1413407091086" | |||
component_uuid="ABCD" snapshot_id="1000" created_at="1225630680000" /> | |||
<events id="2" name="Red (was Orange)" category="Alert" description="Critical issues variation > 0 since previous version (1.0 - 2015 Feb 09), Open issues > 0" | |||
event_data="[null]" event_date="1413407091086" component_uuid="ABCD" snapshot_id="1000" created_at="1225630680000" /> | |||
<events id="3" name="Changes in 'Default' (Java)" category="Profile" description="Version 1.0" event_data="from=2014-10-12T08:36:25+0000;key=java-default;to=2014-10-12T10:36:25+0000" | |||
event_date="1413407091086" component_uuid="ABCD" snapshot_id="1000" created_at="1225630680000" /> | |||
<events id="4" name="1.0" category="Version" description="Version 1.0" event_data="some data" event_date="1413407091086" | |||
component_uuid="BCDE" snapshot_id="1000" created_at="1225630680000" /> | |||
</dataset> |
@@ -37,10 +37,10 @@ class Api::EventsController < Api::ApiController | |||
end | |||
if @resource | |||
conditions<<'resource_id=:rid' | |||
values[:rid]=@resource.id | |||
conditions<<'component_uuid=:component_uuid' | |||
values[:component_uuid]=@resource.uuid | |||
else | |||
conditions<<'resource_id IS NULL' | |||
conditions<<'component_uuid IS NULL' | |||
end | |||
from=nil | |||
@@ -87,7 +87,7 @@ class Api::EventsController < Api::ApiController | |||
def show | |||
begin | |||
event=Event.find(params[:id]) | |||
load_resource(:user, event.resource_id) | |||
load_resource_by_uuid(:user, event.component_uuid) | |||
respond_to do |format| | |||
format.json { render :json => jsonp(events_to_json([event])) } | |||
@@ -144,7 +144,7 @@ class Api::EventsController < Api::ApiController | |||
name = params[:name] | |||
desc = params[:description] | |||
category = params[:category] | |||
snapshots = Snapshot.find(:all, :include => 'events', :conditions => ["(root_snapshot_id = ? OR id = ?) AND scope = 'PRJ'", root_snapshot.id, root_snapshot.id]) | |||
snapshots = Snapshot.find(:all, :include => ['events', 'project'], :conditions => ["(root_snapshot_id = ? OR id = ?) AND scope = 'PRJ'", root_snapshot.id, root_snapshot.id]) | |||
snapshots.each do |snapshot| | |||
# if this is a 'Version' event, must propagate the version number to the snapshot | |||
if category==EventCategory::KEY_VERSION | |||
@@ -157,7 +157,7 @@ class Api::EventsController < Api::ApiController | |||
:description => desc, | |||
:category => category, | |||
:snapshot => snapshot, | |||
:resource_id => snapshot.project_id, | |||
:component_uuid => snapshot.project.uuid, | |||
:event_date => snapshot.created_at | |||
) | |||
event.save! | |||
@@ -185,7 +185,7 @@ class Api::EventsController < Api::ApiController | |||
def destroy | |||
begin | |||
event=Event.find(params[:id]) | |||
load_resource(:admin, event.resource_id) | |||
load_resource_by_uuid(:admin, event.component_uuid) | |||
events = [] | |||
name = event.name | |||
@@ -238,6 +238,24 @@ class Api::EventsController < Api::ApiController | |||
end | |||
end | |||
def load_resource_by_uuid(required_resource_role, component_uuid=nil) | |||
if component_uuid | |||
@resource=Project.first(:conditions => {:uuid => component_uuid}) | |||
if @resource.nil? | |||
raise ApiException.new 404, "Component uuid not found: #{component_uuid}" | |||
end | |||
unless has_role?(required_resource_role, @resource) | |||
raise ApiException.new 401, "Unauthorized" | |||
end | |||
else | |||
# global events | |||
unless is_admin? | |||
raise ApiException.new 401, "Unauthorized" | |||
end | |||
end | |||
end | |||
def events_to_json(events=[]) | |||
json=[] | |||
events.each do |event| |
@@ -283,7 +283,7 @@ class ProjectController < ApplicationController | |||
end | |||
def update_version | |||
snapshot=Snapshot.find(params[:sid]) | |||
snapshot=Snapshot.find(params[:sid], :include => 'project') | |||
not_found("Snapshot not found") unless snapshot | |||
access_denied unless is_admin?(snapshot) | |||
@@ -307,7 +307,7 @@ class ProjectController < ApplicationController | |||
# We create an event for every concerned snapshot | |||
snapshots.each do |snapshot| | |||
event = Event.create!(:name => params[:version_name], :snapshot => snapshot, | |||
:resource_id => snapshot.project_id, :category => EventCategory::KEY_VERSION, | |||
:component_uuid => snapshot.project.uuid, :category => EventCategory::KEY_VERSION, | |||
:event_date => snapshot.created_at) | |||
end | |||
flash[:notice] = message('project_history.version_created', :params => params[:version_name]) | |||
@@ -359,7 +359,7 @@ class ProjectController < ApplicationController | |||
e = Event.new({:name => params[:event_name], | |||
:category => EventCategory::KEY_OTHER, | |||
:snapshot => s, | |||
:resource_id => s.project_id, | |||
:component_uuid => s.project.uuid, | |||
:event_date => s.created_at}) | |||
e.save! | |||
end | |||
@@ -385,7 +385,7 @@ class ProjectController < ApplicationController | |||
flash[:notice] = message('project_history.event_updated') | |||
end | |||
redirect_to :action => 'history', :id => event.resource_id | |||
redirect_to :action => 'history', :id => event.resource.id | |||
end | |||
def delete_event | |||
@@ -394,7 +394,7 @@ class ProjectController < ApplicationController | |||
access_denied unless is_admin?(event.resource) | |||
name = event.name | |||
resource_id = event.resource_id | |||
resource_id = event.resource.id | |||
events = find_events(event) | |||
Event.transaction do | |||
events.map { |e| e.id }.each_slice(999) do |safe_for_oracle_ids| | |||
@@ -416,7 +416,7 @@ class ProjectController < ApplicationController | |||
end | |||
def find_project_snapshots(root_snapshot_id) | |||
snapshots = Snapshot.find(:all, :include => 'events', :conditions => ["(root_snapshot_id = ? OR id = ?) AND scope = 'PRJ'", root_snapshot_id, root_snapshot_id]) | |||
Snapshot.find(:all, :include => ['events', 'project'], :conditions => ["(root_snapshot_id = ? OR id = ?) AND scope = 'PRJ'", root_snapshot_id, root_snapshot_id]) | |||
end | |||
# Returns all an array that contains the given event + all the events that are the same, but which are attached on the submodules |
@@ -23,7 +23,7 @@ class Event < ActiveRecord::Base | |||
validates_length_of :name, :within => 1..400 | |||
validates_length_of :category, :within => 1..50 | |||
belongs_to :resource, :class_name => 'Project', :foreign_key => 'resource_id' | |||
belongs_to :resource, :class_name => 'Project', :foreign_key => 'component_uuid', :primary_key => 'uuid' | |||
belongs_to :snapshot | |||
before_save :populate_snapshot |
@@ -23,7 +23,7 @@ class Project < ActiveRecord::Base | |||
has_many :snapshots | |||
has_many :processed_snapshots, :class_name => 'Snapshot', :conditions => "status='#{Snapshot::STATUS_PROCESSED}' AND qualifier<>'LIB'", :order => 'created_at asc' | |||
has_many :events, :foreign_key => 'resource_id', :order => 'event_date DESC' | |||
has_many :events, :foreign_key => 'component_uuid', :primary_key => 'uuid', :order => 'event_date DESC' | |||
has_many :project_links, :foreign_key => 'component_uuid', :primary_key => 'uuid', :dependent => :delete_all, :order => 'link_type' | |||
has_many :user_roles, :foreign_key => 'resource_id' | |||
has_many :group_roles, :foreign_key => 'resource_id' |
@@ -0,0 +1,32 @@ | |||
# | |||
# SonarQube, open source software quality management tool. | |||
# Copyright (C) 2008-2014 SonarSource | |||
# mailto:contact AT sonarsource DOT com | |||
# | |||
# SonarQube is free software; you can redistribute it and/or | |||
# modify it under the terms of the GNU Lesser General Public | |||
# License as published by the Free Software Foundation; either | |||
# version 3 of the License, or (at your option) any later version. | |||
# | |||
# SonarQube is distributed in the hope that it will be useful, | |||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
# Lesser General Public License for more details. | |||
# | |||
# You should have received a copy of the GNU Lesser General Public License | |||
# along with this program; if not, write to the Free Software Foundation, | |||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
# | |||
# | |||
# SonarQube 5.2 | |||
# SONAR-6261 | |||
# | |||
class AddEventsComponentUuid < ActiveRecord::Migration | |||
def self.up | |||
add_column 'events', 'component_uuid', :string, :limit => 50 | |||
add_index 'events', 'component_uuid', :name => 'events_component_uuid' | |||
end | |||
end |
@@ -0,0 +1,31 @@ | |||
# | |||
# 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 5.2 | |||
# SONAR-6261 | |||
# | |||
class FeedEventsComponentUuid < ActiveRecord::Migration | |||
def self.up | |||
execute_java_migration('org.sonar.server.db.migrations.v52.FeedEventsComponentUuid') | |||
end | |||
end |
@@ -0,0 +1,32 @@ | |||
# | |||
# SonarQube, open source software quality management tool. | |||
# Copyright (C) 2008-2014 SonarSource | |||
# mailto:contact AT sonarsource DOT com | |||
# | |||
# SonarQube is free software; you can redistribute it and/or | |||
# modify it under the terms of the GNU Lesser General Public | |||
# License as published by the Free Software Foundation; either | |||
# version 3 of the License, or (at your option) any later version. | |||
# | |||
# SonarQube is distributed in the hope that it will be useful, | |||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
# Lesser General Public License for more details. | |||
# | |||
# You should have received a copy of the GNU Lesser General Public License | |||
# along with this program; if not, write to the Free Software Foundation, | |||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
# | |||
# | |||
# SonarQube 5.2 | |||
# SONAR-6261 | |||
# | |||
class RemoveEventsResourceId < ActiveRecord::Migration | |||
def self.up | |||
remove_index 'events', :name => 'events_resource_id' | |||
remove_column 'events', 'resource_id' | |||
end | |||
end |
@@ -235,6 +235,92 @@ public final class Constants { | |||
// @@protoc_insertion_point(enum_scope:ComponentType) | |||
} | |||
/** | |||
* Protobuf enum {@code EventCategory} | |||
* | |||
* <pre> | |||
* temporary enum during development of computation stack | |||
* </pre> | |||
*/ | |||
public enum EventCategory | |||
implements com.google.protobuf.ProtocolMessageEnum { | |||
/** | |||
* <code>ALERT = 0;</code> | |||
*/ | |||
ALERT(0, 0), | |||
/** | |||
* <code>PROFILE = 1;</code> | |||
*/ | |||
PROFILE(1, 1), | |||
; | |||
/** | |||
* <code>ALERT = 0;</code> | |||
*/ | |||
public static final int ALERT_VALUE = 0; | |||
/** | |||
* <code>PROFILE = 1;</code> | |||
*/ | |||
public static final int PROFILE_VALUE = 1; | |||
public final int getNumber() { return value; } | |||
public static EventCategory valueOf(int value) { | |||
switch (value) { | |||
case 0: return ALERT; | |||
case 1: return PROFILE; | |||
default: return null; | |||
} | |||
} | |||
public static com.google.protobuf.Internal.EnumLiteMap<EventCategory> | |||
internalGetValueMap() { | |||
return internalValueMap; | |||
} | |||
private static com.google.protobuf.Internal.EnumLiteMap<EventCategory> | |||
internalValueMap = | |||
new com.google.protobuf.Internal.EnumLiteMap<EventCategory>() { | |||
public EventCategory findValueByNumber(int number) { | |||
return EventCategory.valueOf(number); | |||
} | |||
}; | |||
public final com.google.protobuf.Descriptors.EnumValueDescriptor | |||
getValueDescriptor() { | |||
return getDescriptor().getValues().get(index); | |||
} | |||
public final com.google.protobuf.Descriptors.EnumDescriptor | |||
getDescriptorForType() { | |||
return getDescriptor(); | |||
} | |||
public static final com.google.protobuf.Descriptors.EnumDescriptor | |||
getDescriptor() { | |||
return org.sonar.batch.protocol.Constants.getDescriptor().getEnumTypes().get(2); | |||
} | |||
private static final EventCategory[] VALUES = values(); | |||
public static EventCategory valueOf( | |||
com.google.protobuf.Descriptors.EnumValueDescriptor desc) { | |||
if (desc.getType() != getDescriptor()) { | |||
throw new java.lang.IllegalArgumentException( | |||
"EnumValueDescriptor is not for this type."); | |||
} | |||
return VALUES[desc.getIndex()]; | |||
} | |||
private final int index; | |||
private final int value; | |||
private EventCategory(int index, int value) { | |||
this.index = index; | |||
this.value = value; | |||
} | |||
// @@protoc_insertion_point(enum_scope:EventCategory) | |||
} | |||
/** | |||
* Protobuf enum {@code ComponentLinkType} | |||
*/ | |||
@@ -319,7 +405,7 @@ public final class Constants { | |||
} | |||
public static final com.google.protobuf.Descriptors.EnumDescriptor | |||
getDescriptor() { | |||
return org.sonar.batch.protocol.Constants.getDescriptor().getEnumTypes().get(2); | |||
return org.sonar.batch.protocol.Constants.getDescriptor().getEnumTypes().get(3); | |||
} | |||
private static final ComponentLinkType[] VALUES = values(); | |||
@@ -357,9 +443,11 @@ public final class Constants { | |||
"\t\n\005MINOR\020\001\022\t\n\005MAJOR\020\002\022\014\n\010CRITICAL\020\003\022\013\n\007B" + | |||
"LOCKER\020\004*X\n\rComponentType\022\013\n\007PROJECT\020\000\022\n" + | |||
"\n\006MODULE\020\001\022\r\n\tDIRECTORY\020\002\022\010\n\004FILE\020\003\022\010\n\004V" + | |||
"IEW\020\004\022\013\n\007SUBVIEW\020\005*F\n\021ComponentLinkType\022" + | |||
"\010\n\004HOME\020\000\022\007\n\003SCM\020\001\022\013\n\007SCM_DEV\020\002\022\t\n\005ISSUE" + | |||
"\020\003\022\006\n\002CI\020\004B\034\n\030org.sonar.batch.protocolH\001" | |||
"IEW\020\004\022\013\n\007SUBVIEW\020\005*\'\n\rEventCategory\022\t\n\005A" + | |||
"LERT\020\000\022\013\n\007PROFILE\020\001*F\n\021ComponentLinkType" + | |||
"\022\010\n\004HOME\020\000\022\007\n\003SCM\020\001\022\013\n\007SCM_DEV\020\002\022\t\n\005ISSU" + | |||
"E\020\003\022\006\n\002CI\020\004B\034\n\030org.sonar.batch.protocolH" + | |||
"\001" | |||
}; | |||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = | |||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { |
@@ -53,6 +53,15 @@ message ComponentLink { | |||
optional string href = 2; | |||
} | |||
// temporary message during development of computation stack | |||
message Event { | |||
optional int32 component_ref = 1; | |||
optional string name = 2; | |||
optional string description = 3; | |||
optional EventCategory category = 4; | |||
optional string event_data = 5; | |||
} | |||
message Component { | |||
optional int32 ref = 1; | |||
optional string path = 2; | |||
@@ -62,10 +71,13 @@ message Component { | |||
optional string language = 6; | |||
repeated int32 child_ref = 7 [packed=true]; | |||
repeated ComponentLink link = 10; | |||
// Only available on PROJECT and MODULE type | |||
optional string version = 12; | |||
// temporary fields during development of computation stack | |||
optional int32 snapshot_id = 8; | |||
optional int64 snapshot_id = 8; | |||
optional string uuid = 9; | |||
repeated Event events = 11; | |||
} | |||
message Issue { |
@@ -38,6 +38,12 @@ enum ComponentType { | |||
SUBVIEW = 5; | |||
} | |||
// temporary enum during development of computation stack | |||
enum EventCategory { | |||
ALERT = 0; | |||
PROFILE = 1; | |||
} | |||
enum ComponentLinkType { | |||
HOME = 0; | |||
SCM = 1; |
@@ -19,13 +19,12 @@ | |||
*/ | |||
package org.sonar.batch.deprecated.components; | |||
import org.sonar.batch.components.PastSnapshot; | |||
import org.sonar.api.BatchExtension; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.batch.Event; | |||
import org.sonar.api.database.DatabaseSession; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.batch.components.PastSnapshot; | |||
import java.util.List; | |||
@@ -43,8 +42,8 @@ public class PastSnapshotFinderByPreviousVersion implements BatchExtension { | |||
String currentVersion = projectSnapshot.getVersion(); | |||
Integer resourceId = projectSnapshot.getResourceId(); | |||
String hql = "from " + Event.class.getSimpleName() + | |||
" where name<>:version AND category='Version' AND resourceId=:resourceId ORDER BY date DESC"; | |||
String hql = "select e from " + Event.class.getSimpleName() + " e " + | |||
" join e.resource component where e.name<>:version AND e.category='Version' AND component.id=:resourceId ORDER BY e.date DESC"; | |||
List<Event> events = session.createQuery(hql) | |||
.setParameter("version", currentVersion) |
@@ -41,7 +41,7 @@ public class EventPersister { | |||
} | |||
public List<Event> getEvents(Resource resource) { | |||
return session.getResults(Event.class, "resourceId", resource.getId()); | |||
return session.getResults(Event.class, "componentUuid", resource.getUuid()); | |||
} | |||
public void deleteEvent(Event event) { | |||
@@ -56,8 +56,9 @@ public class EventPersister { | |||
event.setCreatedAt(new Date(system2.now())); | |||
if (event.getDate() == null) { | |||
event.setSnapshot(batchResource.snapshot()); | |||
event.setComponentUuid(batchResource.resource().getUuid()); | |||
} else { | |||
event.setResourceId(batchResource.resource().getId()); | |||
event.setComponentUuid(batchResource.resource().getUuid()); | |||
} | |||
session.save(event); |
@@ -1,7 +1,7 @@ | |||
<dataset> | |||
<projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project" | |||
root_id="[null]" | |||
root_id="[null]" uuid="ABCD" | |||
description="[null]" | |||
enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/> | |||
@@ -30,13 +30,13 @@ | |||
scope="PRJ" qualifier="TRK" created_at="1226235480000" build_date="1226235480000" 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="1225717080000" created_at="1225717080000" description="" | |||
<events id="2" name="Foo" component_uuid="ABCD" snapshot_id="1000" category="Other" event_date="1225717080000" created_at="1225717080000" description="" | |||
event_data="[null]"/> | |||
<events id="4" name="Bar" resource_id="1" snapshot_id="1001" category="Other" event_date="1225889880000" created_at="1225889880000" description="" | |||
<events id="4" name="Bar" component_uuid="ABCD" snapshot_id="1001" category="Other" event_date="1225889880000" created_at="1225889880000" description="" | |||
event_data="[null]"/> | |||
<events id="5" name="Uhh" resource_id="1" snapshot_id="1002" category="Other" event_date="1226062680000" created_at="1226062680000" description="" | |||
<events id="5" name="Uhh" component_uuid="ABCD" snapshot_id="1002" category="Other" event_date="1226062680000" created_at="1226062680000" description="" | |||
event_data="[null]"/> | |||
<events id="6" name="1.2-SNAPSHOT" resource_id="1" snapshot_id="1003" category="Version" event_date="1226235480000" created_at="1226235480000" description="" | |||
<events id="6" name="1.2-SNAPSHOT" component_uuid="ABCD" snapshot_id="1003" category="Version" event_date="1226235480000" created_at="1226235480000" description="" | |||
event_data="[null]"/> | |||
</dataset> |
@@ -1,7 +1,7 @@ | |||
<dataset> | |||
<projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project" | |||
root_id="[null]" | |||
root_id="[null]" uuid="ABCD" | |||
description="[null]" | |||
enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/> | |||
@@ -30,17 +30,17 @@ | |||
scope="PRJ" qualifier="TRK" created_at="1226235480000" build_date="1226235480000" 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="1225630680000" created_at="1225630680000" description="" | |||
<events id="1" name="1.0" component_uuid="ABCD" snapshot_id="1000" category="Version" event_date="1225630680000" created_at="1225630680000" description="" | |||
event_data="[null]"/> | |||
<events id="2" name="Foo" resource_id="1" snapshot_id="1000" category="Other" event_date="1225717080000" created_at="1225717080000" description="" | |||
<events id="2" name="Foo" component_uuid="ABCD" snapshot_id="1000" category="Other" event_date="1225717080000" created_at="1225717080000" 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="1225889880000" created_at="1225889880000" description="" | |||
<!-- events id="3" name="1.1" component_uuid="ABCD" 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" component_uuid="ABCD" snapshot_id="1001" category="Other" event_date="1225889880000" created_at="1225889880000" description="" | |||
event_data="[null]"/> | |||
<events id="5" name="Uhh" resource_id="1" snapshot_id="1002" category="Other" event_date="1226062680000" created_at="1226062680000" description="" | |||
<events id="5" name="Uhh" component_uuid="ABCD" snapshot_id="1002" category="Other" event_date="1226062680000" created_at="1226062680000" description="" | |||
event_data="[null]"/> | |||
<events id="6" name="1.2-SNAPSHOT" resource_id="1" snapshot_id="1003" category="Version" event_date="1226235480000" created_at="1226235480000" description="" | |||
<events id="6" name="1.2-SNAPSHOT" component_uuid="ABCD" snapshot_id="1003" category="Version" event_date="1226235480000" created_at="1226235480000" description="" | |||
event_data="[null]"/> | |||
</dataset> |
@@ -1,7 +1,7 @@ | |||
<dataset> | |||
<projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project" | |||
root_id="[null]" | |||
root_id="[null]" uuid="ABCD" | |||
description="[null]" | |||
enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/> | |||
@@ -30,11 +30,11 @@ | |||
scope="PRJ" qualifier="TRK" created_at="1226235480000" build_date="1226235480000" 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="1225630680000" created_at="1225630680000" description="" event_data="[null]"/> | |||
<events id="2" name="Foo" resource_id="1" snapshot_id="1000" category="Other" event_date="1225717080000" created_at="1225717080000" description="" event_data="[null]"/> | |||
<events id="3" name="1.1" resource_id="1" snapshot_id="1001" category="Version" event_date="1225803480000" created_at="1225803480000" description="" event_data="[null]"/> | |||
<events id="4" name="Bar" resource_id="1" snapshot_id="1001" category="Other" event_date="1225889880000" created_at="1225889880000" description="" event_data="[null]"/> | |||
<events id="5" name="Uhh" resource_id="1" snapshot_id="1002" category="Other" event_date="1226062680000" created_at="1226062680000" description="" event_data="[null]"/> | |||
<events id="6" name="1.2-SNAPSHOT" resource_id="1" snapshot_id="1003" category="Version" event_date="1226235480000" created_at="1226235480000" description="" event_data="[null]"/> | |||
<events id="1" name="1.0" component_uuid="ABCD" snapshot_id="1000" category="Version" event_date="1225630680000" created_at="1225630680000" description="" event_data="[null]"/> | |||
<events id="2" name="Foo" component_uuid="ABCD" snapshot_id="1000" category="Other" event_date="1225717080000" created_at="1225717080000" description="" event_data="[null]"/> | |||
<events id="3" name="1.1" component_uuid="ABCD" snapshot_id="1001" category="Version" event_date="1225803480000" created_at="1225803480000" description="" event_data="[null]"/> | |||
<events id="4" name="Bar" component_uuid="ABCD" snapshot_id="1001" category="Other" event_date="1225889880000" created_at="1225889880000" description="" event_data="[null]"/> | |||
<events id="5" name="Uhh" component_uuid="ABCD" snapshot_id="1002" category="Other" event_date="1226062680000" created_at="1226062680000" description="" event_data="[null]"/> | |||
<events id="6" name="1.2-SNAPSHOT" component_uuid="ABCD" snapshot_id="1003" category="Version" event_date="1226235480000" created_at="1226235480000" description="" event_data="[null]"/> | |||
</dataset> |
@@ -0,0 +1,132 @@ | |||
/* | |||
* 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.core.event; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
public class EventDto { | |||
public static final String CATEGORY_VERSION = "Version"; | |||
public static final String CATEGORY_ALERT = "Alert"; | |||
public static final String CATEGORY_PROFILE = "Profile"; | |||
private Long id; | |||
private String name; | |||
private String description; | |||
private String category; | |||
private Long date; | |||
private Long createdAt; | |||
private String data; | |||
private Long snapshotId; | |||
private String componentUuid; | |||
public Long getId() { | |||
return id; | |||
} | |||
public EventDto setId(Long id) { | |||
this.id = id; | |||
return this; | |||
} | |||
public String getCategory() { | |||
return category; | |||
} | |||
public EventDto setCategory(String category) { | |||
this.category = category; | |||
return this; | |||
} | |||
public String getComponentUuid() { | |||
return componentUuid; | |||
} | |||
public EventDto setComponentUuid(String componentUuid) { | |||
this.componentUuid = componentUuid; | |||
return this; | |||
} | |||
public Long getCreatedAt() { | |||
return createdAt; | |||
} | |||
public EventDto setCreatedAt(Long createdAt) { | |||
this.createdAt = createdAt; | |||
return this; | |||
} | |||
@CheckForNull | |||
public String getData() { | |||
return data; | |||
} | |||
public EventDto setData(@Nullable String data) { | |||
this.data = data; | |||
return this; | |||
} | |||
public Long getDate() { | |||
return date; | |||
} | |||
public EventDto setDate(Long date) { | |||
this.date = date; | |||
return this; | |||
} | |||
@CheckForNull | |||
public String getDescription() { | |||
return description; | |||
} | |||
public EventDto setDescription(@Nullable String description) { | |||
this.description = description; | |||
return this; | |||
} | |||
public String getName() { | |||
return name; | |||
} | |||
public EventDto setName(String name) { | |||
this.name = name; | |||
return this; | |||
} | |||
public Long getSnapshotId() { | |||
return snapshotId; | |||
} | |||
public EventDto setSnapshotId(Long snapshotId) { | |||
this.snapshotId = snapshotId; | |||
return this; | |||
} | |||
} |
@@ -0,0 +1,35 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.core.event.db; | |||
import org.sonar.core.event.EventDto; | |||
import java.util.List; | |||
public interface EventMapper { | |||
List<EventDto> selectByComponentUuid(String uuid); | |||
void insert(EventDto dto); | |||
void delete(long id); | |||
} |
@@ -0,0 +1,24 @@ | |||
/* | |||
* 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. | |||
*/ | |||
@ParametersAreNonnullByDefault | |||
package org.sonar.core.event.db; | |||
import javax.annotation.ParametersAreNonnullByDefault; |
@@ -0,0 +1,24 @@ | |||
/* | |||
* 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. | |||
*/ | |||
@ParametersAreNonnullByDefault | |||
package org.sonar.core.event; | |||
import javax.annotation.ParametersAreNonnullByDefault; |
@@ -33,7 +33,7 @@ import java.util.List; | |||
*/ | |||
public class DatabaseVersion implements BatchComponent, ServerComponent { | |||
public static final int LAST_VERSION = 902; | |||
public static final int LAST_VERSION = 905; | |||
/** | |||
* List of all the tables.n |
@@ -50,6 +50,8 @@ import org.sonar.core.dependency.ResourceSnapshotDto; | |||
import org.sonar.core.dependency.ResourceSnapshotMapper; | |||
import org.sonar.core.duplication.DuplicationMapper; | |||
import org.sonar.core.duplication.DuplicationUnitDto; | |||
import org.sonar.core.event.EventDto; | |||
import org.sonar.core.event.db.EventMapper; | |||
import org.sonar.core.graph.jdbc.GraphDto; | |||
import org.sonar.core.graph.jdbc.GraphDtoMapper; | |||
import org.sonar.core.issue.db.*; | |||
@@ -184,6 +186,7 @@ public class MyBatis implements BatchComponent, ServerComponent { | |||
loadAlias(conf, "IdUuidPair", IdUuidPair.class); | |||
loadAlias(conf, "FilePathWithHash", FilePathWithHashDto.class); | |||
loadAlias(conf, "UuidWithProjectUuid", UuidWithProjectUuidDto.class); | |||
loadAlias(conf, "Event", EventDto.class); | |||
// AuthorizationMapper has to be loaded before IssueMapper because this last one used it | |||
loadMapper(conf, "org.sonar.core.user.AuthorizationMapper"); | |||
@@ -202,7 +205,7 @@ public class MyBatis implements BatchComponent, ServerComponent { | |||
NotificationQueueMapper.class, CharacteristicMapper.class, | |||
GroupMembershipMapper.class, QualityProfileMapper.class, ActiveRuleMapper.class, | |||
MeasureMapper.class, MetricMapper.class, QualityGateMapper.class, QualityGateConditionMapper.class, ComponentMapper.class, SnapshotMapper.class, | |||
ProjectQgateAssociationMapper.class, | |||
ProjectQgateAssociationMapper.class, EventMapper.class, | |||
AnalysisReportMapper.class, ComponentIndexMapper.class, ComponentLinkMapper.class, | |||
Migration45Mapper.class, Migration50Mapper.class | |||
}; |
@@ -125,9 +125,9 @@ class PurgeCommands { | |||
session.commit(); | |||
profiler.stop(); | |||
profiler.start("deleteResourceEvents (events)"); | |||
for (List<Long> partResourceIds : componentIdPartitions) { | |||
purgeMapper.deleteResourceEvents(partResourceIds); | |||
profiler.start("deleteComponentEvents (events)"); | |||
for (List<String> componentUuidPartition : componentUuidsPartitions) { | |||
purgeMapper.deleteComponentEvents(componentUuidPartition); | |||
} | |||
session.commit(); | |||
profiler.stop(); |
@@ -79,7 +79,7 @@ public interface PurgeMapper { | |||
void deleteResourceManualMeasures(@Param("resourceIds") List<Long> resourceIds); | |||
void deleteResourceEvents(@Param("resourceIds") List<Long> resourceIds); | |||
void deleteComponentEvents(@Param("componentUuids") List<String> componentUuids); | |||
void deleteResourceActionPlans(@Param("resourceIds") List<Long> resourceIds); | |||
@@ -0,0 +1,35 @@ | |||
<?xml version="1.0" encoding="UTF-8" ?> | |||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||
<mapper namespace="org.sonar.core.event.db.EventMapper"> | |||
<sql id="eventColumns"> | |||
e.id, | |||
e.name, | |||
e.category, | |||
e.description, | |||
e.event_data as "data", | |||
e.event_date as "date", | |||
e.component_uuid as "componentUuid", | |||
e.snapshot_id as "snapshotId", | |||
e.created_at as "createdAt" | |||
</sql> | |||
<select id="selectByComponentUuid" parameterType="String" resultType="Event"> | |||
SELECT <include refid="eventColumns"/> | |||
FROM events e | |||
<where> | |||
AND e.component_uuid=#{uuid} | |||
</where> | |||
</select> | |||
<insert id="insert" parameterType="Event" keyColumn="id" useGeneratedKeys="true" keyProperty="id"> | |||
INSERT INTO events (name, category, description, event_data, event_date, component_uuid, snapshot_id, created_at) | |||
VALUES (#{name}, #{category}, #{description}, #{data}, #{date}, #{componentUuid}, #{snapshotId}, #{createdAt}) | |||
</insert> | |||
<delete id="delete"> | |||
DELETE FROM events WHERE id=#{id} | |||
</delete> | |||
</mapper> | |||
@@ -326,6 +326,9 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('796'); | |||
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('900'); | |||
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('901'); | |||
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('902'); | |||
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('903'); | |||
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('904'); | |||
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('905'); | |||
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', '1418215735482', '1418215735482', null, null); | |||
ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2; |
@@ -164,7 +164,7 @@ CREATE TABLE "WIDGET_PROPERTIES" ( | |||
CREATE TABLE "EVENTS" ( | |||
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), | |||
"NAME" VARCHAR(400), | |||
"RESOURCE_ID" INTEGER, | |||
"COMPONENT_UUID" VARCHAR(50), | |||
"SNAPSHOT_ID" INTEGER, | |||
"CATEGORY" VARCHAR(50), | |||
"EVENT_DATE" BIGINT NOT NULL, | |||
@@ -599,7 +599,7 @@ CREATE UNIQUE INDEX "METRICS_UNIQUE_NAME" ON "METRICS" ("NAME"); | |||
CREATE INDEX "EVENTS_SNAPSHOT_ID" ON "EVENTS" ("SNAPSHOT_ID"); | |||
CREATE INDEX "EVENTS_RESOURCE_ID" ON "EVENTS" ("RESOURCE_ID"); | |||
CREATE INDEX "EVENTS_COMPONENT_UUID" ON "EVENTS" ("COMPONENT_UUID"); | |||
CREATE INDEX "WIDGETS_WIDGETKEY" ON "WIDGETS" ("WIDGET_KEY"); | |||
@@ -238,10 +238,10 @@ | |||
</foreach> | |||
</delete> | |||
<delete id="deleteResourceEvents" parameterType="map"> | |||
delete from events where resource_id in | |||
<foreach collection="resourceIds" open="(" close=")" item="resourceId" separator=","> | |||
#{resourceId} | |||
<delete id="deleteComponentEvents" parameterType="map"> | |||
delete from events where component_uuid in | |||
<foreach collection="componentUuids" open="(" close=")" item="componentUuid" separator=","> | |||
#{componentUuid} | |||
</foreach> | |||
</delete> | |||
@@ -22,9 +22,9 @@ | |||
<project_measures id="1" value="10" metric_id="1" snapshot_id="1000" /> | |||
<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]" /> | |||
<events id="1" name="1.0-SNAPSHOT" component_uuid="123" event_data="[null]"/> | |||
<events id="2" name="2.0-SNAPSHOT" component_uuid="123" event_data="[null]" /> | |||
<events id="3" name="1.0-SNAPSHOT" component_uuid="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" /> |
@@ -15,7 +15,7 @@ | |||
build_date="1228222680000" | |||
version="[null]" path="[null]"/> | |||
<events id="1" name="Version 1.0" resource_id="1" snapshot_id="1" category="VERSION" description="[null]" | |||
<events id="1" name="Version 1.0" component_uuid="1" snapshot_id="1" category="VERSION" description="[null]" | |||
event_date="1228222680000" created_at="1228222680000" event_data="[null]"/> | |||
<issues id="1" kee="ABCDE" component_uuid="1" project_uuid="1" status="CLOSED" resolution="[null]" line="200" |
@@ -25,7 +25,7 @@ | |||
<dependencies id="1" from_resource_id="1" from_snapshot_id="1" to_resource_id="30" to_snapshot_id="30" | |||
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]" | |||
<events id="1" name="Version 1.0" component_uuid="1" snapshot_id="1" category="VERSION" description="[null]" | |||
event_date="1228222680000" created_at="1228222680000" 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"/> |
@@ -24,7 +24,7 @@ | |||
<dependencies id="1" from_resource_id="1" from_snapshot_id="1" to_resource_id="30" to_snapshot_id="30" | |||
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]" | |||
<events id="1" name="Version 1.0" component_uuid="1" snapshot_id="1" category="VERSION" description="[null]" | |||
event_date="1228222680000" created_at="1228222680000" 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"/> | |||
@@ -57,7 +57,7 @@ | |||
<dependencies id="3" from_resource_id="5" from_snapshot_id="5" to_resource_id="300" to_snapshot_id="300" | |||
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]" | |||
<events id="2" name="Version 1.0" component_uuid="5" snapshot_id="5" category="VERSION" description="[null]" | |||
event_date="1228222680000" created_at="1228222680000" 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"/> |
@@ -41,7 +41,7 @@ Note that measures, events and reviews are not deleted. | |||
<!--parent_dependency_id="[null]" project_snapshot_id="2"--> | |||
<!--dep_usage="USES" dep_weight="1" from_scope="LIB" to_scope="PRJ"/>--> | |||
<events id="1" resource_id="1" snapshot_id="1" | |||
<events id="1" component_uuid="1" snapshot_id="1" | |||
category="VERSION" description="[null]" name="Version 1.0" event_date="1228222680000" | |||
created_at="1228222680000" | |||
event_data="[null]"/> | |||
@@ -80,7 +80,7 @@ Note that measures, events and reviews are not deleted. | |||
parent_dependency_id="[null]" project_snapshot_id="2" | |||
dep_usage="USES" dep_weight="1" from_scope="LIB" to_scope="PRJ"/> | |||
<events id="2" resource_id="2" snapshot_id="2" | |||
<events id="2" component_uuid="2" snapshot_id="2" | |||
category="VERSION" description="[null]" name="Version 1.0" event_date="1228222680000" | |||
created_at="1228222680000" | |||
event_data="[null]"/> |
@@ -26,7 +26,7 @@ | |||
parent_dependency_id="[null]" project_snapshot_id="2" | |||
dep_usage="USES" dep_weight="1" from_scope="LIB" to_scope="PRJ"/> | |||
<events id="1" resource_id="1" snapshot_id="1" | |||
<events id="1" component_uuid="1" snapshot_id="1" | |||
category="VERSION" description="[null]" name="Version 1.0" event_date="1228222680000" | |||
created_at="1228222680000" | |||
event_data="[null]"/> | |||
@@ -64,7 +64,7 @@ | |||
parent_dependency_id="[null]" project_snapshot_id="2" | |||
dep_usage="USES" dep_weight="1" from_scope="LIB" to_scope="PRJ"/> | |||
<events id="2" resource_id="2" snapshot_id="2" | |||
<events id="2" component_uuid="2" snapshot_id="2" | |||
category="VERSION" description="[null]" name="Version 1.0" event_date="1228222680000" | |||
created_at="1228222680000" | |||
event_data="[null]"/> |
@@ -55,7 +55,7 @@ | |||
period5_mode="[null]" period5_param="[null]" period5_date="[null]" | |||
depth="[null]" scope="PRJ" qualifier="TRK" created_at="1228222680000" build_date="1228222680000" version="[null]" path="[null]"/> | |||
<events id="2" resource_id="1" snapshot_id="5" | |||
<events id="2" component_uuid="1" snapshot_id="5" | |||
category="Version" description="[null]" name="Version 1.0" event_date="1228222680000" created_at="1228222680000" | |||
event_data="[null]"/> | |||
@@ -21,9 +21,11 @@ package org.sonar.api.batch; | |||
import org.apache.commons.lang.builder.ToStringBuilder; | |||
import org.sonar.api.database.BaseIdentifiable; | |||
import org.sonar.api.database.model.ResourceModel; | |||
import org.sonar.api.database.model.Snapshot; | |||
import javax.persistence.*; | |||
import java.util.Date; | |||
import static com.google.common.base.Preconditions.checkNotNull; | |||
@@ -61,8 +63,12 @@ public class Event extends BaseIdentifiable { | |||
@JoinColumn(name = "snapshot_id", updatable = true, nullable = true) | |||
private Snapshot snapshot; | |||
@Column(name = "resource_id", updatable = true, nullable = true) | |||
private Integer resourceId; | |||
@ManyToOne(fetch = FetchType.LAZY) | |||
@JoinColumn(name = "component_uuid", referencedColumnName = "uuid", insertable = false, updatable = false, nullable = false) | |||
private ResourceModel resource; | |||
@Column(name = "component_uuid", updatable = true, nullable = true) | |||
private String componentUuid; | |||
public Event() { | |||
} | |||
@@ -128,16 +134,23 @@ public class Event extends BaseIdentifiable { | |||
public final void setSnapshot(Snapshot snapshot) { | |||
this.snapshot = checkNotNull(snapshot, "it is not possible to set a null snapshot linked to an event"); | |||
this.date = snapshot.getCreatedAtMs(); | |||
this.resourceId = snapshot.getResourceId(); | |||
// this.resourceId = snapshot.getResourceId(); | |||
} | |||
public ResourceModel getResource() { | |||
return resource; | |||
} | |||
public void setResource(ResourceModel resource) { | |||
this.resource = resource; | |||
} | |||
public Integer getResourceId() { | |||
return resourceId; | |||
public String getComponentUuid() { | |||
return componentUuid; | |||
} | |||
public Event setResourceId(Integer resourceId) { | |||
this.resourceId = resourceId; | |||
return this; | |||
public void setComponentUuid(String componentUuid) { | |||
this.componentUuid = componentUuid; | |||
} | |||
public String getData() { | |||
@@ -155,7 +168,7 @@ public class Event extends BaseIdentifiable { | |||
.append("categ", category) | |||
.append("date", date) | |||
.append("snapshot", snapshot) | |||
.append("resource", resourceId) | |||
.append("resource", resource) | |||
.toString(); | |||
} | |||
} |
@@ -30,6 +30,7 @@ import org.sonar.api.resources.Resource; | |||
import javax.annotation.Nullable; | |||
import javax.persistence.*; | |||
import java.io.Serializable; | |||
import java.util.Date; | |||
/** | |||
@@ -37,7 +38,7 @@ import java.util.Date; | |||
*/ | |||
@Entity | |||
@Table(name = "projects") | |||
public class ResourceModel extends BaseIdentifiable implements Cloneable { | |||
public class ResourceModel extends BaseIdentifiable implements Cloneable, Serializable { | |||
public static final String SCOPE_PROJECT = "PRJ"; | |||
public static final String QUALIFIER_PROJECT_TRUNK = "TRK"; |