diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2015-07-05 10:06:55 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2015-07-06 09:22:44 +0200 |
commit | 32af292b745b7226bacc3f34d612437664af0ba3 (patch) | |
tree | 538d0b9852eaeb08ad685d426ea61c8170210e40 /sonar-db/src | |
parent | 1df148803610cd54f182b8636f01c0e6ece92b19 (diff) | |
download | sonarqube-32af292b745b7226bacc3f34d612437664af0ba3.tar.gz sonarqube-32af292b745b7226bacc3f34d612437664af0ba3.zip |
Move some classes from sonar-server to sonar-db
Diffstat (limited to 'sonar-db/src')
136 files changed, 4895 insertions, 915 deletions
diff --git a/sonar-db/src/main/java/org/sonar/core/timemachine/Periods.java b/sonar-db/src/main/java/org/sonar/core/timemachine/Periods.java index 2d16c7137d0..9a70977c140 100644 --- a/sonar-db/src/main/java/org/sonar/core/timemachine/Periods.java +++ b/sonar-db/src/main/java/org/sonar/core/timemachine/Periods.java @@ -30,11 +30,9 @@ import org.sonar.api.CoreProperties; import org.sonar.api.config.Settings; import org.sonar.api.database.model.Snapshot; import org.sonar.api.i18n.I18n; -import org.sonar.api.server.ServerSide; import static org.sonar.api.utils.DateUtils.longToDate; -@ServerSide public class Periods { private final Settings settings; diff --git a/sonar-db/src/main/java/org/sonar/db/component/ComponentIndexMapper.java b/sonar-db/src/main/java/org/sonar/db/AbstractDao.java index 44eafac3a24..245f0e87ec9 100644 --- a/sonar-db/src/main/java/org/sonar/db/component/ComponentIndexMapper.java +++ b/sonar-db/src/main/java/org/sonar/db/AbstractDao.java @@ -17,13 +17,25 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +package org.sonar.db; -package org.sonar.db.component; +import org.sonar.api.utils.System2; -import java.util.List; -import org.apache.ibatis.annotations.Param; +public abstract class AbstractDao implements Dao { -public interface ComponentIndexMapper { + private final MyBatis myBatis; + private final System2 system2; - List<Long> selectProjectIdsFromQueryAndViewOrSubViewUuid(@Param("query") String query, @Param("viewUuidQuery") String viewUuidQuery); + public AbstractDao(MyBatis myBatis, System2 system2) { + this.myBatis = myBatis; + this.system2 = system2; + } + + protected MyBatis myBatis() { + return myBatis; + } + + protected long now() { + return system2.now(); + } } diff --git a/sonar-db/src/main/java/org/sonar/db/DaoUtils.java b/sonar-db/src/main/java/org/sonar/db/DaoUtils.java index 5c0d3269e3c..7e3773f2b0d 100644 --- a/sonar-db/src/main/java/org/sonar/db/DaoUtils.java +++ b/sonar-db/src/main/java/org/sonar/db/DaoUtils.java @@ -19,19 +19,22 @@ */ package org.sonar.db; -import com.google.common.base.Function; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import java.util.Collection; -import java.util.Collections; +import java.util.Arrays; import java.util.List; +import org.sonar.db.activity.ActivityDao; +import org.sonar.db.component.ComponentLinkDao; import org.sonar.db.component.ResourceDao; import org.sonar.db.component.ResourceIndexerDao; import org.sonar.db.component.ResourceKeyUpdaterDao; +import org.sonar.db.component.SnapshotDao; +import org.sonar.db.compute.AnalysisReportDao; import org.sonar.db.dashboard.ActiveDashboardDao; import org.sonar.db.dashboard.DashboardDao; +import org.sonar.db.dashboard.WidgetDao; +import org.sonar.db.dashboard.WidgetPropertyDao; import org.sonar.db.debt.CharacteristicDao; import org.sonar.db.duplication.DuplicationDao; +import org.sonar.db.event.EventDao; import org.sonar.db.issue.ActionPlanDao; import org.sonar.db.issue.ActionPlanStatsDao; import org.sonar.db.issue.IssueChangeDao; @@ -39,48 +42,53 @@ import org.sonar.db.issue.IssueDao; import org.sonar.db.issue.IssueFilterDao; import org.sonar.db.issue.IssueFilterFavouriteDao; import org.sonar.db.loadedtemplate.LoadedTemplateDao; +import org.sonar.db.measure.MeasureDao; +import org.sonar.db.measure.MeasureFilterDao; import org.sonar.db.notification.NotificationQueueDao; import org.sonar.db.permission.PermissionDao; import org.sonar.db.permission.PermissionTemplateDao; import org.sonar.db.property.PropertiesDao; import org.sonar.db.purge.PurgeDao; import org.sonar.db.qualitygate.QualityGateConditionDao; -import org.sonar.db.qualityprofile.ActiveRuleDao; import org.sonar.db.qualityprofile.QualityProfileDao; import org.sonar.db.rule.RuleDao; import org.sonar.db.semaphore.SemaphoreDao; +import org.sonar.db.source.FileSourceDao; import org.sonar.db.user.AuthorDao; import org.sonar.db.user.AuthorizationDao; import org.sonar.db.user.GroupMembershipDao; import org.sonar.db.user.RoleDao; import org.sonar.db.user.UserDao; - -import static com.google.common.collect.Lists.newArrayList; +import org.sonar.db.user.UserGroupDao; public final class DaoUtils { - private static final int PARTITION_SIZE_FOR_ORACLE = 1000; - private DaoUtils() { // only static stuff } - public static List<Class> getDaoClasses() { - return ImmutableList.<Class>of( + public static List<Class<? extends Dao>> getDaoClasses() { + return Arrays.asList( ActionPlanDao.class, ActionPlanStatsDao.class, ActiveDashboardDao.class, - ActiveRuleDao.class, + ActivityDao.class, + AnalysisReportDao.class, AuthorDao.class, AuthorizationDao.class, + ComponentLinkDao.class, DashboardDao.class, DuplicationDao.class, + EventDao.class, + FileSourceDao.class, GroupMembershipDao.class, IssueDao.class, IssueChangeDao.class, IssueFilterDao.class, IssueFilterFavouriteDao.class, LoadedTemplateDao.class, + MeasureDao.class, + MeasureFilterDao.class, NotificationQueueDao.class, PermissionDao.class, PermissionTemplateDao.class, @@ -95,55 +103,11 @@ public final class DaoUtils { RoleDao.class, RuleDao.class, SemaphoreDao.class, - UserDao.class + SnapshotDao.class, + UserDao.class, + UserGroupDao.class, + WidgetDao.class, + WidgetPropertyDao.class ); } - - /** - * Partition by 1000 elements a list of input and execute a function on each part. - * - * The goal is to prevent issue with ORACLE when there's more than 1000 elements in a 'in ('X', 'Y', ...)' - * and with MsSQL when there's more than 2000 parameters in a query - */ - public static <OUTPUT, INPUT> List<OUTPUT> executeLargeInputs(Collection<INPUT> input, Function<List<INPUT>, List<OUTPUT>> function) { - if (input.isEmpty()) { - return Collections.emptyList(); - } - List<OUTPUT> results = newArrayList(); - List<List<INPUT>> partitionList = Lists.partition(newArrayList(input), PARTITION_SIZE_FOR_ORACLE); - for (List<INPUT> partition : partitionList) { - List<OUTPUT> subResults = function.apply(partition); - results.addAll(subResults); - } - return results; - } - - /** - * Partition by 1000 elements a list of input and execute a function on each part. - * The function has not output (ex: delete operation) - * - * The goal is to prevent issue with ORACLE when there's more than 1000 elements in a 'in ('X', 'Y', ...)' - * and with MsSQL when there's more than 2000 parameters in a query - */ - public static <INPUT> void executeLargeInputsWithoutOutput(Collection<INPUT> input, Function<List<INPUT>, Void> function) { - if (input.isEmpty()) { - return; - } - - List<List<INPUT>> partitions = Lists.partition(newArrayList(input), PARTITION_SIZE_FOR_ORACLE); - for (List<INPUT> partition : partitions) { - function.apply(partition); - } - } - - public static String repeatCondition(String sql, int count, String separator) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < count; i++) { - sb.append(sql); - if (i < count - 1) { - sb.append(" ").append(separator).append(" "); - } - } - return sb.toString(); - } } diff --git a/sonar-db/src/main/java/org/sonar/db/DatabaseChecker.java b/sonar-db/src/main/java/org/sonar/db/DatabaseChecker.java new file mode 100644 index 00000000000..31dc571008f --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/DatabaseChecker.java @@ -0,0 +1,86 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db; + +import com.google.common.base.Throwables; +import java.sql.Connection; +import java.sql.SQLException; +import org.apache.commons.dbutils.DbUtils; +import org.apache.commons.lang.StringUtils; +import org.picocontainer.Startable; +import org.sonar.api.utils.MessageException; +import org.sonar.api.utils.log.Loggers; +import org.sonar.db.dialect.H2; +import org.sonar.db.dialect.Oracle; + +public class DatabaseChecker implements Startable { + + public static final int ORACLE_MIN_MAJOR_VERSION = 11; + + private final Database db; + + public DatabaseChecker(Database db) { + this.db = db; + } + + @Override + public void start() { + try { + if (H2.ID.equals(db.getDialect().getId())) { + Loggers.get(DatabaseChecker.class).warn("H2 database should be used for evaluation purpose only"); + } else if (Oracle.ID.equals(db.getDialect().getId())) { + checkOracleVersion(); + } + } catch (Exception e) { + Throwables.propagate(e); + } + } + + @Override + public void stop() { + // nothing to do + } + + private void checkOracleVersion() throws SQLException { + Connection connection = db.getDataSource().getConnection(); + try { + // check version of db + // See http://jira.sonarsource.com/browse/SONAR-6434 + int majorVersion = connection.getMetaData().getDatabaseMajorVersion(); + if (majorVersion < ORACLE_MIN_MAJOR_VERSION) { + throw MessageException.of(String.format( + "Unsupported Oracle version: %s. Minimal required version is %d.", connection.getMetaData().getDatabaseProductVersion(), ORACLE_MIN_MAJOR_VERSION)); + } + + // check version of driver + String driverVersion = connection.getMetaData().getDriverVersion(); + String[] parts = StringUtils.split(driverVersion, "."); + int intVersion = Integer.parseInt(parts[0]) * 100 + Integer.parseInt(parts[1]); + if (intVersion < 1102) { + throw MessageException.of(String.format( + "Unsupported Oracle JDBC driver version: %s. Minimal required version is 11.2.", driverVersion)); + } + + } finally { + DbUtils.closeQuietly(connection); + } + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/DatabaseUtils.java b/sonar-db/src/main/java/org/sonar/db/DatabaseUtils.java index 28ac5923b72..6d74d2474cc 100644 --- a/sonar-db/src/main/java/org/sonar/db/DatabaseUtils.java +++ b/sonar-db/src/main/java/org/sonar/db/DatabaseUtils.java @@ -19,17 +19,24 @@ */ package org.sonar.db; +import com.google.common.base.Function; +import com.google.common.collect.Lists; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.util.Collection; +import java.util.Collections; +import java.util.List; import javax.annotation.Nullable; import org.slf4j.LoggerFactory; -/** - * @since 2.13 - */ +import static com.google.common.collect.Lists.newArrayList; + public final class DatabaseUtils { + + private static final int PARTITION_SIZE_FOR_ORACLE = 1000; + private DatabaseUtils() { // only static methods } @@ -66,4 +73,52 @@ public final class DatabaseUtils { } } } + + /** + * Partition by 1000 elements a list of input and execute a function on each part. + * + * The goal is to prevent issue with ORACLE when there's more than 1000 elements in a 'in ('X', 'Y', ...)' + * and with MsSQL when there's more than 2000 parameters in a query + */ + public static <OUTPUT, INPUT> List<OUTPUT> executeLargeInputs(Collection<INPUT> input, Function<List<INPUT>, List<OUTPUT>> function) { + if (input.isEmpty()) { + return Collections.emptyList(); + } + List<OUTPUT> results = newArrayList(); + List<List<INPUT>> partitionList = Lists.partition(newArrayList(input), PARTITION_SIZE_FOR_ORACLE); + for (List<INPUT> partition : partitionList) { + List<OUTPUT> subResults = function.apply(partition); + results.addAll(subResults); + } + return results; + } + + /** + * Partition by 1000 elements a list of input and execute a function on each part. + * The function has not output (ex: delete operation) + * + * The goal is to prevent issue with ORACLE when there's more than 1000 elements in a 'in ('X', 'Y', ...)' + * and with MsSQL when there's more than 2000 parameters in a query + */ + public static <INPUT> void executeLargeInputsWithoutOutput(Collection<INPUT> input, Function<List<INPUT>, Void> function) { + if (input.isEmpty()) { + return; + } + + List<List<INPUT>> partitions = Lists.partition(newArrayList(input), PARTITION_SIZE_FOR_ORACLE); + for (List<INPUT> partition : partitions) { + function.apply(partition); + } + } + + public static String repeatCondition(String sql, int count, String separator) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < count; i++) { + sb.append(sql); + if (i < count - 1) { + sb.append(" ").append(separator).append(" "); + } + } + return sb.toString(); + } } diff --git a/sonar-db/src/main/java/org/sonar/db/DbClient2.java b/sonar-db/src/main/java/org/sonar/db/DbClient2.java new file mode 100644 index 00000000000..92cbd39c2c5 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/DbClient2.java @@ -0,0 +1,253 @@ +/* + * 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.db; + +import java.util.IdentityHashMap; +import java.util.Map; +import javax.annotation.Nullable; +import org.sonar.db.activity.ActivityDao; +import org.sonar.db.component.ComponentLinkDao; +import org.sonar.db.component.ResourceDao; +import org.sonar.db.component.ResourceIndexerDao; +import org.sonar.db.component.SnapshotDao; +import org.sonar.db.compute.AnalysisReportDao; +import org.sonar.db.dashboard.DashboardDao; +import org.sonar.db.dashboard.WidgetDao; +import org.sonar.db.dashboard.WidgetPropertyDao; +import org.sonar.db.debt.CharacteristicDao; +import org.sonar.db.event.EventDao; +import org.sonar.db.issue.ActionPlanDao; +import org.sonar.db.issue.ActionPlanStatsDao; +import org.sonar.db.issue.IssueChangeDao; +import org.sonar.db.issue.IssueDao; +import org.sonar.db.issue.IssueFilterDao; +import org.sonar.db.loadedtemplate.LoadedTemplateDao; +import org.sonar.db.measure.MeasureDao; +import org.sonar.db.permission.PermissionTemplateDao; +import org.sonar.db.property.PropertiesDao; +import org.sonar.db.purge.PurgeDao; +import org.sonar.db.qualitygate.QualityGateConditionDao; +import org.sonar.db.qualityprofile.QualityProfileDao; +import org.sonar.db.source.FileSourceDao; +import org.sonar.db.user.AuthorDao; +import org.sonar.db.user.AuthorizationDao; +import org.sonar.db.user.GroupMembershipDao; +import org.sonar.db.user.RoleDao; +import org.sonar.db.user.UserGroupDao; + +public class DbClient2 { + + private final MyBatis myBatis; + private final QualityProfileDao qualityProfileDao; + private final CharacteristicDao debtCharacteristicDao; + private final LoadedTemplateDao loadedTemplateDao; + private final PropertiesDao propertiesDao; + private final SnapshotDao snapshotDao; + private final ResourceDao resourceDao; + private final MeasureDao measureDao; + private final ActivityDao activityDao; + private final AuthorizationDao authorizationDao; + private final UserGroupDao userGroupDao; + private final GroupMembershipDao groupMembershipDao; + private final RoleDao roleDao; + private final PermissionTemplateDao permissionTemplateDao; + private final IssueDao issueDao; + private final IssueFilterDao issueFilterDao; + private final IssueChangeDao issueChangeDao; + private final ActionPlanDao actionPlanDao; + private final ActionPlanStatsDao actionPlanStatsDao; + private final AnalysisReportDao analysisReportDao; + private final DashboardDao dashboardDao; + private final WidgetDao widgetDao; + private final WidgetPropertyDao widgetPropertyDao; + private final FileSourceDao fileSourceDao; + private final AuthorDao authorDao; + private final ResourceIndexerDao componentIndexDao; + private final ComponentLinkDao componentLinkDao; + private final EventDao eventDao; + private final PurgeDao purgeDao; + private final QualityGateConditionDao gateConditionDao; + + public DbClient2(MyBatis myBatis, Dao[] daos) { + this.myBatis = myBatis; + + Map<Class, Dao> map = new IdentityHashMap<>(); + for (Dao dao : daos) { + map.put(dao.getClass(), dao); + } + debtCharacteristicDao = getDao(map, CharacteristicDao.class); + qualityProfileDao = getDao(map, QualityProfileDao.class); + loadedTemplateDao = getDao(map, LoadedTemplateDao.class); + propertiesDao = getDao(map, PropertiesDao.class); + snapshotDao = getDao(map, SnapshotDao.class); + resourceDao = getDao(map, ResourceDao.class); + measureDao = getDao(map, MeasureDao.class); + activityDao = getDao(map, ActivityDao.class); + authorizationDao = getDao(map, AuthorizationDao.class); + userGroupDao = getDao(map, UserGroupDao.class); + groupMembershipDao = getDao(map, GroupMembershipDao.class); + roleDao = getDao(map, RoleDao.class); + permissionTemplateDao = getDao(map, PermissionTemplateDao.class); + issueDao = getDao(map, IssueDao.class); + issueFilterDao = getDao(map, IssueFilterDao.class); + issueChangeDao = getDao(map, IssueChangeDao.class); + actionPlanDao = getDao(map, ActionPlanDao.class); + actionPlanStatsDao = getDao(map, ActionPlanStatsDao.class); + analysisReportDao = getDao(map, AnalysisReportDao.class); + dashboardDao = getDao(map, DashboardDao.class); + widgetDao = getDao(map, WidgetDao.class); + widgetPropertyDao = getDao(map, WidgetPropertyDao.class); + fileSourceDao = getDao(map, FileSourceDao.class); + authorDao = getDao(map, AuthorDao.class); + componentIndexDao = getDao(map, ResourceIndexerDao.class); + componentLinkDao = getDao(map, ComponentLinkDao.class); + eventDao = getDao(map, EventDao.class); + purgeDao = getDao(map, PurgeDao.class); + gateConditionDao = getDao(map, QualityGateConditionDao.class); + } + + public DbSession openSession(boolean batch) { + return myBatis.openSession(batch); + } + + public void closeSession(@Nullable DbSession session) { + MyBatis.closeQuietly(session); + } + + public IssueDao issueDao() { + return issueDao; + } + + public IssueFilterDao issueFilterDao() { + return issueFilterDao; + } + + public IssueChangeDao issueChangeDao() { + return issueChangeDao; + } + + public QualityProfileDao qualityProfileDao() { + return qualityProfileDao; + } + + public CharacteristicDao debtCharacteristicDao() { + return debtCharacteristicDao; + } + + public LoadedTemplateDao loadedTemplateDao() { + return loadedTemplateDao; + } + + public PropertiesDao propertiesDao() { + return propertiesDao; + } + + public SnapshotDao snapshotDao() { + return snapshotDao; + } + + public ResourceDao resourceDao() { + return resourceDao; + } + + public MeasureDao measureDao() { + return measureDao; + } + + public ActivityDao activityDao() { + return activityDao; + } + + public AuthorizationDao authorizationDao() { + return authorizationDao; + } + + public UserGroupDao userGroupDao() { + return userGroupDao; + } + + public GroupMembershipDao groupMembershipDao() { + return groupMembershipDao; + } + + public RoleDao roleDao() { + return roleDao; + } + + public PermissionTemplateDao permissionTemplateDao() { + return permissionTemplateDao; + } + + public ActionPlanDao actionPlanDao() { + return actionPlanDao; + } + + public AnalysisReportDao analysisReportDao() { + return analysisReportDao; + } + + public DashboardDao dashboardDao() { + return dashboardDao; + } + + public WidgetDao widgetDao() { + return widgetDao; + } + + public WidgetPropertyDao widgetPropertyDao() { + return widgetPropertyDao; + } + + public FileSourceDao fileSourceDao() { + return fileSourceDao; + } + + public AuthorDao authorDao() { + return authorDao; + } + + public ResourceIndexerDao componentIndexDao() { + return componentIndexDao; + } + + public ComponentLinkDao componentLinkDao() { + return componentLinkDao; + } + + public EventDao eventDao() { + return eventDao; + } + + public PurgeDao purgeDao() { + return purgeDao; + } + + public ActionPlanStatsDao getActionPlanStatsDao() { + return actionPlanStatsDao; + } + + public QualityGateConditionDao gateConditionDao() { + return gateConditionDao; + } + + private <K extends Dao> K getDao(Map<Class, Dao> map, Class<K> clazz) { + return (K) map.get(clazz); + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/DefaultDatabase.java b/sonar-db/src/main/java/org/sonar/db/DefaultDatabase.java index c5e5e1c12b8..47db0259f00 100644 --- a/sonar-db/src/main/java/org/sonar/db/DefaultDatabase.java +++ b/sonar-db/src/main/java/org/sonar/db/DefaultDatabase.java @@ -30,10 +30,10 @@ import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.dbcp.BasicDataSourceFactory; import org.apache.commons.dbutils.DbUtils; import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.sonar.api.config.Settings; import org.sonar.api.database.DatabaseProperties; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; import org.sonar.db.dialect.Dialect; import org.sonar.db.dialect.DialectUtils; import org.sonar.db.profiling.ProfiledDataSource; @@ -43,7 +43,7 @@ import org.sonar.db.profiling.ProfiledDataSource; */ public class DefaultDatabase implements Database { - private static final Logger LOG = LoggerFactory.getLogger(Database.class); + private static final Logger LOG = Loggers.get(Database.class); private static final String DEFAULT_URL = "jdbc:h2:tcp://localhost/sonar"; private static final String SONAR_JDBC = "sonar.jdbc."; @@ -65,20 +65,12 @@ public class DefaultDatabase implements Database { initSettings(); initDatasource(); checkConnection(); - doAfterStart(); } catch (Exception e) { throw new IllegalStateException("Fail to connect to database", e); } } - /** - * Override to execute post-startup code. - */ - protected void doAfterStart() { - // nothing to do - } - @VisibleForTesting void initSettings() { properties = new Properties(); @@ -104,7 +96,6 @@ public class DefaultDatabase implements Database { private void checkConnection() { Connection connection = null; try { - LOG.debug("Testing JDBC connection"); connection = datasource.getConnection(); } catch (SQLException e) { throw new IllegalStateException("Can not connect to database. Please check connectivity and settings (see the properties prefixed by 'sonar.jdbc.').", e); @@ -176,7 +167,7 @@ public class DefaultDatabase implements Database { } private static void completeDefaultProperty(Properties props, String key, String defaultValue) { - if (props.getProperty(key) == null && defaultValue != null) { + if (props.getProperty(key) == null) { props.setProperty(key, defaultValue); } } diff --git a/sonar-db/src/main/java/org/sonar/db/MyBatis.java b/sonar-db/src/main/java/org/sonar/db/MyBatis.java index a6aa01cbc4f..5926def8753 100644 --- a/sonar-db/src/main/java/org/sonar/db/MyBatis.java +++ b/sonar-db/src/main/java/org/sonar/db/MyBatis.java @@ -23,6 +23,9 @@ package org.sonar.db; import ch.qos.logback.classic.Level; import com.google.common.io.Closeables; import java.io.InputStream; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; import javax.annotation.Nullable; import org.apache.ibatis.builder.xml.XMLMapperBuilder; import org.apache.ibatis.logging.LogFactory; @@ -35,10 +38,10 @@ import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; import org.apache.ibatis.type.JdbcType; import org.slf4j.LoggerFactory; +import org.sonar.api.utils.log.Loggers; import org.sonar.db.activity.ActivityDto; import org.sonar.db.activity.ActivityMapper; import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentIndexMapper; import org.sonar.db.component.ComponentLinkDto; import org.sonar.db.component.ComponentLinkMapper; import org.sonar.db.component.ComponentMapper; @@ -144,8 +147,6 @@ public class MyBatis { private final Database database; private SqlSessionFactory sessionFactory; - - // TODO this queue should directly be an IndexQueue. Pending move of persistence to sonar-server private WorkQueue<?> queue; public MyBatis(Database database, WorkQueue<?> queue) { @@ -153,12 +154,13 @@ public class MyBatis { this.queue = queue; } + // FIXME should be visible only to DAOs -> to be moved to AbstractDao public static void closeQuietly(@Nullable SqlSession session) { if (session != null) { try { session.close(); } catch (Exception e) { - LoggerFactory.getLogger(MyBatis.class).warn("Fail to close session", e); + Loggers.get(MyBatis.class).warn("Fail to close db session", e); // do not re-throw the exception } } @@ -255,7 +257,7 @@ public class MyBatis { GroupMembershipMapper.class, QualityProfileMapper.class, ActiveRuleMapper.class, MeasureMapper.class, MetricMapper.class, CustomMeasureMapper.class, QualityGateMapper.class, QualityGateConditionMapper.class, ComponentMapper.class, SnapshotMapper.class, ProjectQgateAssociationMapper.class, EventMapper.class, - AnalysisReportMapper.class, ComponentIndexMapper.class, ComponentLinkMapper.class, + AnalysisReportMapper.class, ComponentLinkMapper.class, Migration45Mapper.class, Migration50Mapper.class }; loadMappers(conf, mappers); @@ -277,14 +279,6 @@ public class MyBatis { } /** - * @deprecated since 4.4. Replaced by <code>openSession(true)</code>. - */ - @Deprecated - public BatchSession openBatchSession() { - return (BatchSession) openSession(true); - } - - /** * @since 4.4 */ public DbSession openSession(boolean batch) { @@ -323,4 +317,31 @@ public class MyBatis { private void loadAlias(Configuration conf, String alias, Class dtoClass) { conf.getTypeAliasRegistry().registerAlias(alias, dtoClass); } + + /** + * Create a PreparedStatement for SELECT requests with scrolling of results + */ + public PreparedStatement newScrollingSelectStatement(DbSession session, String sql) { + int fetchSize = database.getDialect().getScrollDefaultFetchSize(); + return newScrollingSelectStatement(session, sql, fetchSize); + } + + /** + * Create a PreparedStatement for SELECT requests with scrolling of results row by row (only one row + * in memory at a time) + */ + public PreparedStatement newScrollingSingleRowSelectStatement(DbSession session, String sql) { + int fetchSize = database.getDialect().getScrollSingleRowFetchSize(); + return newScrollingSelectStatement(session, sql, fetchSize); + } + + private PreparedStatement newScrollingSelectStatement(DbSession session, String sql, int fetchSize) { + try { + PreparedStatement stmt = session.getConnection().prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); + stmt.setFetchSize(fetchSize); + return stmt; + } catch (SQLException e) { + throw new IllegalStateException("Fail to create SQL statement: " + sql, e); + } + } } diff --git a/sonar-db/src/main/java/org/sonar/db/ResultSetIterator.java b/sonar-db/src/main/java/org/sonar/db/ResultSetIterator.java new file mode 100644 index 00000000000..e96a9577141 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/ResultSetIterator.java @@ -0,0 +1,115 @@ +/* + * 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.db; + +import org.apache.commons.dbutils.DbUtils; + +import java.io.Closeable; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * Forward-only {@link java.util.Iterator} over a {@link java.sql.ResultSet}. Rows are + * lazily loaded. The underlying ResultSet must be closed by calling the method + * {@link #close()} + * <p/> + * As a safeguard, the ResultSet is automatically closed after the last element has + * been retrieved via {@link #next()} or {@link #hasNext()} is called (which will return false). + * This automagic behavior is not enough to remove explicit calls to {@link #close()} + * from caller methods. Errors raised before end of traversal must still be handled. + */ +public abstract class ResultSetIterator<E> implements Iterator<E>, Closeable { + + private final ResultSet rs; + private final PreparedStatement stmt; + + private volatile boolean didNext = false; + private volatile boolean hasNext = false; + private volatile boolean closed = false; + + public ResultSetIterator(PreparedStatement stmt) throws SQLException { + this.stmt = stmt; + this.rs = stmt.executeQuery(); + } + + protected ResultSetIterator(ResultSet rs) { + this.stmt = null; + this.rs = rs; + } + + @Override + public boolean hasNext() { + if (closed) { + return false; + } + if (!didNext) { + hasNext = doNextQuietly(); + if (hasNext) { + didNext = true; + } else { + close(); + } + } + return hasNext; + } + + @Override + public E next() { + if (!hasNext()) { + close(); + throw new NoSuchElementException(); + } + try { + return read(rs); + } catch (SQLException e) { + throw new IllegalStateException("Fail to read result set row", e); + } finally { + hasNext = doNextQuietly(); + if (!hasNext) { + close(); + } + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public void close() { + closed = true; + DbUtils.closeQuietly(rs); + DbUtils.closeQuietly(stmt); + } + + protected abstract E read(ResultSet rs) throws SQLException; + + private boolean doNextQuietly() { + try { + return rs.next(); + } catch (SQLException e) { + throw new IllegalStateException("Fail to read row of JDBC result set", e); + } + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/activity/ActivityDao.java b/sonar-db/src/main/java/org/sonar/db/activity/ActivityDao.java new file mode 100644 index 00000000000..25b7539beba --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/activity/ActivityDao.java @@ -0,0 +1,49 @@ +/* + * 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.db.activity; + +import java.util.Date; +import org.sonar.api.utils.System2; +import org.sonar.db.AbstractDao; +import org.sonar.db.DbSession; +import org.sonar.db.MyBatis; + +public class ActivityDao extends AbstractDao { + + public ActivityDao(MyBatis mybatis, System2 system) { + super(mybatis, system); + } + + public void insert(ActivityDto dto) { + DbSession session = myBatis().openSession(false); + try { + insert(session, dto); + session.commit(); + } finally { + MyBatis.closeQuietly(session); + } + } + + public void insert(DbSession session, ActivityDto dto) { + dto.setCreatedAt(new Date(now())); + session.getMapper(ActivityMapper.class).insert(dto); + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/component/ComponentLinkDao.java b/sonar-db/src/main/java/org/sonar/db/component/ComponentLinkDao.java new file mode 100644 index 00000000000..9c4f2940936 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/component/ComponentLinkDao.java @@ -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.db.component; + +import java.util.List; +import org.sonar.db.Dao; +import org.sonar.db.DbSession; + +public class ComponentLinkDao implements Dao { + + public List<ComponentLinkDto> selectByComponentUuid(DbSession session, String componentUuid) { + return session.getMapper(ComponentLinkMapper.class).selectByComponentUuid(componentUuid); + } + + public void insert(DbSession session, ComponentLinkDto dto) { + session.getMapper(ComponentLinkMapper.class).insert(dto); + } + + public void update(DbSession session, ComponentLinkDto dto) { + session.getMapper(ComponentLinkMapper.class).update(dto); + } + + public void delete(DbSession session, long id) { + session.getMapper(ComponentLinkMapper.class).delete(id); + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/component/ResourceDao.java b/sonar-db/src/main/java/org/sonar/db/component/ResourceDao.java index 2ebd03ec015..80addc6dd54 100644 --- a/sonar-db/src/main/java/org/sonar/db/component/ResourceDao.java +++ b/sonar-db/src/main/java/org/sonar/db/component/ResourceDao.java @@ -32,27 +32,24 @@ import org.sonar.api.component.Component; import org.sonar.api.resources.Scopes; import org.sonar.api.utils.System2; import org.sonar.api.utils.internal.Uuids; -import org.sonar.db.Dao; +import org.sonar.db.AbstractDao; import org.sonar.db.DbSession; import org.sonar.db.MyBatis; import static com.google.common.collect.Lists.newArrayList; -public class ResourceDao implements Dao { - private MyBatis mybatis; - private System2 system2; +public class ResourceDao extends AbstractDao { - public ResourceDao(MyBatis mybatis, System2 system2) { - this.mybatis = mybatis; - this.system2 = system2; + public ResourceDao(MyBatis myBatis, System2 system2) { + super(myBatis, system2); } public List<ResourceDto> getResources(ResourceQuery query) { - SqlSession session = mybatis.openSession(false); + SqlSession session = myBatis().openSession(false); try { return session.getMapper(ResourceMapper.class).selectResources(query); } finally { - MyBatis.closeQuietly(session); + myBatis().closeQuietly(session); } } @@ -66,11 +63,11 @@ public class ResourceDao implements Dao { */ @CheckForNull public ResourceDto getResource(ResourceQuery query) { - DbSession session = mybatis.openSession(false); + DbSession session = myBatis().openSession(false); try { return getResource(query, session); } finally { - MyBatis.closeQuietly(session); + myBatis().closeQuietly(session); } } @@ -84,30 +81,30 @@ public class ResourceDao implements Dao { } public List<Long> getResourceIds(ResourceQuery query) { - SqlSession session = mybatis.openSession(false); + SqlSession session = myBatis().openSession(false); try { return session.getMapper(ResourceMapper.class).selectResourceIds(query); } finally { - MyBatis.closeQuietly(session); + myBatis().closeQuietly(session); } } public ResourceDto getResource(long projectId) { - SqlSession session = mybatis.openSession(false); + SqlSession session = myBatis().openSession(false); try { return getResource(projectId, session); } finally { - MyBatis.closeQuietly(session); + myBatis().closeQuietly(session); } } @CheckForNull public ResourceDto getResource(String componentUuid) { - SqlSession session = mybatis.openSession(false); + SqlSession session = myBatis().openSession(false); try { return session.getMapper(ResourceMapper.class).selectResourceByUuid(componentUuid); } finally { - MyBatis.closeQuietly(session); + myBatis().closeQuietly(session); } } @@ -126,11 +123,11 @@ public class ResourceDao implements Dao { } public List<ResourceDto> getDescendantProjects(long projectId) { - SqlSession session = mybatis.openSession(false); + SqlSession session = myBatis().openSession(false); try { return getDescendantProjects(projectId, session); } finally { - MyBatis.closeQuietly(session); + myBatis().closeQuietly(session); } } @@ -153,9 +150,9 @@ public class ResourceDao implements Dao { * Used by the Views Plugin */ public ResourceDao insertOrUpdate(ResourceDto... resources) { - SqlSession session = mybatis.openSession(false); + SqlSession session = myBatis().openSession(false); ResourceMapper mapper = session.getMapper(ResourceMapper.class); - Date now = new Date(system2.now()); + Date now = new Date(now()); try { for (ResourceDto resource : resources) { if (resource.getId() == null) { @@ -175,7 +172,7 @@ public class ResourceDao implements Dao { } session.commit(); } finally { - MyBatis.closeQuietly(session); + myBatis().closeQuietly(session); } return this; } @@ -184,7 +181,7 @@ public class ResourceDao implements Dao { * Should not be called from batch side (used to reindex permission in E/S) */ public void updateAuthorizationDate(Long projectId, SqlSession session) { - session.getMapper(ResourceMapper.class).updateAuthorizationDate(projectId, system2.now()); + session.getMapper(ResourceMapper.class).updateAuthorizationDate(projectId, now()); } @CheckForNull @@ -222,11 +219,11 @@ public class ResourceDao implements Dao { @CheckForNull public ResourceDto getRootProjectByComponentKey(String componentKey) { - DbSession session = mybatis.openSession(false); + DbSession session = myBatis().openSession(false); try { return getRootProjectByComponentKey(session, componentKey); } finally { - MyBatis.closeQuietly(session); + myBatis().closeQuietly(session); } } @@ -253,7 +250,7 @@ public class ResourceDao implements Dao { */ @CheckForNull public ResourceDto getRootProjectByComponentId(long componentId) { - DbSession session = mybatis.openSession(false); + DbSession session = myBatis().openSession(false); try { ResourceDto component = getParentModuleByComponentId(componentId, session); Long rootId = component != null ? component.getRootId() : null; @@ -263,7 +260,7 @@ public class ResourceDao implements Dao { return component; } } finally { - MyBatis.closeQuietly(session); + myBatis().closeQuietly(session); } } @@ -271,11 +268,11 @@ public class ResourceDao implements Dao { if (qualifiers.isEmpty()) { return Collections.emptyList(); } - SqlSession session = mybatis.openSession(false); + SqlSession session = myBatis().openSession(false); try { return toComponents(session.getMapper(ResourceMapper.class).selectProjectsByQualifiers(qualifiers)); } finally { - MyBatis.closeQuietly(session); + myBatis().closeQuietly(session); } } @@ -286,11 +283,11 @@ public class ResourceDao implements Dao { if (qualifiers.isEmpty()) { return Collections.emptyList(); } - SqlSession session = mybatis.openSession(false); + SqlSession session = myBatis().openSession(false); try { return toComponents(session.getMapper(ResourceMapper.class).selectProjectsIncludingNotCompletedOnesByQualifiers(qualifiers)); } finally { - MyBatis.closeQuietly(session); + myBatis().closeQuietly(session); } } @@ -304,11 +301,11 @@ public class ResourceDao implements Dao { if (qualifiers.isEmpty()) { return Collections.emptyList(); } - SqlSession session = mybatis.openSession(false); + SqlSession session = myBatis().openSession(false); try { return toComponents(session.getMapper(ResourceMapper.class).selectGhostsProjects(qualifiers)); } finally { - MyBatis.closeQuietly(session); + myBatis().closeQuietly(session); } } @@ -319,11 +316,11 @@ public class ResourceDao implements Dao { if (qualifiers.isEmpty()) { return Collections.emptyList(); } - SqlSession session = mybatis.openSession(false); + SqlSession session = myBatis().openSession(false); try { return session.getMapper(ResourceMapper.class).selectProvisionedProjects(qualifiers); } finally { - MyBatis.closeQuietly(session); + myBatis().closeQuietly(session); } } @@ -335,11 +332,11 @@ public class ResourceDao implements Dao { } public ResourceDto selectProvisionedProject(String key) { - DbSession session = mybatis.openSession(false); + DbSession session = myBatis().openSession(false); try { return selectProvisionedProject(session, key); } finally { - MyBatis.closeQuietly(session); + myBatis().closeQuietly(session); } } diff --git a/sonar-db/src/main/java/org/sonar/db/component/ResourceIndexerDao.java b/sonar-db/src/main/java/org/sonar/db/component/ResourceIndexerDao.java index 6a61ef714e6..827ece8fd1b 100644 --- a/sonar-db/src/main/java/org/sonar/db/component/ResourceIndexerDao.java +++ b/sonar-db/src/main/java/org/sonar/db/component/ResourceIndexerDao.java @@ -19,16 +19,19 @@ */ package org.sonar.db.component; +import java.util.List; import org.apache.commons.lang.StringUtils; import org.apache.ibatis.session.ResultContext; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.SqlSession; import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Scopes; +import org.sonar.api.utils.System2; +import org.sonar.db.AbstractDao; import org.sonar.db.DbSession; import org.sonar.db.MyBatis; -public class ResourceIndexerDao { +public class ResourceIndexerDao extends AbstractDao { private static final String SELECT_RESOURCES = "org.sonar.db.component.ResourceIndexerMapper.selectResources"; public static final int MINIMUM_KEY_SIZE = 3; @@ -41,17 +44,19 @@ public class ResourceIndexerDao { private static final String[] NOT_RENAMABLE_QUALIFIERS = {Qualifiers.FILE, Qualifiers.UNIT_TEST_FILE, Qualifiers.CLASS}; private static final String[] NOT_RENAMABLE_SCOPES = {Scopes.FILE}; - private final MyBatis mybatis; + public ResourceIndexerDao(MyBatis myBatis, System2 system2) { + super(myBatis, system2); + } - public ResourceIndexerDao(MyBatis mybatis) { - this.mybatis = mybatis; + public List<Long> selectProjectIdsFromQueryAndViewOrSubViewUuid(DbSession session, String query, String viewOrSubViewUuid) { + return session.getMapper(ResourceIndexerMapper.class).selectProjectIdsFromQueryAndViewOrSubViewUuid(query + "%", "%." + viewOrSubViewUuid + ".%"); } /** * This method is reentrant. It can be executed even if the project is already indexed. */ public ResourceIndexerDao indexProject(final long rootProjectId) { - DbSession session = mybatis.openSession(true); + DbSession session = myBatis().openSession(true); try { indexProject(rootProjectId, session); session.commit(); @@ -71,7 +76,7 @@ public class ResourceIndexerDao { * This method is reentrant. It can be executed even if some projects are already indexed. */ public ResourceIndexerDao indexProjects() { - final DbSession session = mybatis.openSession(true); + final DbSession session = myBatis().openSession(true); try { final ResourceIndexerMapper mapper = session.getMapper(ResourceIndexerMapper.class); session.select("org.sonar.db.component.ResourceIndexerMapper.selectRootProjectIds", /* workaround to get booleans */ResourceIndexerQuery.create(), new ResultHandler() { @@ -132,7 +137,7 @@ public class ResourceIndexerDao { } public boolean indexResource(long id) { - DbSession session = mybatis.openSession(false); + DbSession session = myBatis().openSession(false); try { return indexResource(session, id); } finally { @@ -156,7 +161,7 @@ public class ResourceIndexerDao { public boolean indexResource(int id, String name, String qualifier, int rootId) { boolean indexed = false; - SqlSession session = mybatis.openSession(false); + SqlSession session = myBatis().openSession(false); ResourceIndexerMapper mapper = session.getMapper(ResourceIndexerMapper.class); try { indexed = indexResource(id, name, qualifier, rootId, session, mapper); diff --git a/sonar-db/src/main/java/org/sonar/db/component/ResourceIndexerMapper.java b/sonar-db/src/main/java/org/sonar/db/component/ResourceIndexerMapper.java index ecbacc7da82..a0cb17b2ccf 100644 --- a/sonar-db/src/main/java/org/sonar/db/component/ResourceIndexerMapper.java +++ b/sonar-db/src/main/java/org/sonar/db/component/ResourceIndexerMapper.java @@ -19,8 +19,13 @@ */ package org.sonar.db.component; +import java.util.List; +import org.apache.ibatis.annotations.Param; + public interface ResourceIndexerMapper { + List<Long> selectProjectIdsFromQueryAndViewOrSubViewUuid(@Param("query") String query, @Param("viewUuidQuery") String viewUuidQuery); + ResourceIndexDto selectMasterIndexByResourceId(long resourceId); ResourceDto selectResourceToIndex(long resourceId); diff --git a/sonar-db/src/main/java/org/sonar/db/component/ResourceKeyUpdaterDao.java b/sonar-db/src/main/java/org/sonar/db/component/ResourceKeyUpdaterDao.java index 6441c88df37..78217f48edd 100644 --- a/sonar-db/src/main/java/org/sonar/db/component/ResourceKeyUpdaterDao.java +++ b/sonar-db/src/main/java/org/sonar/db/component/ResourceKeyUpdaterDao.java @@ -28,6 +28,7 @@ import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.apache.ibatis.session.SqlSession; +import org.sonar.db.Dao; import org.sonar.db.DbSession; import org.sonar.db.MyBatis; @@ -36,7 +37,7 @@ import org.sonar.db.MyBatis; * * @since 3.2 */ -public class ResourceKeyUpdaterDao { +public class ResourceKeyUpdaterDao implements Dao { private MyBatis mybatis; public ResourceKeyUpdaterDao(MyBatis mybatis) { diff --git a/sonar-db/src/main/java/org/sonar/db/component/SnapshotDao.java b/sonar-db/src/main/java/org/sonar/db/component/SnapshotDao.java new file mode 100644 index 00000000000..d23eeb5a934 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/component/SnapshotDao.java @@ -0,0 +1,107 @@ +/* + * 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.db.component; + +import com.google.common.base.Strings; +import com.google.common.collect.Lists; +import java.util.Collection; +import java.util.List; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import org.sonar.api.resources.Scopes; +import org.sonar.db.Dao; +import org.sonar.db.DbSession; + +public class SnapshotDao implements Dao { + + @CheckForNull + public SnapshotDto selectNullableById(DbSession session, long id) { + return mapper(session).selectByKey(id); + } + + public SnapshotDto selectById(DbSession session, long id) { + SnapshotDto value = selectNullableById(session, id); + if (value == null) { + throw new IllegalArgumentException(String.format("Snapshot id does not exist: %d", id)); + } + return value; + } + + @CheckForNull + public SnapshotDto selectLastSnapshotByComponentId(DbSession session, long componentId) { + return mapper(session).selectLastSnapshot(componentId); + } + + public List<SnapshotDto> selectSnapshotsByComponentId(DbSession session, long componentId) { + return mapper(session).selectSnapshotsByQuery(new SnapshotQuery().setComponentId(componentId)); + } + + public List<SnapshotDto> selectSnapshotsByQuery(DbSession session, SnapshotQuery query) { + return mapper(session).selectSnapshotsByQuery(query); + } + + public List<SnapshotDto> selectPreviousVersionSnapshots(DbSession session, long componentId, String lastVersion) { + return mapper(session).selectPreviousVersionSnapshots(componentId, lastVersion); + } + + public List<SnapshotDto> selectSnapshotAndChildrenOfProjectScope(DbSession session, long snapshotId) { + return mapper(session).selectSnapshotAndChildrenOfScope(snapshotId, Scopes.PROJECT); + } + + public int updateSnapshotAndChildrenLastFlagAndStatus(DbSession session, SnapshotDto snapshot, boolean isLast, String status) { + Long rootId = snapshot.getId(); + String path = Strings.nullToEmpty(snapshot.getPath()) + snapshot.getId() + ".%"; + Long pathRootId = snapshot.getRootIdOrSelf(); + + return mapper(session).updateSnapshotAndChildrenLastFlagAndStatus(rootId, pathRootId, path, isLast, status); + } + + public int updateSnapshotAndChildrenLastFlag(DbSession session, SnapshotDto snapshot, boolean isLast) { + Long rootId = snapshot.getId(); + String path = Strings.nullToEmpty(snapshot.getPath()) + snapshot.getId() + ".%"; + Long pathRootId = snapshot.getRootIdOrSelf(); + + return mapper(session).updateSnapshotAndChildrenLastFlag(rootId, pathRootId, path, isLast); + } + + public static boolean isLast(SnapshotDto snapshotTested, @Nullable SnapshotDto previousLastSnapshot) { + return previousLastSnapshot == null || previousLastSnapshot.getCreatedAt() < snapshotTested.getCreatedAt(); + } + + public SnapshotDto insert(DbSession session, SnapshotDto item) { + mapper(session).insert(item); + return item; + } + + public void insert(DbSession session, Collection<SnapshotDto> items) { + for (SnapshotDto item : items) { + insert(session, item); + } + } + + public void insert(DbSession session, SnapshotDto item, SnapshotDto... others) { + insert(session, Lists.asList(item, others)); + } + + private SnapshotMapper mapper(DbSession session) { + return session.getMapper(SnapshotMapper.class); + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/compute/AnalysisReportDao.java b/sonar-db/src/main/java/org/sonar/db/compute/AnalysisReportDao.java new file mode 100644 index 00000000000..d805044aae6 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/compute/AnalysisReportDao.java @@ -0,0 +1,107 @@ +/* + * 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.db.compute; + +import com.google.common.annotations.VisibleForTesting; +import org.sonar.api.utils.System2; +import org.sonar.db.compute.AnalysisReportDto; +import org.sonar.db.compute.AnalysisReportMapper; +import org.sonar.db.Dao; +import org.sonar.db.DbSession; + +import javax.annotation.CheckForNull; + +import java.util.List; + +import static org.sonar.db.compute.AnalysisReportDto.Status.PENDING; +import static org.sonar.db.compute.AnalysisReportDto.Status.WORKING; + +public class AnalysisReportDao implements Dao { + + private System2 system2; + + public AnalysisReportDao(System2 system2) { + this.system2 = system2; + } + + /** + * Update all rows with: STATUS='PENDING', STARTED_AT=NULL, UPDATED_AT={now} + */ + public void resetAllToPendingStatus(DbSession session) { + mapper(session).resetAllToPendingStatus(system2.now()); + } + + public void truncate(DbSession session) { + mapper(session).truncate(); + } + + public List<AnalysisReportDto> selectByProjectKey(DbSession session, String projectKey) { + return mapper(session).selectByProjectKey(projectKey); + } + + @VisibleForTesting + AnalysisReportDto selectById(DbSession session, long id) { + return mapper(session).selectById(id); + } + + @CheckForNull + public AnalysisReportDto pop(DbSession session) { + List<Long> reportIds = mapper(session).selectAvailables(PENDING, WORKING); + if (reportIds.isEmpty()) { + return null; + } + + long reportId = reportIds.get(0); + return tryToPop(session, reportId); + } + + @VisibleForTesting + AnalysisReportDto tryToPop(DbSession session, long reportId) { + AnalysisReportMapper mapper = mapper(session); + int nbOfReportBooked = mapper.updateWithBookingReport(reportId, system2.now(), PENDING, WORKING); + if (nbOfReportBooked == 0) { + return null; + } + + AnalysisReportDto result = mapper.selectById(reportId); + session.commit(); + return result; + } + + public List<AnalysisReportDto> selectAll(DbSession session) { + return mapper(session).selectAll(); + } + + public AnalysisReportDto insert(DbSession session, AnalysisReportDto report) { + report.setCreatedAt(system2.now()); + report.setUpdatedAt(system2.now()); + mapper(session).insert(report); + return report; + } + + public void delete(DbSession session, long id) { + mapper(session).delete(id); + } + + private AnalysisReportMapper mapper(DbSession session) { + return session.getMapper(AnalysisReportMapper.class); + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/dashboard/ActiveDashboardDao.java b/sonar-db/src/main/java/org/sonar/db/dashboard/ActiveDashboardDao.java index 8463da58cfa..c29f495047e 100644 --- a/sonar-db/src/main/java/org/sonar/db/dashboard/ActiveDashboardDao.java +++ b/sonar-db/src/main/java/org/sonar/db/dashboard/ActiveDashboardDao.java @@ -22,11 +22,9 @@ package org.sonar.db.dashboard; import java.util.List; import javax.annotation.Nullable; import org.apache.ibatis.session.SqlSession; -import org.sonar.api.server.ServerSide; import org.sonar.db.Dao; import org.sonar.db.MyBatis; -@ServerSide public class ActiveDashboardDao implements Dao { private MyBatis mybatis; diff --git a/sonar-db/src/main/java/org/sonar/db/dashboard/DashboardDao.java b/sonar-db/src/main/java/org/sonar/db/dashboard/DashboardDao.java index 40b151e7ec9..4462c1c24c8 100644 --- a/sonar-db/src/main/java/org/sonar/db/dashboard/DashboardDao.java +++ b/sonar-db/src/main/java/org/sonar/db/dashboard/DashboardDao.java @@ -19,8 +19,11 @@ */ package org.sonar.db.dashboard; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import org.apache.ibatis.session.SqlSession; import org.sonar.db.Dao; +import org.sonar.db.DbSession; import org.sonar.db.MyBatis; public class DashboardDao implements Dao { @@ -62,4 +65,21 @@ public class DashboardDao implements Dao { } } + @CheckForNull + public DashboardDto getNullableByKey(DbSession session, Long key) { + return mapper(session).selectById(key); + } + + /** + * Get dashboard if allowed : shared or owned by logged-in user + * @param userId id of logged-in user, null if anonymous + */ + @CheckForNull + public DashboardDto getAllowedByKey(DbSession session, Long key, @Nullable Long userId) { + return mapper(session).selectAllowedById(key, userId != null ? userId : -1L); + } + + private DashboardMapper mapper(DbSession session) { + return session.getMapper(DashboardMapper.class); + } } diff --git a/sonar-db/src/main/java/org/sonar/db/dashboard/WidgetDao.java b/sonar-db/src/main/java/org/sonar/db/dashboard/WidgetDao.java new file mode 100644 index 00000000000..dec981655e0 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/dashboard/WidgetDao.java @@ -0,0 +1,76 @@ +/* + * 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.db.dashboard; + +import java.util.Collection; +import org.sonar.db.dashboard.WidgetDto; +import org.sonar.db.dashboard.WidgetMapper; +import org.sonar.db.Dao; +import org.sonar.db.DbSession; +import org.sonar.db.MyBatis; + +public class WidgetDao implements Dao { + + private MyBatis myBatis; + + public WidgetDao(MyBatis myBatis) { + this.myBatis = myBatis; + } + + public WidgetDto getNullableByKey(Long widgetId) { + DbSession session = myBatis.openSession(false); + try { + return getNullableByKey(session, widgetId); + } finally { + MyBatis.closeQuietly(session); + } + } + + public WidgetDto getNullableByKey(DbSession session, Long widgetId) { + return mapper(session).selectById(widgetId); + } + + public WidgetDto update(WidgetDto item) { + DbSession session = myBatis.openSession(false); + try { + return update(session, item); + } finally { + MyBatis.closeQuietly(session); + } + } + + public WidgetDto update(DbSession session, WidgetDto item) { + mapper(session).update(item); + return item; + } + + public Collection<WidgetDto> findByDashboard(DbSession session, long dashboardKey) { + return mapper(session).selectByDashboard(dashboardKey); + } + + public Collection<WidgetDto> findAll(DbSession session) { + return mapper(session).selectAll(); + } + + private WidgetMapper mapper(DbSession session) { + return session.getMapper(WidgetMapper.class); + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/dashboard/WidgetPropertyDao.java b/sonar-db/src/main/java/org/sonar/db/dashboard/WidgetPropertyDao.java new file mode 100644 index 00000000000..0102d3338a0 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/dashboard/WidgetPropertyDao.java @@ -0,0 +1,90 @@ +/* + * 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.db.dashboard; + +import com.google.common.base.Function; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import org.sonar.db.Dao; +import org.sonar.db.DaoUtils; +import org.sonar.db.DatabaseUtils; +import org.sonar.db.DbSession; +import org.sonar.db.MyBatis; + +public class WidgetPropertyDao implements Dao { + + private final MyBatis myBatis; + + public WidgetPropertyDao(MyBatis myBatis) { + this.myBatis = myBatis; + } + + public WidgetPropertyDto insert(WidgetPropertyDto item) { + DbSession session = myBatis.openSession(false); + try { + return insert(session, item); + } finally { + MyBatis.closeQuietly(session); + } + } + + public WidgetPropertyDto insert(DbSession session, WidgetPropertyDto item) { + mapper(session).insert(item); + return item; + } + + public void insert(DbSession session, Collection<WidgetPropertyDto> items) { + for (WidgetPropertyDto item : items) { + insert(session, item); + } + } + + public WidgetPropertyDto getNullableByKey(Long propertyId) { + DbSession session = myBatis.openSession(false); + try { + return getNullableByKey(session, propertyId); + } finally { + MyBatis.closeQuietly(session); + } + } + + public WidgetPropertyDto getNullableByKey(DbSession session, Long propertyId) { + return mapper(session).selectById(propertyId); + } + + public Collection<WidgetPropertyDto> findByDashboard(DbSession session, long dashboardKey) { + return mapper(session).selectByDashboard(dashboardKey); + } + + public void deleteByWidgetIds(final DbSession session, List<Long> widgetIdsWithPropertiesToDelete) { + DatabaseUtils.executeLargeInputs(widgetIdsWithPropertiesToDelete, new Function<List<Long>, List<Void>>() { + @Override + public List<Void> apply(List<Long> input) { + mapper(session).deleteByWidgetIds(input); + return Arrays.asList(); + } + }); + } + + private WidgetPropertyMapper mapper(DbSession session) { + return session.getMapper(WidgetPropertyMapper.class); + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/duplication/DuplicationDao.java b/sonar-db/src/main/java/org/sonar/db/duplication/DuplicationDao.java index 25690f35569..94d7ef81c73 100644 --- a/sonar-db/src/main/java/org/sonar/db/duplication/DuplicationDao.java +++ b/sonar-db/src/main/java/org/sonar/db/duplication/DuplicationDao.java @@ -22,10 +22,11 @@ package org.sonar.db.duplication; import java.util.Collection; import java.util.List; import org.apache.ibatis.session.SqlSession; +import org.sonar.db.Dao; import org.sonar.db.DbSession; import org.sonar.db.MyBatis; -public class DuplicationDao { +public class DuplicationDao implements Dao { private final MyBatis mybatis; diff --git a/sonar-db/src/main/java/org/sonar/batch/index/ResourceCopy.java b/sonar-db/src/main/java/org/sonar/db/event/EventDao.java index 6a3ccd83029..0f58097ab35 100644 --- a/sonar-db/src/main/java/org/sonar/batch/index/ResourceCopy.java +++ b/sonar-db/src/main/java/org/sonar/db/event/EventDao.java @@ -17,13 +17,25 @@ * 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.batch.index; -/** - * Used by views !! - */ -public interface ResourceCopy { +package org.sonar.db.event; + +import java.util.List; +import org.sonar.db.Dao; +import org.sonar.db.DbSession; + +public class EventDao implements Dao { + + 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); + } - int getCopyResourceId(); + public void delete(DbSession session, Long id) { + session.getMapper(EventMapper.class).delete(id); + } } diff --git a/sonar-db/src/main/java/org/sonar/db/issue/ActionPlanDao.java b/sonar-db/src/main/java/org/sonar/db/issue/ActionPlanDao.java index bb63a3c9b90..5c061ad2407 100644 --- a/sonar-db/src/main/java/org/sonar/db/issue/ActionPlanDao.java +++ b/sonar-db/src/main/java/org/sonar/db/issue/ActionPlanDao.java @@ -25,13 +25,11 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import org.apache.ibatis.session.SqlSession; -import org.sonar.api.server.ServerSide; import org.sonar.db.Dao; import org.sonar.db.MyBatis; import static com.google.common.collect.Lists.newArrayList; -@ServerSide public class ActionPlanDao implements Dao { private final MyBatis mybatis; diff --git a/sonar-db/src/main/java/org/sonar/db/issue/ActionPlanStatsDao.java b/sonar-db/src/main/java/org/sonar/db/issue/ActionPlanStatsDao.java index dfd4192922b..4d653374b5c 100644 --- a/sonar-db/src/main/java/org/sonar/db/issue/ActionPlanStatsDao.java +++ b/sonar-db/src/main/java/org/sonar/db/issue/ActionPlanStatsDao.java @@ -22,18 +22,18 @@ package org.sonar.db.issue; import java.util.List; import org.apache.ibatis.session.SqlSession; +import org.sonar.api.utils.System2; +import org.sonar.db.AbstractDao; import org.sonar.db.MyBatis; -public class ActionPlanStatsDao { +public class ActionPlanStatsDao extends AbstractDao { - private final MyBatis mybatis; - - public ActionPlanStatsDao(MyBatis mybatis) { - this.mybatis = mybatis; + public ActionPlanStatsDao(MyBatis myBatis, System2 system2) { + super(myBatis, system2); } public List<ActionPlanStatsDto> findByProjectId(Long projectId) { - SqlSession session = mybatis.openSession(false); + SqlSession session = myBatis().openSession(false); try { return session.getMapper(ActionPlanStatsMapper.class).findByProjectId(projectId); } finally { diff --git a/sonar-db/src/main/java/org/sonar/db/issue/IssueDao.java b/sonar-db/src/main/java/org/sonar/db/issue/IssueDao.java index edc89f9c267..cecd0fe0f08 100644 --- a/sonar-db/src/main/java/org/sonar/db/issue/IssueDao.java +++ b/sonar-db/src/main/java/org/sonar/db/issue/IssueDao.java @@ -20,12 +20,16 @@ package org.sonar.db.issue; +import java.util.List; +import java.util.Set; +import javax.annotation.CheckForNull; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.SqlSession; +import org.sonar.db.Dao; import org.sonar.db.DbSession; import org.sonar.db.MyBatis; -public class IssueDao { +public class IssueDao implements Dao { private final MyBatis mybatis; @@ -43,7 +47,48 @@ public class IssueDao { } } - protected IssueMapper mapper(DbSession session) { + @CheckForNull + public IssueDto selectNullableByKey(DbSession session, String key) { + return mapper(session).selectByKey(key); + } + + public IssueDto selectByKey(DbSession session, String key) { + IssueDto issue = selectNullableByKey(session, key); + if (issue == null) { + throw new IllegalArgumentException(String.format("Issue key '%s' does not exist", key)); + } + return issue; + } + + public List<IssueDto> findByActionPlan(DbSession session, String actionPlan) { + return mapper(session).selectByActionPlan(actionPlan); + } + + public List<IssueDto> selectByKeys(DbSession session, List<String> keys) { + return mapper(session).selectByKeys(keys); + } + + public Set<String> selectComponentUuidsOfOpenIssuesForProjectUuid(DbSession session, String projectUuid) { + return mapper(session).selectComponentUuidsOfOpenIssuesForProjectUuid(projectUuid); + } + + public void insert(DbSession session, IssueDto dto) { + mapper(session).insert(dto); + } + + public void insert(DbSession session, IssueDto dto, IssueDto... others) { + IssueMapper mapper = mapper(session); + mapper.insert(dto); + for (IssueDto other : others) { + mapper.insert(other); + } + } + + public void update(DbSession session, IssueDto dto) { + mapper(session).update(dto); + } + + private IssueMapper mapper(DbSession session) { return session.getMapper(IssueMapper.class); } diff --git a/sonar-db/src/main/java/org/sonar/db/issue/IssueFilterFavouriteDao.java b/sonar-db/src/main/java/org/sonar/db/issue/IssueFilterFavouriteDao.java index f9de1a19963..7f1f06ce324 100644 --- a/sonar-db/src/main/java/org/sonar/db/issue/IssueFilterFavouriteDao.java +++ b/sonar-db/src/main/java/org/sonar/db/issue/IssueFilterFavouriteDao.java @@ -22,9 +22,10 @@ package org.sonar.db.issue; import java.util.List; import org.apache.ibatis.session.SqlSession; +import org.sonar.db.Dao; import org.sonar.db.MyBatis; -public class IssueFilterFavouriteDao { +public class IssueFilterFavouriteDao implements Dao { private final MyBatis mybatis; diff --git a/sonar-db/src/main/java/org/sonar/db/measure/MeasureDao.java b/sonar-db/src/main/java/org/sonar/db/measure/MeasureDao.java new file mode 100644 index 00000000000..ff4b710d9ca --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/measure/MeasureDao.java @@ -0,0 +1,87 @@ +/* + * 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.db.measure; + +import com.google.common.base.Function; +import com.google.common.collect.Lists; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import javax.annotation.CheckForNull; +import org.sonar.db.Dao; +import org.sonar.db.DaoUtils; +import org.sonar.db.DatabaseUtils; +import org.sonar.db.DbSession; +import org.sonar.db.component.SnapshotDto; + +public class MeasureDao implements Dao { + + public boolean existsByKey(DbSession session, String componentKey, String metricKey) { + return mapper(session).countByComponentAndMetric(componentKey, metricKey) > 0; + } + + @CheckForNull + public MeasureDto findByComponentKeyAndMetricKey(DbSession session, String componentKey, String metricKey) { + return mapper(session).selectByComponentAndMetric(componentKey, metricKey); + } + + public List<MeasureDto> findByComponentKeyAndMetricKeys(final DbSession session, final String componentKey, List<String> metricKeys) { + return DatabaseUtils.executeLargeInputs(metricKeys, new Function<List<String>, List<MeasureDto>>() { + @Override + public List<MeasureDto> apply(List<String> keys) { + return mapper(session).selectByComponentAndMetrics(componentKey, keys); + } + }); + } + + public List<PastMeasureDto> selectByComponentUuidAndProjectSnapshotIdAndMetricIds(final DbSession session, final String componentUuid, final long projectSnapshotId, + Set<Integer> metricIds) { + return DatabaseUtils.executeLargeInputs(metricIds, new Function<List<Integer>, List<PastMeasureDto>>() { + @Override + public List<PastMeasureDto> apply(List<Integer> ids) { + return mapper(session).selectByComponentUuidAndProjectSnapshotIdAndStatusAndMetricIds(componentUuid, projectSnapshotId, ids, + SnapshotDto.STATUS_PROCESSED); + } + }); + } + + public void insert(DbSession session, MeasureDto measureDto) { + mapper(session).insert(measureDto); + } + + public void insert(DbSession session, Collection<MeasureDto> items) { + for (MeasureDto item : items) { + insert(session, item); + } + } + + public void insert(DbSession session, MeasureDto item, MeasureDto... others) { + insert(session, Lists.asList(item, others)); + } + + public List<String> selectMetricKeysForSnapshot(DbSession session, long snapshotId) { + return mapper(session).selectMetricKeysForSnapshot(snapshotId); + } + + private MeasureMapper mapper(DbSession session) { + return session.getMapper(MeasureMapper.class); + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/measure/MeasureFilterDao.java b/sonar-db/src/main/java/org/sonar/db/measure/MeasureFilterDao.java index 50d0bad2f53..8b5981caa45 100644 --- a/sonar-db/src/main/java/org/sonar/db/measure/MeasureFilterDao.java +++ b/sonar-db/src/main/java/org/sonar/db/measure/MeasureFilterDao.java @@ -20,9 +20,10 @@ package org.sonar.db.measure; import org.apache.ibatis.session.SqlSession; +import org.sonar.db.Dao; import org.sonar.db.MyBatis; -public class MeasureFilterDao { +public class MeasureFilterDao implements Dao { private MyBatis mybatis; public MeasureFilterDao(MyBatis mybatis) { diff --git a/sonar-db/src/main/java/org/sonar/db/notification/NotificationQueueDao.java b/sonar-db/src/main/java/org/sonar/db/notification/NotificationQueueDao.java index b82ba01dd09..6fc69f7818e 100644 --- a/sonar-db/src/main/java/org/sonar/db/notification/NotificationQueueDao.java +++ b/sonar-db/src/main/java/org/sonar/db/notification/NotificationQueueDao.java @@ -23,10 +23,11 @@ package org.sonar.db.notification; import java.util.Collections; import java.util.List; import org.apache.ibatis.session.SqlSession; +import org.sonar.db.Dao; import org.sonar.db.DbSession; import org.sonar.db.MyBatis; -public class NotificationQueueDao { +public class NotificationQueueDao implements Dao { private final MyBatis mybatis; diff --git a/sonar-db/src/main/java/org/sonar/db/permission/PermissionDao.java b/sonar-db/src/main/java/org/sonar/db/permission/PermissionDao.java index e6a1508e222..e18bdbbcb57 100644 --- a/sonar-db/src/main/java/org/sonar/db/permission/PermissionDao.java +++ b/sonar-db/src/main/java/org/sonar/db/permission/PermissionDao.java @@ -27,13 +27,12 @@ import javax.annotation.Nullable; import org.apache.ibatis.session.RowBounds; import org.apache.ibatis.session.SqlSession; import org.sonar.api.security.DefaultGroups; -import org.sonar.api.server.ServerSide; +import org.sonar.db.Dao; import org.sonar.db.MyBatis; import static com.google.common.collect.Maps.newHashMap; -@ServerSide -public class PermissionDao { +public class PermissionDao implements Dao { private static final String QUERY_PARAMETER = "query"; private static final String COMPONENT_ID_PARAMETER = "componentId"; diff --git a/sonar-db/src/main/java/org/sonar/db/property/PropertiesDao.java b/sonar-db/src/main/java/org/sonar/db/property/PropertiesDao.java index cb1a63adbe3..c69532dc8ea 100644 --- a/sonar-db/src/main/java/org/sonar/db/property/PropertiesDao.java +++ b/sonar-db/src/main/java/org/sonar/db/property/PropertiesDao.java @@ -36,6 +36,7 @@ import org.apache.ibatis.session.SqlSession; import org.sonar.api.resources.Scopes; import org.sonar.db.Dao; import org.sonar.db.DaoUtils; +import org.sonar.db.DatabaseUtils; import org.sonar.db.DbSession; import org.sonar.db.MyBatis; @@ -83,7 +84,7 @@ public class PropertiesDao implements Dao { String sql = "SELECT count(*) FROM properties pp " + "left outer join projects pj on pp.resource_id = pj.id " + "where pp.user_id is not null and (pp.resource_id is null or pj.uuid=?) " + - "and (" + DaoUtils.repeatCondition("pp.prop_key like ?", dispatcherKeys.size(), "or") + ")"; + "and (" + DatabaseUtils.repeatCondition("pp.prop_key like ?", dispatcherKeys.size(), "or") + ")"; try { pstmt = connection.prepareStatement(sql); pstmt.setString(1, projectUuid); diff --git a/sonar-db/src/main/java/org/sonar/db/purge/PurgeDao.java b/sonar-db/src/main/java/org/sonar/db/purge/PurgeDao.java index a06767ab51c..f4ddf2478b6 100644 --- a/sonar-db/src/main/java/org/sonar/db/purge/PurgeDao.java +++ b/sonar-db/src/main/java/org/sonar/db/purge/PurgeDao.java @@ -48,19 +48,17 @@ public class PurgeDao implements Dao { private final MyBatis mybatis; private final ResourceDao resourceDao; private final System2 system2; - private final PurgeProfiler profiler; - public PurgeDao(MyBatis mybatis, ResourceDao resourceDao, PurgeProfiler profiler, System2 system2) { + public PurgeDao(MyBatis mybatis, ResourceDao resourceDao, System2 system2) { this.mybatis = mybatis; this.resourceDao = resourceDao; - this.profiler = profiler; this.system2 = system2; } - public PurgeDao purge(PurgeConfiguration conf, PurgeListener purgeListener) { + public PurgeDao purge(PurgeConfiguration conf, PurgeListener listener, PurgeProfiler profiler) { DbSession session = mybatis.openSession(true); try { - purge(session, conf, purgeListener); + purge(session, conf, listener, profiler); session.commit(); } finally { MyBatis.closeQuietly(session); @@ -68,7 +66,7 @@ public class PurgeDao implements Dao { return this; } - public void purge(DbSession session, PurgeConfiguration conf, PurgeListener purgeListener) { + public void purge(DbSession session, PurgeConfiguration conf, PurgeListener listener, PurgeProfiler profiler) { PurgeMapper mapper = session.getMapper(PurgeMapper.class); PurgeCommands commands = new PurgeCommands(session, mapper, profiler); List<ResourceDto> projects = getProjects(conf.rootProjectIdUuid().getId(), session); @@ -78,7 +76,7 @@ public class PurgeDao implements Dao { purge(project, conf.scopesWithoutHistoricalData(), commands); } for (ResourceDto project : projects) { - disableOrphanResources(project, session, mapper, purgeListener); + disableOrphanResources(project, session, mapper, listener); } deleteOldClosedIssues(conf, mapper); } @@ -171,16 +169,16 @@ public class PurgeDao implements Dao { return result; } - public PurgeDao deleteResourceTree(IdUuidPair rootIdUuid) { + public PurgeDao deleteResourceTree(IdUuidPair rootIdUuid, PurgeProfiler profiler) { DbSession session = mybatis.openSession(true); try { - return deleteResourceTree(session, rootIdUuid); + return deleteResourceTree(session, rootIdUuid, profiler); } finally { MyBatis.closeQuietly(session); } } - public PurgeDao deleteResourceTree(DbSession session, IdUuidPair rootIdUuid) { + public PurgeDao deleteResourceTree(DbSession session, IdUuidPair rootIdUuid, PurgeProfiler profiler) { deleteProject(rootIdUuid, mapper(session), new PurgeCommands(session, profiler)); deleteFileSources(rootIdUuid.getUuid(), new PurgeCommands(session, profiler)); return this; @@ -209,17 +207,17 @@ public class PurgeDao implements Dao { mapper.resolveResourceIssuesNotAlreadyResolved(componentIdUuid.getUuid(), system2.now()); } - public PurgeDao deleteSnapshots(PurgeSnapshotQuery query) { + public PurgeDao deleteSnapshots(PurgeSnapshotQuery query, PurgeProfiler profiler) { final DbSession session = mybatis.openSession(true); try { - return deleteSnapshots(query, session); + return deleteSnapshots(query, session, profiler); } finally { MyBatis.closeQuietly(session); } } - public PurgeDao deleteSnapshots(PurgeSnapshotQuery query, final DbSession session) { + public PurgeDao deleteSnapshots(PurgeSnapshotQuery query, DbSession session, PurgeProfiler profiler) { new PurgeCommands(session, profiler).deleteSnapshots(query); return this; } diff --git a/sonar-db/src/main/java/org/sonar/db/purge/period/DefaultPeriodCleaner.java b/sonar-db/src/main/java/org/sonar/db/purge/period/DefaultPeriodCleaner.java index ac7bad54d1a..35c03578122 100644 --- a/sonar-db/src/main/java/org/sonar/db/purge/period/DefaultPeriodCleaner.java +++ b/sonar-db/src/main/java/org/sonar/db/purge/period/DefaultPeriodCleaner.java @@ -29,6 +29,7 @@ import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.db.DbSession; import org.sonar.db.purge.PurgeDao; +import org.sonar.db.purge.PurgeProfiler; import org.sonar.db.purge.PurgeSnapshotQuery; import org.sonar.db.purge.PurgeableSnapshotDto; @@ -36,10 +37,12 @@ import org.sonar.db.purge.PurgeableSnapshotDto; public class DefaultPeriodCleaner { private static final Logger LOG = Loggers.get(DefaultPeriodCleaner.class); - private PurgeDao purgeDao; + private final PurgeDao purgeDao; + private final PurgeProfiler profiler; - public DefaultPeriodCleaner(PurgeDao purgeDao) { + public DefaultPeriodCleaner(PurgeDao purgeDao, PurgeProfiler profiler) { this.purgeDao = purgeDao; + this.profiler = profiler; } public void clean(DbSession session, long projectId, Settings settings) { @@ -58,8 +61,8 @@ public class DefaultPeriodCleaner { private void delete(List<PurgeableSnapshotDto> snapshots, DbSession session) { for (PurgeableSnapshotDto snapshot : snapshots) { LOG.debug("<- Delete snapshot: {} [{}]", DateUtils.formatDateTime(snapshot.getDate()), snapshot.getSnapshotId()); - purgeDao.deleteSnapshots(PurgeSnapshotQuery.create().setRootSnapshotId(snapshot.getSnapshotId()), session); - purgeDao.deleteSnapshots(PurgeSnapshotQuery.create().setId(snapshot.getSnapshotId()), session); + purgeDao.deleteSnapshots(PurgeSnapshotQuery.create().setRootSnapshotId(snapshot.getSnapshotId()), session, profiler); + purgeDao.deleteSnapshots(PurgeSnapshotQuery.create().setId(snapshot.getSnapshotId()), session, profiler); } } diff --git a/sonar-db/src/main/java/org/sonar/db/qualityprofile/ActiveRuleDao.java b/sonar-db/src/main/java/org/sonar/db/qualityprofile/ActiveRuleDao.java deleted file mode 100644 index 24efe187dd7..00000000000 --- a/sonar-db/src/main/java/org/sonar/db/qualityprofile/ActiveRuleDao.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package org.sonar.db.qualityprofile; - -import java.util.List; -import org.apache.ibatis.session.SqlSession; -import org.sonar.api.server.ServerSide; -import org.sonar.db.DbSession; -import org.sonar.db.MyBatis; - -/** - * @deprecated use the ActiveRuleDao class defined in sonar-server - */ -@Deprecated -@ServerSide -public class ActiveRuleDao { - - private final MyBatis mybatis; - - public ActiveRuleDao(MyBatis mybatis) { - this.mybatis = mybatis; - } - - public void insert(ActiveRuleDto dto, SqlSession session) { - session.getMapper(ActiveRuleMapper.class).insert(dto); - } - - public List<ActiveRuleDto> selectByProfileKey(String profileKey) { - DbSession session = mybatis.openSession(false); - try { - return session.getMapper(ActiveRuleMapper.class).selectByProfileKey(profileKey); - } finally { - session.close(); - } - } - - public void insert(ActiveRuleParamDto dto, SqlSession session) { - session.getMapper(ActiveRuleMapper.class).insertParameter(dto); - } - - public List<ActiveRuleParamDto> selectParamsByProfileKey(String profileKey) { - DbSession session = mybatis.openSession(false); - try { - return session.getMapper(ActiveRuleMapper.class).selectParamsByProfileKey(profileKey); - } finally { - session.close(); - } - } -} diff --git a/sonar-db/src/main/java/org/sonar/db/rule/RuleDao.java b/sonar-db/src/main/java/org/sonar/db/rule/RuleDao.java index 25236bc2bcb..8991c688db6 100644 --- a/sonar-db/src/main/java/org/sonar/db/rule/RuleDao.java +++ b/sonar-db/src/main/java/org/sonar/db/rule/RuleDao.java @@ -21,13 +21,14 @@ package org.sonar.db.rule; import java.util.List; import org.apache.ibatis.session.SqlSession; +import org.sonar.db.Dao; import org.sonar.db.MyBatis; /** * @deprecated in 4.4 moved to org.sonar.server.rule.db.RuleDao. */ @Deprecated -public class RuleDao { +public class RuleDao implements Dao { private MyBatis mybatis; diff --git a/sonar-db/src/main/java/org/sonar/db/semaphore/SemaphoreDao.java b/sonar-db/src/main/java/org/sonar/db/semaphore/SemaphoreDao.java index c34a9b89542..59c89c738b1 100644 --- a/sonar-db/src/main/java/org/sonar/db/semaphore/SemaphoreDao.java +++ b/sonar-db/src/main/java/org/sonar/db/semaphore/SemaphoreDao.java @@ -24,15 +24,13 @@ import javax.annotation.CheckForNull; import org.apache.ibatis.session.SqlSession; import org.sonar.api.utils.Semaphores; import org.sonar.api.utils.System2; +import org.sonar.db.Dao; import org.sonar.db.MyBatis; import static com.google.common.base.Preconditions.checkArgument; import static org.sonar.api.utils.DateUtils.longToDate; -/** - * @since 3.4 - */ -public class SemaphoreDao { +public class SemaphoreDao implements Dao { private static final String SEMAPHORE_NAME_MUST_NOT_BE_EMPTY = "Semaphore name must not be empty"; private final MyBatis mybatis; diff --git a/sonar-db/src/main/java/org/sonar/db/source/FileSourceDao.java b/sonar-db/src/main/java/org/sonar/db/source/FileSourceDao.java new file mode 100644 index 00000000000..6aeb7d0742b --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/source/FileSourceDao.java @@ -0,0 +1,146 @@ +/* + * 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.db.source; + +import com.google.common.base.Function; +import com.google.common.base.Splitter; +import java.io.Reader; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import javax.annotation.CheckForNull; +import org.apache.commons.dbutils.DbUtils; +import org.apache.commons.io.IOUtils; +import org.sonar.db.Dao; +import org.sonar.db.DbSession; +import org.sonar.db.MyBatis; +import org.sonar.db.source.FileSourceDto.Type; + +public class FileSourceDao implements Dao { + + private static final Splitter END_OF_LINE_SPLITTER = Splitter.on('\n'); + private final MyBatis mybatis; + + public FileSourceDao(MyBatis myBatis) { + this.mybatis = myBatis; + } + + @CheckForNull + public FileSourceDto selectSource(String fileUuid) { + DbSession session = mybatis.openSession(false); + try { + return mapper(session).select(fileUuid, Type.SOURCE); + } finally { + MyBatis.closeQuietly(session); + } + } + + @CheckForNull + public FileSourceDto selectTest(String fileUuid) { + DbSession session = mybatis.openSession(false); + try { + return mapper(session).select(fileUuid, Type.TEST); + } finally { + MyBatis.closeQuietly(session); + } + } + + @CheckForNull + public List<String> selectLineHashes(DbSession dbSession, String fileUuid) { + Connection connection = dbSession.getConnection(); + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + pstmt = connection.prepareStatement("SELECT line_hashes FROM file_sources WHERE file_uuid=? AND data_type=?"); + pstmt.setString(1, fileUuid); + pstmt.setString(2, Type.SOURCE); + rs = pstmt.executeQuery(); + if (rs.next()) { + return END_OF_LINE_SPLITTER.splitToList(rs.getString(1)); + } + return null; + } catch (SQLException e) { + throw new IllegalStateException("Fail to read FILE_SOURCES.LINE_HASHES of file " + fileUuid, e); + } finally { + DbUtils.closeQuietly(connection, pstmt, rs); + } + } + + public <T> void readLineHashesStream(DbSession dbSession, String fileUuid, Function<Reader, T> function) { + Connection connection = dbSession.getConnection(); + PreparedStatement pstmt = null; + ResultSet rs = null; + Reader reader = null; + try { + pstmt = connection.prepareStatement("SELECT line_hashes FROM file_sources WHERE file_uuid=? AND data_type=?"); + pstmt.setString(1, fileUuid); + pstmt.setString(2, Type.SOURCE); + rs = pstmt.executeQuery(); + if (rs.next()) { + reader = rs.getCharacterStream(1); + function.apply(reader); + } + } catch (SQLException e) { + throw new IllegalStateException("Fail to read FILE_SOURCES.LINE_HASHES of file " + fileUuid, e); + } finally { + IOUtils.closeQuietly(reader); + DbUtils.closeQuietly(connection, pstmt, rs); + } + } + + public void insert(FileSourceDto dto) { + DbSession session = mybatis.openSession(false); + try { + insert(session, dto); + session.commit(); + } finally { + MyBatis.closeQuietly(session); + } + } + + public void insert(DbSession session, FileSourceDto dto) { + mapper(session).insert(dto); + } + + public void update(FileSourceDto dto) { + DbSession session = mybatis.openSession(false); + try { + update(session, dto); + session.commit(); + } finally { + MyBatis.closeQuietly(session); + } + } + + public void update(DbSession session, FileSourceDto dto) { + mapper(session).update(dto); + } + + public void updateDateWhenUpdatedDateIsZero(DbSession session, String projectUuid, long updateDate) { + mapper(session).updateDateWhenUpdatedDateIsZero(projectUuid, updateDate); + } + + private FileSourceMapper mapper(DbSession session) { + return session.getMapper(FileSourceMapper.class); + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/user/AuthorDao.java b/sonar-db/src/main/java/org/sonar/db/user/AuthorDao.java index 5837964ce82..56a4eb312fc 100644 --- a/sonar-db/src/main/java/org/sonar/db/user/AuthorDao.java +++ b/sonar-db/src/main/java/org/sonar/db/user/AuthorDao.java @@ -27,6 +27,7 @@ import java.util.List; import org.apache.ibatis.session.SqlSession; import org.sonar.db.Dao; import org.sonar.db.DaoUtils; +import org.sonar.db.DatabaseUtils; import org.sonar.db.MyBatis; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ResourceDao; @@ -112,7 +113,7 @@ public class AuthorDao implements Dao { } public List<String> selectScmAccountsByDeveloperUuids(final SqlSession session, Collection<String> developerUuids) { - return DaoUtils.executeLargeInputs(developerUuids, new Function<List<String>, List<String>>() { + return DatabaseUtils.executeLargeInputs(developerUuids, new Function<List<String>, List<String>>() { @Override public List<String> apply(List<String> partition) { return session.getMapper(AuthorMapper.class).selectScmAccountsByDeveloperUuids(partition); diff --git a/sonar-db/src/main/java/org/sonar/db/user/AuthorizationDao.java b/sonar-db/src/main/java/org/sonar/db/user/AuthorizationDao.java index 2a386c1d2b7..c4c8a118dce 100644 --- a/sonar-db/src/main/java/org/sonar/db/user/AuthorizationDao.java +++ b/sonar-db/src/main/java/org/sonar/db/user/AuthorizationDao.java @@ -30,6 +30,7 @@ import org.apache.ibatis.session.SqlSession; import org.sonar.api.server.ServerSide; import org.sonar.db.Dao; import org.sonar.db.DaoUtils; +import org.sonar.db.DatabaseUtils; import org.sonar.db.DbSession; import org.sonar.db.MyBatis; @@ -49,7 +50,7 @@ public class AuthorizationDao implements Dao { if (componentIds.isEmpty()) { return Collections.emptySet(); } - return DaoUtils.executeLargeInputs(componentIds, new Function<List<Long>, List<Long>>() { + return DatabaseUtils.executeLargeInputs(componentIds, new Function<List<Long>, List<Long>>() { @Override public List<Long> apply(List<Long> partition) { if (userId == null) { diff --git a/sonar-db/src/main/java/org/sonar/db/user/GroupMembershipDao.java b/sonar-db/src/main/java/org/sonar/db/user/GroupMembershipDao.java index a62609259b8..e27e6fe5d98 100644 --- a/sonar-db/src/main/java/org/sonar/db/user/GroupMembershipDao.java +++ b/sonar-db/src/main/java/org/sonar/db/user/GroupMembershipDao.java @@ -34,6 +34,7 @@ import org.apache.ibatis.session.RowBounds; import org.apache.ibatis.session.SqlSession; import org.sonar.db.Dao; import org.sonar.db.DaoUtils; +import org.sonar.db.DatabaseUtils; import org.sonar.db.DbSession; import org.sonar.db.MyBatis; @@ -77,7 +78,7 @@ public class GroupMembershipDao implements Dao { public Map<String, Integer> countUsersByGroups(final DbSession session, Collection<Long> groupIds) { final Map<String, Integer> result = Maps.newHashMap(); - DaoUtils.executeLargeInputs(groupIds, new Function<List<Long>, List<GroupUserCount>>() { + DatabaseUtils.executeLargeInputs(groupIds, new Function<List<Long>, List<GroupUserCount>>() { @Override public List<GroupUserCount> apply(@Nonnull List<Long> input) { List<GroupUserCount> userCounts = mapper(session).countUsersByGroup(input); @@ -93,7 +94,7 @@ public class GroupMembershipDao implements Dao { public Multimap<String, String> selectGroupsByLogins(final DbSession session, Collection<String> logins) { final Multimap<String, String> result = ArrayListMultimap.create(); - DaoUtils.executeLargeInputs(logins, new Function<List<String>, List<LoginGroup>>() { + DatabaseUtils.executeLargeInputs(logins, new Function<List<String>, List<LoginGroup>>() { @Override public List<LoginGroup> apply(@Nonnull List<String> input) { List<LoginGroup> groupMemberships = mapper(session).selectGroupsByLogins(input); diff --git a/sonar-db/src/main/java/org/sonar/core/issue/db/package-info.java b/sonar-db/src/main/java/org/sonar/db/user/UserGroupDao.java index 55dc4912649..2c5a8665ee6 100644 --- a/sonar-db/src/main/java/org/sonar/core/issue/db/package-info.java +++ b/sonar-db/src/main/java/org/sonar/db/user/UserGroupDao.java @@ -17,8 +17,28 @@ * 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.issue.db; -import javax.annotation.ParametersAreNonnullByDefault; +package org.sonar.db.user; +import org.sonar.db.Dao; +import org.sonar.db.DbSession; + +public class UserGroupDao implements Dao { + + public UserGroupDto insert(DbSession session, UserGroupDto dto) { + mapper(session).insert(dto); + return dto; + } + + public void delete(DbSession session, UserGroupDto dto) { + mapper(session).delete(dto); + } + + public void deleteMembersByGroupId(DbSession session, long groupId) { + mapper(session).deleteMembersByGroup(groupId); + } + + protected UserGroupMapper mapper(DbSession session) { + return session.getMapper(UserGroupMapper.class); + } +} diff --git a/sonar-db/src/main/resources/org/sonar/db/component/ComponentIndexMapper.xml b/sonar-db/src/main/resources/org/sonar/db/component/ComponentIndexMapper.xml deleted file mode 100644 index 2a308781795..00000000000 --- a/sonar-db/src/main/resources/org/sonar/db/component/ComponentIndexMapper.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?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.db.component.ComponentIndexMapper"> - - <select id="selectProjectIdsFromQueryAndViewOrSubViewUuid" parameterType="map" resultType="long"> - SELECT r.resource_id FROM resource_index r - INNER JOIN projects copy ON copy.copy_resource_id = r.resource_id - <where> - AND copy.module_uuid_path LIKE #{viewUuidQuery} - AND r.kee LIKE #{query} - </where> - ORDER BY r.name_size - </select> - -</mapper> - diff --git a/sonar-db/src/main/resources/org/sonar/db/component/ResourceIndexerMapper.xml b/sonar-db/src/main/resources/org/sonar/db/component/ResourceIndexerMapper.xml index 82afc7fa85d..b9a10673e3c 100644 --- a/sonar-db/src/main/resources/org/sonar/db/component/ResourceIndexerMapper.xml +++ b/sonar-db/src/main/resources/org/sonar/db/component/ResourceIndexerMapper.xml @@ -3,6 +3,16 @@ <mapper namespace="org.sonar.db.component.ResourceIndexerMapper"> + <select id="selectProjectIdsFromQueryAndViewOrSubViewUuid" parameterType="map" resultType="long"> + SELECT r.resource_id FROM resource_index r + INNER JOIN projects copy ON copy.copy_resource_id = r.resource_id + <where> + AND copy.module_uuid_path LIKE #{viewUuidQuery} + AND r.kee LIKE #{query} + </where> + ORDER BY r.name_size + </select> + <!-- The column PROJECTS.ROOT_ID is not exact on multi-modules projects. The root id must be loaded from the table SNAPSHOTS diff --git a/sonar-db/src/test/java/org/sonar/db/DaoUtilsTest.java b/sonar-db/src/test/java/org/sonar/db/DaoUtilsTest.java index 24987271dfb..fc7c4b1ef80 100644 --- a/sonar-db/src/test/java/org/sonar/db/DaoUtilsTest.java +++ b/sonar-db/src/test/java/org/sonar/db/DaoUtilsTest.java @@ -19,67 +19,14 @@ */ package org.sonar.db; -import com.google.common.base.Function; -import com.google.common.collect.Iterables; -import java.util.Collections; -import java.util.List; import org.junit.Test; -import static com.google.common.collect.Lists.newArrayList; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; public class DaoUtilsTest { @Test public void list_all_dao_classes() { - List<Class> daoClasses = DaoUtils.getDaoClasses(); - - assertThat(daoClasses).isNotEmpty(); - } - - @Test - public void repeatCondition() { - assertThat(DaoUtils.repeatCondition("uuid=?", 1, "or")).isEqualTo("uuid=?"); - assertThat(DaoUtils.repeatCondition("uuid=?", 3, "or")).isEqualTo("uuid=? or uuid=? or uuid=?"); - } - - @Test - public void execute_large_inputs() { - List<Integer> inputs = newArrayList(); - List<String> expectedOutputs = newArrayList(); - for (int i = 0; i < 2010; i++) { - inputs.add(i); - expectedOutputs.add(Integer.toString(i)); - } - - List<String> outputs = DaoUtils.executeLargeInputs(inputs, new Function<List<Integer>, List<String>>() { - @Override - public List<String> apply(List<Integer> input) { - // Check that each partition is only done on 1000 elements max - assertThat(input.size()).isLessThanOrEqualTo(1000); - return newArrayList(Iterables.transform(input, new Function<Integer, String>() { - @Override - public String apply(Integer input) { - return Integer.toString(input); - } - })); - } - }); - - assertThat(outputs).isEqualTo(expectedOutputs); - } - - @Test - public void execute_large_inputs_on_empty_list() { - List<String> outputs = DaoUtils.executeLargeInputs(Collections.<Integer>emptyList(), new Function<List<Integer>, List<String>>() { - @Override - public List<String> apply(List<Integer> input) { - fail("No partition should be made on empty list"); - return Collections.emptyList(); - } - }); - - assertThat(outputs).isEmpty(); + assertThat(DaoUtils.getDaoClasses()).isNotEmpty(); } } diff --git a/sonar-db/src/test/java/org/sonar/db/DatabaseCheckerTest.java b/sonar-db/src/test/java/org/sonar/db/DatabaseCheckerTest.java new file mode 100644 index 00000000000..2902ac122f9 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/DatabaseCheckerTest.java @@ -0,0 +1,114 @@ +/* + * 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.db; + +import java.sql.SQLException; +import org.apache.commons.lang.StringUtils; +import org.junit.Test; +import org.mockito.Mockito; +import org.sonar.api.utils.MessageException; +import org.sonar.db.dialect.Dialect; +import org.sonar.db.dialect.H2; +import org.sonar.db.dialect.MySql; +import org.sonar.db.dialect.Oracle; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class DatabaseCheckerTest { + + @Test + public void requires_oracle_driver_11_2() throws Exception { + Database db = mockDb(new Oracle(), "11.2.1", "11.2.0.0.1"); + new DatabaseChecker(db).start(); + // no error + + db = mockDb(new Oracle(), "11.2.1", "11.3.1"); + new DatabaseChecker(db).start(); + // no error + + db = mockDb(new Oracle(), "11.2.1", "12.0.2"); + new DatabaseChecker(db).start(); + // no error + + db = mockDb(new Oracle(), "11.2.1", "11.1.0.2"); + try { + new DatabaseChecker(db).start(); + fail(); + } catch (MessageException e) { + assertThat(e).hasMessage("Unsupported Oracle JDBC driver version: 11.1.0.2. Minimal required version is 11.2."); + } + } + + @Test + public void requires_oracle_11g_or_greater() throws Exception { + // oracle 11.0 is ok + Database db = mockDb(new Oracle(), "11.0.1", "11.2.0.0.1"); + new DatabaseChecker(db).start(); + + // oracle 11.1 is ok + db = mockDb(new Oracle(), "11.1.1", "11.2.0.0.1"); + new DatabaseChecker(db).start(); + + // oracle 11.2 is ok + db = mockDb(new Oracle(), "11.2.1", "11.2.0.0.1"); + new DatabaseChecker(db).start(); + + // oracle 12 is ok + db = mockDb(new Oracle(), "12.0.1", "11.2.0.0.1"); + new DatabaseChecker(db).start(); + + // oracle 10 is not supported + db = mockDb(new Oracle(), "10.2.1", "11.2.0.0.1"); + try { + new DatabaseChecker(db).start(); + fail(); + } catch (MessageException e) { + assertThat(e).hasMessage("Unsupported Oracle version: 10.2.1. Minimal required version is 11."); + } + } + + @Test + public void log_warning_if_h2() throws Exception { + Database db = mockDb(new H2(), "13.4", "13.4"); + DatabaseChecker checker = new DatabaseChecker(db); + checker.start(); + checker.stop(); + // TODO test log + } + + @Test + public void do_not_fail_if_mysql() throws Exception { + Database db = mockDb(new MySql(), "5.7", "5.7"); + new DatabaseChecker(db).start(); + // no error + } + + private Database mockDb(Dialect dialect, String dbVersion, String driverVersion) throws SQLException { + Database db = mock(Database.class, Mockito.RETURNS_DEEP_STUBS); + when(db.getDialect()).thenReturn(dialect); + when(db.getDataSource().getConnection().getMetaData().getDatabaseMajorVersion()).thenReturn(Integer.parseInt(StringUtils.substringBefore(dbVersion, "."))); + when(db.getDataSource().getConnection().getMetaData().getDatabaseProductVersion()).thenReturn(dbVersion); + when(db.getDataSource().getConnection().getMetaData().getDriverVersion()).thenReturn(driverVersion); + return db; + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/DatabaseUtilsTest.java b/sonar-db/src/test/java/org/sonar/db/DatabaseUtilsTest.java index 933e931ac03..1b6acbb3eb2 100644 --- a/sonar-db/src/test/java/org/sonar/db/DatabaseUtilsTest.java +++ b/sonar-db/src/test/java/org/sonar/db/DatabaseUtilsTest.java @@ -19,15 +19,21 @@ */ package org.sonar.db; +import com.google.common.base.Function; +import com.google.common.collect.Iterables; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.util.Collections; +import java.util.List; import org.junit.Test; import org.sonar.db.dialect.Oracle; +import static com.google.common.collect.Lists.newArrayList; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -142,4 +148,49 @@ public class DatabaseUtilsTest extends AbstractDaoTestCase { } return sql; } + + @Test + public void repeatCondition() { + assertThat(DatabaseUtils.repeatCondition("uuid=?", 1, "or")).isEqualTo("uuid=?"); + assertThat(DatabaseUtils.repeatCondition("uuid=?", 3, "or")).isEqualTo("uuid=? or uuid=? or uuid=?"); + } + + @Test + public void execute_large_inputs() { + List<Integer> inputs = newArrayList(); + List<String> expectedOutputs = newArrayList(); + for (int i = 0; i < 2010; i++) { + inputs.add(i); + expectedOutputs.add(Integer.toString(i)); + } + + List<String> outputs = DatabaseUtils.executeLargeInputs(inputs, new Function<List<Integer>, List<String>>() { + @Override + public List<String> apply(List<Integer> input) { + // Check that each partition is only done on 1000 elements max + assertThat(input.size()).isLessThanOrEqualTo(1000); + return newArrayList(Iterables.transform(input, new Function<Integer, String>() { + @Override + public String apply(Integer input) { + return Integer.toString(input); + } + })); + } + }); + + assertThat(outputs).isEqualTo(expectedOutputs); + } + + @Test + public void execute_large_inputs_on_empty_list() { + List<String> outputs = DatabaseUtils.executeLargeInputs(Collections.<Integer>emptyList(), new Function<List<Integer>, List<String>>() { + @Override + public List<String> apply(List<Integer> input) { + fail("No partition should be made on empty list"); + return Collections.emptyList(); + } + }); + + assertThat(outputs).isEmpty(); + } } diff --git a/sonar-db/src/test/java/org/sonar/db/DbTester.java b/sonar-db/src/test/java/org/sonar/db/DbTester.java index ba428c5cbe8..dfa4e9cfef0 100644 --- a/sonar-db/src/test/java/org/sonar/db/DbTester.java +++ b/sonar-db/src/test/java/org/sonar/db/DbTester.java @@ -20,14 +20,8 @@ package org.sonar.db; import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; -import java.io.File; -import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.URISyntaxException; import java.sql.Clob; import java.sql.Connection; import java.sql.PreparedStatement; @@ -36,19 +30,13 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.List; import java.util.Map; -import java.util.Properties; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.dbutils.QueryRunner; -import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.text.StrSubstitutor; import org.dbunit.Assertion; -import org.dbunit.DataSourceDatabaseTester; import org.dbunit.DatabaseUnitException; -import org.dbunit.IDatabaseTester; import org.dbunit.assertion.DiffCollectingFailureHandler; import org.dbunit.assertion.Difference; import org.dbunit.database.DatabaseConfig; @@ -61,13 +49,10 @@ import org.dbunit.dataset.filter.DefaultColumnFilter; import org.dbunit.dataset.xml.FlatXmlDataSet; import org.dbunit.ext.mssql.InsertIdentityOperation; import org.dbunit.operation.DatabaseOperation; -import org.junit.AssumptionViolatedException; +import org.junit.After; import org.junit.rules.ExternalResource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.config.Settings; -import org.sonar.db.deprecated.NullQueue; -import org.sonar.db.dialect.Dialect; +import org.picocontainer.containers.TransientPicoContainer; +import org.sonar.api.utils.System2; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Maps.newHashMap; @@ -78,96 +63,77 @@ import static org.junit.Assert.fail; * This class should be call using @ClassRule in order to create the schema once (ft @Rule is used * the schema will be recreated before each test). * Data will be truncated each time you call prepareDbUnit(). - * <p/> + * <p> * File using {@link DbTester} must be annotated with {@link org.sonar.test.DbTests} so * that they can be executed on all supported DBs (Oracle, MySQL, ...). */ public class DbTester extends ExternalResource { - private static final Logger LOG = LoggerFactory.getLogger(DbTester.class); + private final System2 system2; + private final TestDb db; + private DbClient2 client; + private DbSession session = null; - private Database db; - private DatabaseCommands commands; - private IDatabaseTester tester; - private MyBatis myBatis; - private String schemaPath = null; - - public DbTester schema(Class baseClass, String filename) { - String path = StringUtils.replaceChars(baseClass.getCanonicalName(), '.', '/'); - schemaPath = path + "/" + filename; - return this; + @Deprecated + public DbTester() { + this.system2 = System2.INSTANCE; + this.db = TestDb.create(null); } - @Override - protected void before() throws Throwable { - Settings settings = new Settings().setProperties(Maps.fromProperties(System.getProperties())); - if (settings.hasKey("orchestrator.configUrl")) { - loadOrchestratorSettings(settings); - } - String login = settings.getString("sonar.jdbc.username"); - for (String key : settings.getKeysStartingWith("sonar.jdbc")) { - LOG.info(key + ": " + settings.getString(key)); - } - String dialect = settings.getString("sonar.jdbc.dialect"); - if (dialect != null && !"h2".equals(dialect)) { - db = new DefaultDatabase(settings); - } else { - db = new H2Database("h2Tests" + DigestUtils.md5Hex(StringUtils.defaultString(schemaPath)), schemaPath == null); - } - db.start(); - if (schemaPath != null) { - // will fail if not H2 - if (db.getDialect().getId().equals("h2")) { - ((H2Database) db).executeScript(schemaPath); - } else { - db.stop(); - throw new AssumptionViolatedException("Test disabled because it supports only H2"); - } - } - LOG.info("Test Database: " + db); - - commands = DatabaseCommands.forDialect(db.getDialect()); - tester = new DataSourceDatabaseTester(db.getDataSource(), commands.useLoginAsSchema() ? login : null); - - myBatis = new MyBatis(db, new NullQueue()); - myBatis.start(); + private DbTester(System2 system2, @Nullable String schemaPath) { + this.system2 = system2; + this.db = TestDb.create(schemaPath); + } - truncateTables(); + public static DbTester create(System2 system2) { + return new DbTester(system2, null); } - public void truncateTables() { - try { - commands.truncateDatabase(db.getDataSource()); - } catch (SQLException e) { - throw new IllegalStateException("Fail to truncate db tables", e); - } + public static DbTester createForSchema(System2 system2, Class testClass, String filename) { + String path = StringUtils.replaceChars(testClass.getCanonicalName(), '.', '/'); + String schemaPath = path + "/" + filename; + return new DbTester(system2, schemaPath); } @Override - protected void after() { - db.stop(); - db = null; - myBatis = null; + protected void before() throws Throwable { + truncateTables(); } - public Database database() { - return db; + @After + public void closeSession() throws Exception { + if (session != null) { + MyBatis.closeQuietly(session); + } } - public Dialect dialect() { - return db.getDialect(); + public DbSession getSession() { + if (session == null) { + session = db.getMyBatis().openSession(false); + } + return session; } - public MyBatis myBatis() { - return myBatis; + public void truncateTables() { + db.truncateTables(); } - public Connection openConnection() throws SQLException { - return db.getDataSource().getConnection(); + public DbClient2 getDbClient() { + if (client == null) { + TransientPicoContainer ioc = new TransientPicoContainer(); + ioc.addComponent(db.getMyBatis()); + ioc.addComponent(system2); + for (Class daoClass : DaoUtils.getDaoClasses()) { + ioc.addComponent(daoClass); + } + List<Dao> daos = ioc.getComponents(Dao.class); + client = new DbClient2(db.getMyBatis(), daos.toArray(new Dao[daos.size()])); + } + return client; } public void executeUpdateSql(String sql) { - try (Connection connection = openConnection()) { + try (Connection connection = db.getDatabase().getDataSource().getConnection()) { new QueryRunner().update(connection, sql); } catch (Exception e) { throw new IllegalStateException("Fail to execute sql: " + sql); @@ -191,7 +157,7 @@ public class DbTester extends ExternalResource { Preconditions.checkArgument(StringUtils.contains(sql, "count("), "Parameter must be a SQL request containing 'count(x)' function. Got " + sql); try ( - Connection connection = openConnection(); + Connection connection = db.getDatabase().getDataSource().getConnection(); PreparedStatement stmt = connection.prepareStatement(sql); ResultSet rs = stmt.executeQuery()) { if (rs.next()) { @@ -206,7 +172,7 @@ public class DbTester extends ExternalResource { public List<Map<String, Object>> select(String selectSql) { try ( - Connection connection = openConnection(); + Connection connection = db.getDatabase().getDataSource().getConnection(); PreparedStatement stmt = connection.prepareStatement(selectSql); ResultSet rs = stmt.executeQuery()) { return getHashMap(rs); @@ -259,8 +225,7 @@ public class DbTester extends ExternalResource { public void prepareDbUnit(Class testClass, String... testNames) { InputStream[] streams = new InputStream[testNames.length]; try { - // Purge previous data - commands.truncateDatabase(db.getDataSource()); + db.truncateTables(); for (int i = 0; i < testNames.length; i++) { String path = "/" + testClass.getName().replace('.', '/') + "/" + testNames[i]; @@ -271,7 +236,7 @@ public class DbTester extends ExternalResource { } prepareDbUnit(streams); - commands.resetPrimaryKeys(db.getDataSource()); + db.getCommands().resetPrimaryKeys(db.getDatabase().getDataSource()); } catch (SQLException e) { throw translateException("Could not setup DBUnit data", e); } finally { @@ -288,9 +253,9 @@ public class DbTester extends ExternalResource { for (int i = 0; i < dataSetStream.length; i++) { dataSets[i] = dbUnitDataSet(dataSetStream[i]); } - tester.setDataSet(new CompositeDataSet(dataSets)); + db.getDbUnitTester().setDataSet(new CompositeDataSet(dataSets)); connection = dbUnitConnection(); - new InsertIdentityOperation(DatabaseOperation.INSERT).execute(connection, tester.getDataSet()); + new InsertIdentityOperation(DatabaseOperation.INSERT).execute(connection, db.getDbUnitTester().getDataSet()); } catch (Exception e) { throw translateException("Could not setup DBUnit data", e); } finally { @@ -339,7 +304,7 @@ public class DbTester extends ExternalResource { } public void assertColumnDefinition(String table, String column, int expectedType, @Nullable Integer expectedSize) { - try (Connection connection = openConnection(); + try (Connection connection = db.getDatabase().getDataSource().getConnection(); PreparedStatement stmt = connection.prepareStatement("select * from " + table); ResultSet res = stmt.executeQuery()) { Integer columnIndex = getColumnIndex(res, column); @@ -389,8 +354,8 @@ public class DbTester extends ExternalResource { private IDatabaseConnection dbUnitConnection() { try { - IDatabaseConnection connection = tester.getConnection(); - connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, commands.getDbUnitFactory()); + IDatabaseConnection connection = db.getDbUnitTester().getConnection(); + connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, db.getDbUnitFactory()); return connection; } catch (Exception e) { throw translateException("Error while getting connection", e); @@ -413,36 +378,6 @@ public class DbTester extends ExternalResource { return runtimeException; } - private void loadOrchestratorSettings(Settings settings) throws URISyntaxException, IOException { - String url = settings.getString("orchestrator.configUrl"); - URI uri = new URI(url); - InputStream input = null; - try { - if (url.startsWith("file:")) { - File file = new File(uri); - input = FileUtils.openInputStream(file); - } else { - HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection(); - int responseCode = connection.getResponseCode(); - if (responseCode >= 400) { - throw new IllegalStateException("Fail to request: " + uri + ". Status code=" + responseCode); - } - - input = connection.getInputStream(); - - } - Properties props = new Properties(); - props.load(input); - settings.addProperties(props); - for (Map.Entry<String, String> entry : settings.getProperties().entrySet()) { - String interpolatedValue = StrSubstitutor.replace(entry.getValue(), System.getenv(), "${", "}"); - settings.setProperty(entry.getKey(), interpolatedValue); - } - } finally { - IOUtils.closeQuietly(input); - } - } - private static void doClobFree(Clob clob) throws SQLException { try { clob.free(); @@ -450,4 +385,19 @@ public class DbTester extends ExternalResource { // JTS driver do not implement free() as it's using JDBC 3.0 } } + + @Deprecated + public MyBatis myBatis() { + return db.getMyBatis(); + } + + @Deprecated + public Connection openConnection() throws Exception { + return db.getDatabase().getDataSource().getConnection(); + } + + @Deprecated + public Database database() { + return db.getDatabase(); + } } diff --git a/sonar-db/src/test/java/org/sonar/db/MyBatisTest.java b/sonar-db/src/test/java/org/sonar/db/MyBatisTest.java index 194346fe0a0..87922b13faf 100644 --- a/sonar-db/src/test/java/org/sonar/db/MyBatisTest.java +++ b/sonar-db/src/test/java/org/sonar/db/MyBatisTest.java @@ -63,7 +63,7 @@ public class MyBatisTest { MyBatis myBatis = new MyBatis(database, queue); myBatis.start(); - SqlSession session = myBatis.openBatchSession(); + SqlSession session = myBatis.openSession(false); try { assertThat(session.getConnection(), notNullValue()); assertThat(session.getMapper(RuleMapper.class), notNullValue()); diff --git a/sonar-db/src/test/java/org/sonar/db/ResultSetIteratorTest.java b/sonar-db/src/test/java/org/sonar/db/ResultSetIteratorTest.java new file mode 100644 index 00000000000..970f9090fd1 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/ResultSetIteratorTest.java @@ -0,0 +1,176 @@ +/* + * 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.db; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.NoSuchElementException; +import org.apache.commons.dbutils.DbUtils; +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.api.utils.System2; +import org.sonar.test.DbTests; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.fail; + +@Category(DbTests.class) +public class ResultSetIteratorTest { + + @ClassRule + public static DbTester dbTester = DbTester.createForSchema(System2.INSTANCE, ResultSetIteratorTest.class, "schema.sql"); + + Connection connection = null; + + @Before + public void setUp() throws Exception { + connection = dbTester.openConnection(); + } + + @After + public void tearDown() { + DbUtils.closeQuietly(connection); + } + + @Test + public void create_iterator_from_statement() throws Exception { + dbTester.prepareDbUnit(getClass(), "feed.xml"); + + PreparedStatement stmt = connection.prepareStatement("select * from issues order by id"); + FirstIntColumnIterator iterator = new FirstIntColumnIterator(stmt); + + assertThat(iterator.hasNext()).isTrue(); + + // calling multiple times hasNext() is ok + assertThat(iterator.hasNext()).isTrue(); + + assertThat(iterator.next()).isEqualTo(10); + assertThat(iterator.hasNext()).isTrue(); + assertThat(iterator.next()).isEqualTo(20); + + // call next() without calling hasNext() + assertThat(iterator.next()).isEqualTo(30); + assertThat(iterator.hasNext()).isFalse(); + + try { + iterator.next(); + fail(); + } catch (NoSuchElementException e) { + // ok + } + + iterator.close(); + // statement is closed by ResultSetIterator + assertThat(stmt.isClosed()).isTrue(); + } + + @Test + public void iterate_empty_list() throws Exception { + dbTester.prepareDbUnit(getClass(), "feed.xml"); + + PreparedStatement stmt = connection.prepareStatement("select * from issues where id < 0"); + FirstIntColumnIterator iterator = new FirstIntColumnIterator(stmt); + + assertThat(iterator.hasNext()).isFalse(); + } + + @Test + public void create_iterator_from_result_set() throws Exception { + dbTester.prepareDbUnit(getClass(), "feed.xml"); + + PreparedStatement stmt = connection.prepareStatement("select * from issues order by id"); + ResultSet rs = stmt.executeQuery(); + FirstIntColumnIterator iterator = new FirstIntColumnIterator(rs); + + assertThat(iterator.next()).isEqualTo(10); + assertThat(iterator.next()).isEqualTo(20); + assertThat(iterator.next()).isEqualTo(30); + + iterator.close(); + assertThat(rs.isClosed()).isTrue(); + stmt.close(); + } + + @Test + public void remove_row_is_not_supported() throws Exception { + PreparedStatement stmt = connection.prepareStatement("select * from issues order by id"); + FirstIntColumnIterator iterator = new FirstIntColumnIterator(stmt); + + try { + iterator.remove(); + fail(); + } catch (UnsupportedOperationException ok) { + // ok + } + + iterator.close(); + } + + @Test + public void fail_to_read_row() throws Exception { + dbTester.prepareDbUnit(getClass(), "feed.xml"); + + PreparedStatement stmt = connection.prepareStatement("select * from issues order by id"); + FailIterator iterator = new FailIterator(stmt); + + assertThat(iterator.hasNext()).isTrue(); + try { + iterator.next(); + fail(); + } catch (IllegalStateException e) { + assertThat(e.getCause()).isInstanceOf(SQLException.class); + } + iterator.close(); + } + + private static class FirstIntColumnIterator extends ResultSetIterator<Integer> { + + public FirstIntColumnIterator(PreparedStatement stmt) throws SQLException { + super(stmt); + } + + public FirstIntColumnIterator(ResultSet rs) { + super(rs); + } + + @Override + protected Integer read(ResultSet rs) throws SQLException { + return rs.getInt(1); + } + } + + private static class FailIterator extends ResultSetIterator<Integer> { + + public FailIterator(PreparedStatement stmt) throws SQLException { + super(stmt); + } + + @Override + protected Integer read(ResultSet rs) throws SQLException { + // column does not exist + return rs.getInt(1234); + } + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/TestDb.java b/sonar-db/src/test/java/org/sonar/db/TestDb.java new file mode 100644 index 00000000000..715ea17af6d --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/TestDb.java @@ -0,0 +1,175 @@ +/* + * 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.db; + +import com.google.common.collect.Maps; +import java.io.File; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URI; +import java.sql.SQLException; +import java.util.Map; +import java.util.Properties; +import javax.annotation.Nullable; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.text.StrSubstitutor; +import org.dbunit.DataSourceDatabaseTester; +import org.dbunit.IDatabaseTester; +import org.dbunit.dataset.datatype.IDataTypeFactory; +import org.junit.AssumptionViolatedException; +import org.sonar.api.config.Settings; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; +import org.sonar.db.deprecated.NullQueue; + +/** + * This class should be call using @ClassRule in order to create the schema once (ft @Rule is used + * the schema will be recreated before each test). + * Data will be truncated each time you call prepareDbUnit(). + * <p/> + * File using {@link TestDb} must be annotated with {@link org.sonar.test.DbTests} so + * that they can be executed on all supported DBs (Oracle, MySQL, ...). + */ +class TestDb { + + private static TestDb DEFAULT; + + private static final Logger LOG = Loggers.get(TestDb.class); + + private Database db; + private DatabaseCommands commands; + private IDatabaseTester tester; + private MyBatis myBatis; + + private TestDb(@Nullable String schemaPath) { + if (db == null) { + Settings settings = new Settings().setProperties(Maps.fromProperties(System.getProperties())); + if (settings.hasKey("orchestrator.configUrl")) { + loadOrchestratorSettings(settings); + } + String login = settings.getString("sonar.jdbc.username"); + for (String key : settings.getKeysStartingWith("sonar.jdbc")) { + LOG.info(key + ": " + settings.getString(key)); + } + String dialect = settings.getString("sonar.jdbc.dialect"); + if (dialect != null && !"h2".equals(dialect)) { + db = new DefaultDatabase(settings); + } else { + db = new H2Database("h2Tests" + DigestUtils.md5Hex(StringUtils.defaultString(schemaPath)), schemaPath == null); + } + db.start(); + if (schemaPath != null) { + // will fail if not H2 + if (db.getDialect().getId().equals("h2")) { + ((H2Database) db).executeScript(schemaPath); + } else { + db.stop(); + throw new AssumptionViolatedException("Test disabled because it supports only H2"); + } + } + LOG.info("Test Database: " + db); + + commands = DatabaseCommands.forDialect(db.getDialect()); + tester = new DataSourceDatabaseTester(db.getDataSource(), commands.useLoginAsSchema() ? login : null); + + myBatis = new MyBatis(db, new NullQueue()); + myBatis.start(); + } + } + + void truncateTables() { + try { + commands.truncateDatabase(db.getDataSource()); + } catch (SQLException e) { + throw new IllegalStateException("Fail to truncate db tables", e); + } + } + + static TestDb create(@Nullable String schemaPath) { + if (schemaPath == null) { + if (DEFAULT == null) { + DEFAULT = new TestDb(null); + } + return DEFAULT; + } + return new TestDb(schemaPath); + } + + void stop() { + db.stop(); + db = null; + myBatis = null; + } + + Database getDatabase() { + return db; + } + + DatabaseCommands getCommands() { + return commands; + } + + MyBatis getMyBatis() { + return myBatis; + } + + IDatabaseTester getDbUnitTester() { + return tester; + } + + IDataTypeFactory getDbUnitFactory() { + return commands.getDbUnitFactory(); + } + + private void loadOrchestratorSettings(Settings settings) { + String url = settings.getString("orchestrator.configUrl"); + InputStream input = null; + try { + URI uri = new URI(url); + if (url.startsWith("file:")) { + File file = new File(uri); + input = FileUtils.openInputStream(file); + } else { + HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection(); + int responseCode = connection.getResponseCode(); + if (responseCode >= 400) { + throw new IllegalStateException("Fail to request: " + uri + ". Status code=" + responseCode); + } + + input = connection.getInputStream(); + + } + Properties props = new Properties(); + props.load(input); + settings.addProperties(props); + for (Map.Entry<String, String> entry : settings.getProperties().entrySet()) { + String interpolatedValue = StrSubstitutor.replace(entry.getValue(), System.getenv(), "${", "}"); + settings.setProperty(entry.getKey(), interpolatedValue); + } + } catch (Exception e) { + throw new IllegalStateException(e); + } finally { + IOUtils.closeQuietly(input); + } + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/activity/ActivityDaoTest.java b/sonar-db/src/test/java/org/sonar/db/activity/ActivityDaoTest.java new file mode 100644 index 00000000000..c2135f6e3ac --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/activity/ActivityDaoTest.java @@ -0,0 +1,59 @@ +/* + * 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.db.activity; + +import java.util.Map; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.test.DbTests; + +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 ActivityDaoTest { + + System2 system = mock(System2.class); + + @Rule + public DbTester dbTester = DbTester.create(system); + + ActivityDao sut = dbTester.getDbClient().activityDao(); + + @Test + public void insert() { + when(system.now()).thenReturn(1_500_000_000_000L); + ActivityDto dto = new ActivityDto() + .setKey("UUID_1").setAction("THE_ACTION").setType("THE_TYPE") + .setAuthor("THE_AUTHOR").setData("THE_DATA"); + sut.insert(dto); + + Map<String, Object> map = dbTester.selectFirst("select created_at as \"createdAt\", log_action as \"action\", data_field as \"data\" from activities where log_key='UUID_1'"); + assertThat(map.get("action")).isEqualTo("THE_ACTION"); + // not possible to check exact date yet. dbTester#selectFirst() uses ResultSet#getObject(), which returns + // non-JDBC interface in Oracle driver. + assertThat(map.get("createdAt")).isNotNull(); + assertThat(map.get("data")).isEqualTo("THE_DATA"); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/component/ComponentLinkDaoTest.java b/sonar-db/src/test/java/org/sonar/db/component/ComponentLinkDaoTest.java new file mode 100644 index 00000000000..931d4f0c508 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/component/ComponentLinkDaoTest.java @@ -0,0 +1,100 @@ +/* + * 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.db.component; + +import java.util.List; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.test.DbTests; + +import static org.assertj.core.api.Assertions.assertThat; + +@Category(DbTests.class) +public class ComponentLinkDaoTest { + + @ClassRule + public static DbTester dbTester = DbTester.create(System2.INSTANCE); + + ComponentLinkDao dao = dbTester.getDbClient().componentLinkDao(); + + @Test + public void select_by_component_uuid() { + dbTester.prepareDbUnit(getClass(), "shared.xml"); + + List<ComponentLinkDto> links = dao.selectByComponentUuid(dbTester.getSession(), "ABCD"); + assertThat(links).hasSize(2); + + links = dao.selectByComponentUuid(dbTester.getSession(), "BCDE"); + assertThat(links).hasSize(1); + + ComponentLinkDto link = links.get(0); + assertThat(link.getId()).isEqualTo(3L); + assertThat(link.getComponentUuid()).isEqualTo("BCDE"); + assertThat(link.getType()).isEqualTo("homepage"); + assertThat(link.getName()).isEqualTo("Home"); + assertThat(link.getHref()).isEqualTo("http://www.struts.org"); + } + + @Test + public void insert() { + dbTester.prepareDbUnit(getClass(), "empty.xml"); + + dao.insert(dbTester.getSession(), new ComponentLinkDto() + .setComponentUuid("ABCD") + .setType("homepage") + .setName("Home") + .setHref("http://www.sonarqube.org") + ); + dbTester.getSession().commit(); + + dbTester.assertDbUnit(getClass(), "insert-result.xml", new String[] {"id"}, "project_links"); + } + + @Test + public void update() { + dbTester.prepareDbUnit(getClass(), "update.xml"); + + dao.update(dbTester.getSession(), new ComponentLinkDto() + .setId(1L) + .setComponentUuid("ABCD") + .setType("homepage") + .setName("Home") + .setHref("http://www.sonarqube.org") + ); + dbTester.getSession().commit(); + + dbTester.assertDbUnit(getClass(), "update-result.xml", "project_links"); + } + + @Test + public void delete() { + dbTester.prepareDbUnit(getClass(), "delete.xml"); + + dao.delete(dbTester.getSession(), 1L); + dbTester.getSession().commit(); + + assertThat(dbTester.countRowsOfTable("project_links")).isEqualTo(0); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/component/ResourceIndexerDaoTest.java b/sonar-db/src/test/java/org/sonar/db/component/ResourceIndexerDaoTest.java index 90329d5842b..deb992be365 100644 --- a/sonar-db/src/test/java/org/sonar/db/component/ResourceIndexerDaoTest.java +++ b/sonar-db/src/test/java/org/sonar/db/component/ResourceIndexerDaoTest.java @@ -22,14 +22,15 @@ package org.sonar.db.component; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; -import org.hamcrest.core.Is; import org.junit.Before; import org.junit.Test; import org.sonar.api.resources.Qualifiers; +import org.sonar.api.utils.System2; import org.sonar.db.AbstractDaoTestCase; +import org.sonar.db.DbSession; -import static org.hamcrest.Matchers.greaterThan; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; public class ResourceIndexerDaoTest extends AbstractDaoTestCase { @@ -37,7 +38,7 @@ public class ResourceIndexerDaoTest extends AbstractDaoTestCase { @Before public void createDao() { - dao = new ResourceIndexerDao(getMyBatis()); + dao = new ResourceIndexerDao(getMyBatis(), mock(System2.class)); } @Test @@ -88,17 +89,17 @@ public class ResourceIndexerDaoTest extends AbstractDaoTestCase { // project rs = connection.createStatement().executeQuery("select count(resource_id) from resource_index where resource_id=1"); rs.next(); - assertThat(rs.getInt(1), greaterThan(0)); + assertThat(rs.getInt(1)).isGreaterThan(0); // directory rs = connection.createStatement().executeQuery("select count(resource_id) from resource_index where resource_id=2"); rs.next(); - assertThat(rs.getInt(1), Is.is(0)); + assertThat(rs.getInt(1)).isEqualTo(0); // file rs = connection.createStatement().executeQuery("select count(resource_id) from resource_index where resource_id=3"); rs.next(); - assertThat(rs.getInt(1), greaterThan(0)); + assertThat(rs.getInt(1)).isGreaterThan(0); } finally { if (null != rs) { rs.close(); @@ -150,4 +151,16 @@ public class ResourceIndexerDaoTest extends AbstractDaoTestCase { checkTables("shouldNotReindexUnchangedResource", new String[] {"id"}, "resource_index"); } + + @Test + public void select_project_ids_from_query_and_view_or_sub_view_uuid() { + setupData("select_project_ids_from_query_and_view_or_sub_view_uuid"); + String viewUuid = "EFGH"; + + DbSession session = getMyBatis().openSession(false); + assertThat(dao.selectProjectIdsFromQueryAndViewOrSubViewUuid(session, "project", viewUuid)).containsOnly(1L, 2L); + assertThat(dao.selectProjectIdsFromQueryAndViewOrSubViewUuid(session, "one", viewUuid)).containsOnly(1L); + assertThat(dao.selectProjectIdsFromQueryAndViewOrSubViewUuid(session, "two", viewUuid)).containsOnly(2L); + assertThat(dao.selectProjectIdsFromQueryAndViewOrSubViewUuid(session, "unknown", viewUuid)).isEmpty(); + } } diff --git a/sonar-db/src/test/java/org/sonar/db/component/SnapshotDaoTest.java b/sonar-db/src/test/java/org/sonar/db/component/SnapshotDaoTest.java new file mode 100644 index 00000000000..21ec3e349a9 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/component/SnapshotDaoTest.java @@ -0,0 +1,305 @@ +/* + * 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.db.component; + +import java.util.Date; +import java.util.List; +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.api.utils.DateUtils; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.test.DbTests; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.db.component.SnapshotQuery.SORT_FIELD.BY_DATE; +import static org.sonar.db.component.SnapshotQuery.SORT_ORDER.ASC; +import static org.sonar.db.component.SnapshotQuery.SORT_ORDER.DESC; + +@Category(DbTests.class) +public class SnapshotDaoTest { + + @ClassRule + public static DbTester db = new DbTester(); + + DbSession session; + + SnapshotDao sut; + + @Before + public void createDao() { + session = db.myBatis().openSession(false); + sut = new SnapshotDao(); + } + + @After + public void tearDown() { + session.close(); + } + + @Test + public void get_by_key() { + db.prepareDbUnit(getClass(), "shared.xml"); + + SnapshotDto result = sut.selectNullableById(session, 3L); + assertThat(result).isNotNull(); + assertThat(result.getId()).isEqualTo(3L); + assertThat(result.getComponentId()).isEqualTo(3L); + assertThat(result.getRootProjectId()).isEqualTo(1L); + assertThat(result.getParentId()).isEqualTo(2L); + assertThat(result.getRootId()).isEqualTo(1L); + assertThat(result.getStatus()).isEqualTo("P"); + assertThat(result.getLast()).isTrue(); + assertThat(result.getPurgeStatus()).isEqualTo(1); + assertThat(result.getDepth()).isEqualTo(1); + assertThat(result.getScope()).isEqualTo("DIR"); + assertThat(result.getQualifier()).isEqualTo("PAC"); + assertThat(result.getVersion()).isEqualTo("2.1-SNAPSHOT"); + assertThat(result.getPath()).isEqualTo("1.2."); + + assertThat(result.getPeriodMode(1)).isEqualTo("days1"); + assertThat(result.getPeriodModeParameter(1)).isEqualTo("30"); + assertThat(result.getPeriodDate(1)).isEqualTo(1316815200000L); + assertThat(result.getPeriodMode(2)).isEqualTo("days2"); + assertThat(result.getPeriodModeParameter(2)).isEqualTo("31"); + assertThat(result.getPeriodDate(2)).isEqualTo(1316901600000L); + assertThat(result.getPeriodMode(3)).isEqualTo("days3"); + assertThat(result.getPeriodModeParameter(3)).isEqualTo("32"); + assertThat(result.getPeriodDate(3)).isEqualTo(1316988000000L); + assertThat(result.getPeriodMode(4)).isEqualTo("days4"); + assertThat(result.getPeriodModeParameter(4)).isEqualTo("33"); + assertThat(result.getPeriodDate(4)).isEqualTo(1317074400000L); + assertThat(result.getPeriodMode(5)).isEqualTo("days5"); + assertThat(result.getPeriodModeParameter(5)).isEqualTo("34"); + assertThat(result.getPeriodDate(5)).isEqualTo(1317160800000L); + + assertThat(result.getCreatedAt()).isEqualTo(1228172400000L); + assertThat(result.getBuildDate()).isEqualTo(1317247200000L); + + assertThat(sut.selectNullableById(session, 999L)).isNull(); + } + + @Test + public void lastSnapshot_returns_null_when_no_last_snapshot() { + SnapshotDto snapshot = sut.selectLastSnapshotByComponentId(session, 123L); + + assertThat(snapshot).isNull(); + } + + @Test + public void lastSnapshot_from_one_resource() { + db.prepareDbUnit(getClass(), "snapshots.xml"); + + SnapshotDto snapshot = sut.selectLastSnapshotByComponentId(session, 2L); + + assertThat(snapshot).isNotNull(); + assertThat(snapshot.getId()).isEqualTo(4L); + } + + @Test + public void lastSnapshot_from_one_resource_without_last_is_null() { + db.prepareDbUnit(getClass(), "snapshots.xml"); + + SnapshotDto snapshot = sut.selectLastSnapshotByComponentId(session, 5L); + + assertThat(snapshot).isNull(); + } + + @Test + public void snapshot_and_child_retrieved() { + db.prepareDbUnit(getClass(), "snapshots.xml"); + + List<SnapshotDto> snapshots = sut.selectSnapshotAndChildrenOfProjectScope(session, 1L); + + assertThat(snapshots).isNotEmpty(); + assertThat(snapshots).extracting("id").containsOnly(1L, 6L); + } + + @Test + public void select_snapshots_by_component_id() { + db.prepareDbUnit(getClass(), "snapshots.xml"); + + List<SnapshotDto> snapshots = sut.selectSnapshotsByComponentId(session, 1L); + + assertThat(snapshots).hasSize(3); + } + + @Test + public void select_snapshots_by_query() { + db.prepareDbUnit(getClass(), "select_snapshots_by_query.xml"); + + assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery())).hasSize(6); + + assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(1L))).hasSize(3); + + assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(1L).setVersion("2.2-SNAPSHOT"))).extracting("id").containsOnly(3L); + + assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(1L).setIsLast(true))).extracting("id").containsOnly(1L); + assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(1L).setIsLast(false))).extracting("id").containsOnly(2L, 3L); + + assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(1L).setCreatedAfter(1228172400002L))).extracting("id").containsOnly(2L, 3L); + assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(1L).setCreatedBefore(1228172400002L))).extracting("id").containsOnly(1L); + + assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(2L).setStatus("P"))).hasSize(1); + assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(2L).setStatus("U"))).hasSize(1); + + assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(1L).setSort(BY_DATE, ASC)).get(0).getId()).isEqualTo(1L); + assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(1L).setSort(BY_DATE, DESC)).get(0).getId()).isEqualTo(3L); + } + + @Test + public void select_previous_version_snapshots() throws Exception { + db.prepareDbUnit(getClass(), "select_previous_version_snapshots.xml"); + + List<SnapshotDto> snapshots = sut.selectPreviousVersionSnapshots(session, 1L, "1.2-SNAPSHOT"); + assertThat(snapshots).hasSize(2); + + SnapshotDto firstSnapshot = snapshots.get(0); + assertThat(firstSnapshot.getVersion()).isEqualTo("1.1"); + + // All snapshots are returned on an unknown version + assertThat(sut.selectPreviousVersionSnapshots(session, 1L, "UNKNOWN")).hasSize(3); + } + + @Test + public void insert() { + db.prepareDbUnit(getClass(), "empty.xml"); + + SnapshotDto dto = defaultSnapshot().setCreatedAt(1403042400000L); + + sut.insert(session, dto); + session.commit(); + + assertThat(dto.getId()).isNotNull(); + db.assertDbUnit(getClass(), "insert-result.xml", new String[] {"id"}, "snapshots"); + } + + @Test + public void insert_snapshots() { + db.prepareDbUnit(getClass(), "empty.xml"); + + sut.insert(session, + new SnapshotDto().setComponentId(1L).setLast(false), + new SnapshotDto().setComponentId(2L).setLast(false)); + session.commit(); + + assertThat(db.countRowsOfTable("snapshots")).isEqualTo(2); + } + + @Test + public void set_snapshot_and_children_to_false_and_status_processed() { + db.prepareDbUnit(getClass(), "snapshots.xml"); + SnapshotDto snapshot = defaultSnapshot().setId(1L); + + sut.updateSnapshotAndChildrenLastFlagAndStatus(session, snapshot, false, SnapshotDto.STATUS_PROCESSED); + session.commit(); + + List<SnapshotDto> snapshots = sut.selectSnapshotAndChildrenOfProjectScope(session, 1L); + assertThat(snapshots).hasSize(2); + assertThat(snapshots).extracting("id").containsOnly(1L, 6L); + assertThat(snapshots).extracting("last").containsOnly(false); + assertThat(snapshots).extracting("status").containsOnly(SnapshotDto.STATUS_PROCESSED); + } + + @Test + public void set_snapshot_and_children_isLast_flag_to_false() { + db.prepareDbUnit(getClass(), "snapshots.xml"); + SnapshotDto snapshot = defaultSnapshot().setId(1L); + + sut.updateSnapshotAndChildrenLastFlag(session, snapshot, false); + session.commit(); + + List<SnapshotDto> snapshots = sut.selectSnapshotAndChildrenOfProjectScope(session, 1L); + assertThat(snapshots).hasSize(2); + assertThat(snapshots).extracting("id").containsOnly(1L, 6L); + assertThat(snapshots).extracting("last").containsOnly(false); + } + + @Test + public void is_last_snapshot_when_no_previous_snapshot() { + SnapshotDto snapshot = defaultSnapshot(); + + boolean isLast = SnapshotDao.isLast(snapshot, null); + + assertThat(isLast).isTrue(); + } + + @Test + public void is_last_snapshot_when_previous_snapshot_is_older() { + Date today = new Date(); + Date yesterday = DateUtils.addDays(today, -1); + + SnapshotDto snapshot = defaultSnapshot().setCreatedAt(today.getTime()); + SnapshotDto previousLastSnapshot = defaultSnapshot().setCreatedAt(yesterday.getTime()); + + boolean isLast = SnapshotDao.isLast(snapshot, previousLastSnapshot); + + assertThat(isLast).isTrue(); + } + + @Test + public void is_not_last_snapshot_when_previous_snapshot_is_newer() { + Date today = new Date(); + Date yesterday = DateUtils.addDays(today, -1); + + SnapshotDto snapshot = defaultSnapshot().setCreatedAt(yesterday.getTime()); + SnapshotDto previousLastSnapshot = defaultSnapshot().setCreatedAt(today.getTime()); + + boolean isLast = SnapshotDao.isLast(snapshot, previousLastSnapshot); + + assertThat(isLast).isFalse(); + } + + private static SnapshotDto defaultSnapshot() { + return new SnapshotDto() + .setComponentId(3L) + .setRootProjectId(1L) + .setParentId(2L) + .setRootId(1L) + .setStatus("P") + .setLast(true) + .setPurgeStatus(1) + .setDepth(1) + .setScope("DIR") + .setQualifier("PAC") + .setVersion("2.1-SNAPSHOT") + .setPath("1.2.") + .setPeriodMode(1, "days1") + .setPeriodMode(2, "days2") + .setPeriodMode(3, "days3") + .setPeriodMode(4, "days4") + .setPeriodMode(5, "days5") + .setPeriodParam(1, "30") + .setPeriodParam(2, "31") + .setPeriodParam(3, "32") + .setPeriodParam(4, "33") + .setPeriodParam(5, "34") + .setPeriodDate(1, 1_500_000_000_001L) + .setPeriodDate(2, 1_500_000_000_002L) + .setPeriodDate(3, 1_500_000_000_003L) + .setPeriodDate(4, 1_500_000_000_004L) + .setPeriodDate(5, 1_500_000_000_005L) + .setBuildDate(1_500_000_000_006L); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/compute/AnalysisReportDaoTest.java b/sonar-db/src/test/java/org/sonar/db/compute/AnalysisReportDaoTest.java new file mode 100644 index 00000000000..17bb66813b7 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/compute/AnalysisReportDaoTest.java @@ -0,0 +1,212 @@ +/* + * 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.db.compute; + +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.utils.System2; +import org.sonar.db.compute.AnalysisReportDao; +import org.sonar.db.compute.AnalysisReportDto; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.MyBatis; +import org.sonar.test.DbTests; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.db.compute.AnalysisReportDto.Status.PENDING; +import static org.sonar.db.compute.AnalysisReportDto.Status.WORKING; + +@Category(DbTests.class) +public class AnalysisReportDaoTest { + + private static final String DEFAULT_PROJECT_KEY = "123456789-987654321"; + + @ClassRule + public static DbTester db = new DbTester(); + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + AnalysisReportDao sut; + DbSession session; + System2 system2; + + @Before + public void before() { + this.session = db.myBatis().openSession(false); + this.system2 = mock(System2.class); + this.sut = new AnalysisReportDao(system2); + + when(system2.now()).thenReturn(1_500_000_000_000L); + } + + @After + public void after() { + MyBatis.closeQuietly(session); + } + + @Test + public void insert_multiple_reports() { + db.prepareDbUnit(getClass(), "empty.xml"); + + AnalysisReportDto report1 = new AnalysisReportDto().setProjectKey("ProjectKey1").setProjectName("Project 1").setUuid("UUID_1").setStatus(PENDING); + AnalysisReportDto report2 = new AnalysisReportDto().setProjectKey("ProjectKey2").setProjectName("Project 2").setUuid("UUID_2").setStatus(PENDING); + + sut.insert(session, report1); + sut.insert(session, report2); + session.commit(); + + db.assertDbUnit(getClass(), "insert-result.xml", "analysis_reports"); + } + + @Test + public void resetAllToPendingStatus() { + db.prepareDbUnit(getClass(), "update-all-to-status-pending.xml"); + + sut.resetAllToPendingStatus(session); + session.commit(); + + db.assertDbUnit(getClass(), "update-all-to-status-pending-result.xml", "analysis_reports"); + } + + @Test + public void truncate() { + db.prepareDbUnit(getClass(), "any-analysis-reports.xml"); + + sut.truncate(session); + session.commit(); + + db.assertDbUnit(getClass(), "truncate-result.xml", "analysis_reports"); + } + + @Test + public void find_one_report_by_project_key() { + db.prepareDbUnit(getClass(), "select.xml"); + + final String projectKey = "123456789-987654321"; + List<AnalysisReportDto> reports = sut.selectByProjectKey(session, projectKey); + AnalysisReportDto report = reports.get(0); + + assertThat(reports).hasSize(1); + assertThat(report.getProjectKey()).isEqualTo(projectKey); + assertThat(report.getProjectName()).isEqualTo("Project 1"); + assertThat(report.getStatus()).isEqualTo(AnalysisReportDto.Status.WORKING); + assertThat(report.getId()).isEqualTo(1); + } + + @Test + public void find_several_reports_by_project_key() { + db.prepareDbUnit(getClass(), "select.xml"); + + final String projectKey = "987654321-123456789"; + List<AnalysisReportDto> reports = sut.selectByProjectKey(session, projectKey); + + assertThat(reports).hasSize(2); + } + + @Test + public void pop_oldest_pending() { + db.prepareDbUnit(getClass(), "pop_oldest_pending.xml"); + + AnalysisReportDto nextAvailableReport = sut.pop(session); + + assertThat(nextAvailableReport.getId()).isEqualTo(3); + assertThat(nextAvailableReport.getProjectKey()).isEqualTo("P2"); + } + + @Test + public void pop_null_if_no_pending_reports() { + db.prepareDbUnit(getClass(), "pop_null_if_no_pending_reports.xml"); + + AnalysisReportDto nextAvailableReport = sut.pop(session); + + assertThat(nextAvailableReport).isNull(); + } + + @Test + public void getById_maps_all_the_fields_except_the_data() { + db.prepareDbUnit(getClass(), "one_analysis_report.xml"); + + AnalysisReportDto report = sut.selectById(session, 1L); + + assertThat(report.getProjectKey()).isEqualTo(DEFAULT_PROJECT_KEY); + assertThat(report.getCreatedAt()).isEqualTo(1_500_000_000_001L); + assertThat(report.getUpdatedAt()).isEqualTo(1_500_000_000_002L); + assertThat(report.getStartedAt()).isEqualTo(1_500_000_000_003L); + assertThat(report.getFinishedAt()).isEqualTo(1_500_000_000_004L); + assertThat(report.getStatus()).isEqualTo(WORKING); + } + + @Test + public void getById_returns_null_when_id_not_found() { + db.prepareDbUnit(getClass(), "select.xml"); + + AnalysisReportDto report = sut.selectById(session, 4L); + + assertThat(report).isNull(); + } + + @Test + public void delete_one_analysis_report() { + db.prepareDbUnit(getClass(), "one_analysis_report.xml"); + + sut.delete(session, 1); + session.commit(); + + db.assertDbUnit(getClass(), "truncate-result.xml", "analysis_reports"); + } + + @Test + public void findAll_one_analysis_report() { + db.prepareDbUnit(getClass(), "one_analysis_report.xml"); + + List<AnalysisReportDto> reports = sut.selectAll(session); + + assertThat(reports).hasSize(1); + } + + @Test + public void findAll_empty_table() { + db.prepareDbUnit(getClass(), "empty.xml"); + + List<AnalysisReportDto> reports = sut.selectAll(session); + + assertThat(reports).isEmpty(); + } + + @Test + public void findAll_three_analysis_reports() { + db.prepareDbUnit(getClass(), "three_analysis_reports.xml"); + + List<AnalysisReportDto> reports = sut.selectAll(session); + + assertThat(reports).hasSize(3); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/qualityprofile/ActiveRuleDaoTest.java b/sonar-db/src/test/java/org/sonar/db/dashboard/WidgetDaoTest.java index 7c3eeaa1d08..aa5afd5af14 100644 --- a/sonar-db/src/test/java/org/sonar/db/qualityprofile/ActiveRuleDaoTest.java +++ b/sonar-db/src/test/java/org/sonar/db/dashboard/WidgetDaoTest.java @@ -17,55 +17,53 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +package org.sonar.db.dashboard; -package org.sonar.db.qualityprofile; - -import java.util.List; +import java.util.Collection; +import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; -import org.sonar.db.AbstractDaoTestCase; +import org.junit.experimental.categories.Category; import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.MyBatis; +import org.sonar.test.DbTests; import static org.assertj.core.api.Assertions.assertThat; -public class ActiveRuleDaoTest extends AbstractDaoTestCase { +@Category(DbTests.class) +public class WidgetDaoTest { - ActiveRuleDao dao; + WidgetDao dao; - @Before - public void before() { - dao = new ActiveRuleDao(getMyBatis()); - } + @Rule + public DbTester dbTester = new DbTester(); - @Test - public void select_by_profile() { - setupData("shared"); + private DbSession session; - List<ActiveRuleDto> result = dao.selectByProfileKey("parent"); - assertThat(result).hasSize(2); + @Before + public void setUp() { + dao = new WidgetDao(dbTester.myBatis()); + session = dbTester.myBatis().openSession(false); } - @Test - public void insert_parameter() { - setupData("empty"); - - DbSession session = getMyBatis().openSession(false); - ActiveRuleParamDto dto = new ActiveRuleParamDto() - .setActiveRuleId(1) - .setRulesParameterId(1) - .setKey("max") - .setValue("20"); - dao.insert(dto, session); - session.commit(); - session.close(); - - checkTables("insert_parameter", "active_rule_parameters"); + @After + public void tearDown() { + MyBatis.closeQuietly(session); } @Test - public void select_params_by_profile_id() { - setupData("shared"); + public void should_select_all() { + dbTester.prepareDbUnit(this.getClass(), "before.xml"); + session.commit(); - assertThat(dao.selectParamsByProfileKey("child")).hasSize(2); + Collection<WidgetDto> widgets = dao.findAll(session); + assertThat(widgets).hasSize(5); + for (WidgetDto widget : widgets) { + assertThat(widget.getId()).isNotNull(); + assertThat(widget.getName()).isNotNull(); + assertThat(widget.getDescription()).isNotNull(); + } } } diff --git a/sonar-db/src/test/java/org/sonar/db/event/EventDaoTest.java b/sonar-db/src/test/java/org/sonar/db/event/EventDaoTest.java new file mode 100644 index 00000000000..4915c0e2291 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/event/EventDaoTest.java @@ -0,0 +1,116 @@ +/* + * 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.db.event; + +import java.util.List; +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.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.test.DbTests; + +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() { + dbTester.truncateTables(); + session = dbTester.myBatis().openSession(false); + dao = new EventDao(); + } + + @After + public void tearDown() { + session.close(); + } + + @Test + public void select_by_component_uuid() { + 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() { + 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() { + 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", new String[] {"id"}, "events"); + } + + @Test + public void delete() { + dbTester.prepareDbUnit(getClass(), "delete.xml"); + + dao.delete(session, 1L); + session.commit(); + + assertThat(dbTester.countRowsOfTable("events")).isEqualTo(0); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/issue/ActionPlanStatsDaoTest.java b/sonar-db/src/test/java/org/sonar/db/issue/ActionPlanStatsDaoTest.java index a70e1a3d08e..9a083137952 100644 --- a/sonar-db/src/test/java/org/sonar/db/issue/ActionPlanStatsDaoTest.java +++ b/sonar-db/src/test/java/org/sonar/db/issue/ActionPlanStatsDaoTest.java @@ -21,24 +21,23 @@ package org.sonar.db.issue; import java.util.Collection; -import org.junit.Before; +import org.junit.Rule; import org.junit.Test; -import org.sonar.db.AbstractDaoTestCase; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; import static org.assertj.core.api.Assertions.assertThat; -public class ActionPlanStatsDaoTest extends AbstractDaoTestCase { +public class ActionPlanStatsDaoTest { - ActionPlanStatsDao dao; + @Rule + public DbTester dbTester = DbTester.create(System2.INSTANCE); - @Before - public void createDao() { - dao = new ActionPlanStatsDao(getMyBatis()); - } + ActionPlanStatsDao dao = dbTester.getDbClient().getActionPlanStatsDao(); @Test public void should_find_by_project() { - setupData("shared", "should_find_by_project"); + dbTester.prepareDbUnit(getClass(), "shared.xml", "should_find_by_project.xml"); Collection<ActionPlanStatsDto> result = dao.findByProjectId(1l); assertThat(result).isNotEmpty(); diff --git a/sonar-db/src/test/java/org/sonar/db/issue/IssueDaoTest.java b/sonar-db/src/test/java/org/sonar/db/issue/IssueDaoTest.java index 24f556df1e6..dc64f45d05d 100644 --- a/sonar-db/src/test/java/org/sonar/db/issue/IssueDaoTest.java +++ b/sonar-db/src/test/java/org/sonar/db/issue/IssueDaoTest.java @@ -20,12 +20,17 @@ package org.sonar.db.issue; +import java.util.Arrays; +import java.util.List; import org.apache.ibatis.executor.result.DefaultResultHandler; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.sonar.api.rule.RuleKey; import org.sonar.db.AbstractDaoTestCase; import org.sonar.db.DbSession; +import org.sonar.db.component.ComponentDto; +import org.sonar.db.rule.RuleTesting; import static org.assertj.core.api.Assertions.assertThat; @@ -91,4 +96,116 @@ public class IssueDaoTest extends AbstractDaoTestCase { assertThat(issue.getComponentKey()).isNotNull(); assertThat(issue.getProjectKey()).isNull(); } + + @Test + public void get_by_key() { + setupData("shared", "get_by_key"); + + IssueDto issue = dao.selectByKey(session, "ABCDE"); + assertThat(issue.getKee()).isEqualTo("ABCDE"); + assertThat(issue.getId()).isEqualTo(100L); + assertThat(issue.getComponentUuid()).isEqualTo("CDEF"); + assertThat(issue.getProjectUuid()).isEqualTo("ABCD"); + assertThat(issue.getRuleId()).isEqualTo(500); + assertThat(issue.getLanguage()).isEqualTo("java"); + assertThat(issue.getSeverity()).isEqualTo("BLOCKER"); + assertThat(issue.isManualSeverity()).isFalse(); + assertThat(issue.getMessage()).isNull(); + assertThat(issue.getLine()).isEqualTo(200); + assertThat(issue.getEffortToFix()).isEqualTo(4.2); + assertThat(issue.getStatus()).isEqualTo("OPEN"); + assertThat(issue.getResolution()).isEqualTo("FIXED"); + assertThat(issue.getChecksum()).isEqualTo("XXX"); + assertThat(issue.getAuthorLogin()).isEqualTo("karadoc"); + assertThat(issue.getReporter()).isEqualTo("arthur"); + assertThat(issue.getAssignee()).isEqualTo("perceval"); + assertThat(issue.getIssueAttributes()).isEqualTo("JIRA=FOO-1234"); + assertThat(issue.getIssueCreationDate()).isNotNull(); + assertThat(issue.getIssueUpdateDate()).isNotNull(); + assertThat(issue.getIssueCloseDate()).isNotNull(); + assertThat(issue.getCreatedAt()).isEqualTo(1400000000000L); + assertThat(issue.getUpdatedAt()).isEqualTo(1450000000000L); + assertThat(issue.getRuleRepo()).isEqualTo("squid"); + assertThat(issue.getRule()).isEqualTo("AvoidCycle"); + assertThat(issue.getComponentKey()).isEqualTo("Action.java"); + assertThat(issue.getProjectKey()).isEqualTo("struts"); + } + + @Test + public void get_by_keys() { + setupData("shared", "get_by_key"); + + List<IssueDto> issues = dao.selectByKeys(session, Arrays.asList("ABCDE")); + assertThat(issues).hasSize(1); + } + + @Test + public void find_by_action_plan() { + setupData("shared", "find_by_action_plan"); + + List<IssueDto> issues = dao.findByActionPlan(session, "AP-1"); + assertThat(issues).hasSize(1); + + IssueDto issue = issues.get(0); + assertThat(issue.getKee()).isEqualTo("ABCDE"); + assertThat(issue.getActionPlanKey()).isEqualTo("AP-1"); + assertThat(issue.getComponentUuid()).isEqualTo("CDEF"); + assertThat(issue.getProjectUuid()).isEqualTo("ABCD"); + assertThat(issue.getRuleId()).isEqualTo(500); + assertThat(issue.getLanguage()).isEqualTo("java"); + assertThat(issue.getSeverity()).isEqualTo("BLOCKER"); + assertThat(issue.isManualSeverity()).isFalse(); + assertThat(issue.getMessage()).isNull(); + assertThat(issue.getLine()).isEqualTo(200); + assertThat(issue.getEffortToFix()).isEqualTo(4.2); + assertThat(issue.getStatus()).isEqualTo("OPEN"); + assertThat(issue.getResolution()).isEqualTo("FIXED"); + assertThat(issue.getChecksum()).isEqualTo("XXX"); + assertThat(issue.getAuthorLogin()).isEqualTo("karadoc"); + assertThat(issue.getReporter()).isEqualTo("arthur"); + assertThat(issue.getAssignee()).isEqualTo("perceval"); + assertThat(issue.getIssueAttributes()).isEqualTo("JIRA=FOO-1234"); + assertThat(issue.getIssueCreationDate()).isNotNull(); + assertThat(issue.getIssueUpdateDate()).isNotNull(); + assertThat(issue.getIssueCloseDate()).isNotNull(); + assertThat(issue.getCreatedAt()).isNotNull(); + assertThat(issue.getUpdatedAt()).isNotNull(); + assertThat(issue.getRuleRepo()).isEqualTo("squid"); + assertThat(issue.getRule()).isEqualTo("AvoidCycle"); + assertThat(issue.getComponentKey()).isEqualTo("Action.java"); + assertThat(issue.getProjectKey()).isEqualTo("struts"); + } + + @Test + public void insert() { + IssueDto dto = new IssueDto(); + dto.setComponent(new ComponentDto().setKey("struts:Action").setId(123L).setUuid("component-uuid")); + dto.setProject(new ComponentDto().setKey("struts").setId(100L).setUuid("project-uuid")); + dto.setRule(RuleTesting.newDto(RuleKey.of("squid", "S001")).setId(200)); + dto.setKee("ABCDE"); + dto.setLine(500); + dto.setEffortToFix(3.14); + dto.setDebt(10L); + dto.setResolution("FIXED"); + dto.setStatus("RESOLVED"); + dto.setSeverity("BLOCKER"); + dto.setReporter("emmerik"); + dto.setAuthorLogin("morgan"); + dto.setAssignee("karadoc"); + dto.setActionPlanKey("current_sprint"); + dto.setIssueAttributes("JIRA=FOO-1234"); + dto.setChecksum("123456789"); + dto.setMessage("the message"); + + dto.setIssueCreationTime(1_500_000_000_000L); + dto.setIssueUpdateTime(1_500_000_000_001L); + dto.setIssueCloseTime(1_500_000_000_002L); + dto.setCreatedAt(1_400_000_000_000L); + dto.setUpdatedAt(1_450_000_000_000L); + + dao.insert(session, dto); + session.commit(); + + checkTables("insert", new String[] {"id"}, "issues"); + } } diff --git a/sonar-db/src/test/java/org/sonar/db/measure/MeasureDaoTest.java b/sonar-db/src/test/java/org/sonar/db/measure/MeasureDaoTest.java new file mode 100644 index 00000000000..9621d6aa945 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/measure/MeasureDaoTest.java @@ -0,0 +1,333 @@ +/* + * 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.db.measure; + +import com.google.common.base.Function; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableSet; +import java.util.List; +import java.util.Map; +import javax.annotation.Nullable; +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.db.measure.MeasureDao; +import org.sonar.db.measure.MeasureDto; +import org.sonar.db.measure.PastMeasureDto; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.test.DbTests; + +import static com.google.common.collect.Lists.newArrayList; +import static org.assertj.core.api.Assertions.assertThat; + +@Category(DbTests.class) +public class MeasureDaoTest { + + @ClassRule + public static DbTester db = new DbTester(); + + DbSession session; + MeasureDao sut; + + @Before + public void setUp() { + db.truncateTables(); + session = db.myBatis().openSession(false); + sut = new MeasureDao(); + } + + @After + public void tearDown() { + session.close(); + } + + @Test + public void get_value_by_key() { + db.prepareDbUnit(getClass(), "shared.xml"); + + MeasureDto result = sut.findByComponentKeyAndMetricKey(session, "org.struts:struts-core:src/org/struts/RequestContext.java", "ncloc"); + assertThat(result.getId()).isEqualTo(22); + assertThat(result.getValue()).isEqualTo(10d); + assertThat(result.getData()).isNull(); + assertThat(result.getVariation(1)).isEqualTo(1d); + assertThat(result.getVariation(2)).isEqualTo(2d); + assertThat(result.getVariation(3)).isEqualTo(3d); + assertThat(result.getVariation(4)).isEqualTo(4d); + assertThat(result.getVariation(5)).isEqualTo(-5d); + assertThat(result.getAlertStatus()).isEqualTo("OK"); + assertThat(result.getAlertText()).isEqualTo("Green"); + } + + @Test + // TODO the string must be longer than 4000 char to be persisted in the data field + public void get_data_by_key() { + db.prepareDbUnit(getClass(), "shared.xml"); + + MeasureDto result = sut.findByComponentKeyAndMetricKey(session, "org.struts:struts-core:src/org/struts/RequestContext.java", "authors_by_line"); + assertThat(result.getId()).isEqualTo(20); + assertThat(result.getData()).isEqualTo("0123456789012345678901234567890123456789"); + } + + @Test + public void get_text_value_by_key() { + db.prepareDbUnit(getClass(), "shared.xml"); + + MeasureDto result = sut.findByComponentKeyAndMetricKey(session, "org.struts:struts-core:src/org/struts/RequestContext.java", "coverage_line_hits_data"); + assertThat(result.getId()).isEqualTo(21); + assertThat(result.getData()).isEqualTo("36=1;37=1;38=1;39=1;43=1;48=1;53=1"); + } + + @Test + public void find_by_component_key_and_metrics() { + db.prepareDbUnit(getClass(), "shared.xml"); + + List<MeasureDto> results = sut.findByComponentKeyAndMetricKeys(session, "org.struts:struts-core:src/org/struts/RequestContext.java", + newArrayList("ncloc", "authors_by_line")); + assertThat(results).hasSize(2); + + results = sut.findByComponentKeyAndMetricKeys(session, "org.struts:struts-core:src/org/struts/RequestContext.java", newArrayList("ncloc")); + assertThat(results).hasSize(1); + + MeasureDto result = results.get(0); + assertThat(result.getId()).isEqualTo(22); + assertThat(result.getValue()).isEqualTo(10d); + assertThat(result.getComponentKey()).isEqualTo("org.struts:struts-core:src/org/struts/RequestContext.java"); + assertThat(result.getMetricKey()).isEqualTo("ncloc"); + assertThat(result.getVariation(1)).isEqualTo(1d); + assertThat(result.getVariation(2)).isEqualTo(2d); + assertThat(result.getVariation(3)).isEqualTo(3d); + assertThat(result.getVariation(4)).isEqualTo(4d); + assertThat(result.getVariation(5)).isEqualTo(-5d); + } + + @Test + public void find_by_component_key_and_metric() { + db.prepareDbUnit(getClass(), "shared.xml"); + + MeasureDto result = sut.findByComponentKeyAndMetricKey(session, "org.struts:struts-core:src/org/struts/RequestContext.java", "ncloc"); + assertThat(result.getId()).isEqualTo(22); + assertThat(result.getValue()).isEqualTo(10d); + assertThat(result.getMetricKey()).isEqualTo("ncloc"); + assertThat(result.getComponentKey()).isEqualTo("org.struts:struts-core:src/org/struts/RequestContext.java"); + assertThat(result.getVariation(1)).isEqualTo(1d); + assertThat(result.getVariation(2)).isEqualTo(2d); + assertThat(result.getVariation(3)).isEqualTo(3d); + assertThat(result.getVariation(4)).isEqualTo(4d); + assertThat(result.getVariation(5)).isEqualTo(-5d); + + assertThat(sut.findByComponentKeyAndMetricKey(session, "org.struts:struts-core:src/org/struts/RequestContext.java", "unknown")).isNull(); + } + + @Test + public void exists_by_key() { + db.prepareDbUnit(getClass(), "shared.xml"); + + assertThat(sut.existsByKey(session, "org.struts:struts-core:src/org/struts/RequestContext.java", "ncloc")).isTrue(); + assertThat(sut.existsByKey(session, "org.struts:struts-core:src/org/struts/RequestContext.java", "unknown")).isFalse(); + } + + @Test + public void select_past_measures_by_component_uuid_and_root_snapshot_id_and_metric_keys() { + db.prepareDbUnit(getClass(), "past_measures.xml"); + + List<PastMeasureDto> fileMeasures = sut.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(session, "CDEF", 1000L, ImmutableSet.of(1, 2)); + assertThat(fileMeasures).hasSize(2); + + PastMeasureDto fileMeasure1 = fileMeasures.get(0); + assertThat(fileMeasure1.getValue()).isEqualTo(5d); + assertThat(fileMeasure1.getMetricId()).isEqualTo(1); + assertThat(fileMeasure1.getRuleId()).isNull(); + assertThat(fileMeasure1.getCharacteristicId()).isNull(); + assertThat(fileMeasure1.getPersonId()).isNull(); + + PastMeasureDto fileMeasure2 = fileMeasures.get(1); + assertThat(fileMeasure2.getValue()).isEqualTo(60d); + assertThat(fileMeasure2.getMetricId()).isEqualTo(2); + + List<PastMeasureDto> projectMeasures = sut.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(session, "ABCD", 1000L, ImmutableSet.of(1, 2)); + assertThat(projectMeasures).hasSize(2); + + PastMeasureDto projectMeasure1 = projectMeasures.get(0); + assertThat(projectMeasure1.getValue()).isEqualTo(60d); + assertThat(projectMeasure1.getMetricId()).isEqualTo(1); + + PastMeasureDto projectMeasure2 = projectMeasures.get(1); + assertThat(projectMeasure2.getValue()).isEqualTo(80d); + assertThat(projectMeasure2.getMetricId()).isEqualTo(2); + + assertThat(sut.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(session, "UNKNOWN", 1000L, ImmutableSet.of(1, 2))).isEmpty(); + assertThat(sut.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(session, "CDEF", 987654L, ImmutableSet.of(1, 2))).isEmpty(); + assertThat(sut.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(session, "CDEF", 1000L, ImmutableSet.of(123, 456))).isEmpty(); + } + + @Test + public void select_past_measures_on_rule_by_component_uuid_and_root_snapshot_id_and_metric_keys() { + db.prepareDbUnit(getClass(), "past_measures_with_rule_id.xml"); + + List<PastMeasureDto> measures = sut.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(session, "ABCD", 1000L, ImmutableSet.of(1)); + assertThat(measures).hasSize(3); + + Map<Long, PastMeasureDto> pastMeasuresById = pastMeasuresById(measures); + + PastMeasureDto measure1 = pastMeasuresById.get(1L); + assertThat(measure1.getValue()).isEqualTo(60d); + assertThat(measure1.getMetricId()).isEqualTo(1); + assertThat(measure1.getRuleId()).isNull(); + assertThat(measure1.getCharacteristicId()).isNull(); + assertThat(measure1.getPersonId()).isNull(); + + PastMeasureDto measure2 = pastMeasuresById.get(2L); + assertThat(measure2.getValue()).isEqualTo(20d); + assertThat(measure2.getMetricId()).isEqualTo(1); + assertThat(measure2.getRuleId()).isEqualTo(30); + assertThat(measure2.getCharacteristicId()).isNull(); + assertThat(measure2.getPersonId()).isNull(); + + PastMeasureDto measure3 = pastMeasuresById.get(3L); + assertThat(measure3.getValue()).isEqualTo(40d); + assertThat(measure3.getMetricId()).isEqualTo(1); + assertThat(measure3.getRuleId()).isEqualTo(31); + assertThat(measure3.getCharacteristicId()).isNull(); + assertThat(measure3.getPersonId()).isNull(); + } + + @Test + public void select_past_measures_on_characteristic_by_component_uuid_and_root_snapshot_id_and_metric_keys() { + db.prepareDbUnit(getClass(), "past_measures_with_characteristic_id.xml"); + + List<PastMeasureDto> measures = sut.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(session, "ABCD", 1000L, ImmutableSet.of(1)); + assertThat(measures).hasSize(3); + + Map<Long, PastMeasureDto> pastMeasuresById = pastMeasuresById(measures); + + PastMeasureDto measure1 = pastMeasuresById.get(1L); + assertThat(measure1.getValue()).isEqualTo(60d); + assertThat(measure1.getMetricId()).isEqualTo(1); + assertThat(measure1.getRuleId()).isNull(); + assertThat(measure1.getCharacteristicId()).isNull(); + assertThat(measure1.getPersonId()).isNull(); + + PastMeasureDto measure2 = pastMeasuresById.get(2L); + assertThat(measure2.getValue()).isEqualTo(20d); + assertThat(measure2.getMetricId()).isEqualTo(1); + assertThat(measure2.getRuleId()).isNull(); + assertThat(measure2.getCharacteristicId()).isEqualTo(10); + assertThat(measure2.getPersonId()).isNull(); + + PastMeasureDto measure3 = pastMeasuresById.get(3L); + assertThat(measure3.getValue()).isEqualTo(40d); + assertThat(measure3.getMetricId()).isEqualTo(1); + assertThat(measure3.getRuleId()).isNull(); + assertThat(measure3.getCharacteristicId()).isEqualTo(11); + assertThat(measure3.getPersonId()).isNull(); + } + + @Test + public void select_past_measures_on_person_by_component_uuid_and_root_snapshot_id_and_metric_keys() { + db.prepareDbUnit(getClass(), "past_measures_with_person_id.xml"); + + List<PastMeasureDto> measures = sut.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(session, "ABCD", 1000L, ImmutableSet.of(1)); + assertThat(measures).hasSize(3); + + Map<Long, PastMeasureDto> pastMeasuresById = pastMeasuresById(measures); + + PastMeasureDto measure1 = pastMeasuresById.get(1L); + assertThat(measure1.getValue()).isEqualTo(60d); + assertThat(measure1.getMetricId()).isEqualTo(1); + assertThat(measure1.getRuleId()).isNull(); + assertThat(measure1.getCharacteristicId()).isNull(); + assertThat(measure1.getPersonId()).isNull(); + + PastMeasureDto measure2 = pastMeasuresById.get(2L); + assertThat(measure2.getValue()).isEqualTo(20d); + assertThat(measure2.getMetricId()).isEqualTo(1); + assertThat(measure2.getRuleId()).isNull(); + assertThat(measure2.getCharacteristicId()).isNull(); + assertThat(measure2.getPersonId()).isEqualTo(20); + + PastMeasureDto measure3 = pastMeasuresById.get(3L); + assertThat(measure3.getValue()).isEqualTo(40d); + assertThat(measure3.getMetricId()).isEqualTo(1); + assertThat(measure3.getRuleId()).isNull(); + assertThat(measure3.getCharacteristicId()).isNull(); + assertThat(measure3.getPersonId()).isEqualTo(21); + } + + @Test + public void insert() { + db.prepareDbUnit(getClass(), "empty.xml"); + + sut.insert(session, new MeasureDto() + .setSnapshotId(2L) + .setMetricId(3) + .setCharacteristicId(4) + .setPersonId(23) + .setRuleId(5) + .setComponentId(6L) + .setValue(2.0d) + .setData("measure-value") + .setVariation(1, 1.0d) + .setVariation(2, 2.0d) + .setVariation(3, 3.0d) + .setVariation(4, 4.0d) + .setVariation(5, 5.0d) + .setAlertStatus("alert") + .setAlertText("alert-text") + .setDescription("measure-description") + ); + session.commit(); + + db.assertDbUnit(getClass(), "insert-result.xml", new String[] {"id"}, "project_measures"); + } + + @Test + public void insert_measures() { + db.prepareDbUnit(getClass(), "empty.xml"); + + sut.insert(session, new MeasureDto() + .setSnapshotId(2L) + .setMetricId(3) + .setComponentId(6L) + .setValue(2.0d), + new MeasureDto() + .setSnapshotId(3L) + .setMetricId(4) + .setComponentId(6L) + .setValue(4.0d) + ); + session.commit(); + + assertThat(db.countRowsOfTable("project_measures")).isEqualTo(2); + } + + private static Map<Long, PastMeasureDto> pastMeasuresById(List<PastMeasureDto> pastMeasures) { + return FluentIterable.from(pastMeasures).uniqueIndex(new Function<PastMeasureDto, Long>() { + @Nullable + @Override + public Long apply(PastMeasureDto input) { + return input.getId(); + } + }); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/purge/PurgeDaoTest.java b/sonar-db/src/test/java/org/sonar/db/purge/PurgeDaoTest.java index 592e42b406e..11aa33abc18 100644 --- a/sonar-db/src/test/java/org/sonar/db/purge/PurgeDaoTest.java +++ b/sonar-db/src/test/java/org/sonar/db/purge/PurgeDaoTest.java @@ -55,7 +55,7 @@ public class PurgeDaoTest extends AbstractDaoTestCase { when(system2.now()).thenReturn(1450000000000L); dbSession = getMyBatis().openSession(false); - sut = new PurgeDao(getMyBatis(), new ResourceDao(getMyBatis(), system2), new PurgeProfiler(), system2); + sut = new PurgeDao(getMyBatis(), new ResourceDao(getMyBatis(), system2), system2); } @After @@ -66,14 +66,14 @@ public class PurgeDaoTest extends AbstractDaoTestCase { @Test public void shouldDeleteAbortedBuilds() { setupData("shouldDeleteAbortedBuilds"); - sut.purge(newConfigurationWith30Days(), PurgeListener.EMPTY); + sut.purge(newConfigurationWith30Days(), PurgeListener.EMPTY, new PurgeProfiler()); checkTables("shouldDeleteAbortedBuilds", "snapshots"); } @Test public void should_purge_project() { setupData("shouldPurgeProject"); - sut.purge(newConfigurationWith30Days(), PurgeListener.EMPTY); + sut.purge(newConfigurationWith30Days(), PurgeListener.EMPTY, new PurgeProfiler()); checkTables("shouldPurgeProject", "projects", "snapshots"); } @@ -88,28 +88,28 @@ public class PurgeDaoTest extends AbstractDaoTestCase { @Test public void delete_file_sources_of_disabled_resources() { setupData("delete_file_sources_of_disabled_resources"); - sut.purge(newConfigurationWith30Days(system2), PurgeListener.EMPTY); + sut.purge(newConfigurationWith30Days(system2), PurgeListener.EMPTY, new PurgeProfiler()); checkTables("delete_file_sources_of_disabled_resources", "file_sources"); } @Test public void shouldDeleteHistoricalDataOfDirectoriesAndFiles() { setupData("shouldDeleteHistoricalDataOfDirectoriesAndFiles"); - sut.purge(new PurgeConfiguration(new IdUuidPair(1L, "1"), new String[] {Scopes.DIRECTORY, Scopes.FILE}, 30), PurgeListener.EMPTY); + sut.purge(new PurgeConfiguration(new IdUuidPair(1L, "1"), new String[] {Scopes.DIRECTORY, Scopes.FILE}, 30), PurgeListener.EMPTY, new PurgeProfiler()); checkTables("shouldDeleteHistoricalDataOfDirectoriesAndFiles", "projects", "snapshots"); } @Test public void disable_resources_without_last_snapshot() { setupData("disable_resources_without_last_snapshot"); - sut.purge(newConfigurationWith30Days(system2), PurgeListener.EMPTY); + sut.purge(newConfigurationWith30Days(system2), PurgeListener.EMPTY, new PurgeProfiler()); checkTables("disable_resources_without_last_snapshot", new String[] {"issue_close_date", "issue_update_date"}, "projects", "snapshots", "issues"); } @Test public void shouldDeleteSnapshots() { setupData("shouldDeleteSnapshots"); - sut.deleteSnapshots(PurgeSnapshotQuery.create().setIslast(false).setResourceId(1L)); + sut.deleteSnapshots(PurgeSnapshotQuery.create().setIslast(false).setResourceId(1L), new PurgeProfiler()); checkTables("shouldDeleteSnapshots", "snapshots"); } @@ -130,21 +130,21 @@ public class PurgeDaoTest extends AbstractDaoTestCase { @Test public void should_delete_project_and_associated_data() { setupData("shouldDeleteProject"); - sut.deleteResourceTree(new IdUuidPair(1L, "A")); + sut.deleteResourceTree(new IdUuidPair(1L, "A"), new PurgeProfiler()); assertEmptyTables("projects", "snapshots", "action_plans", "issues", "issue_changes", "file_sources"); } @Test public void should_delete_old_closed_issues() { setupData("should_delete_old_closed_issues"); - sut.purge(newConfigurationWith30Days(), PurgeListener.EMPTY); + sut.purge(newConfigurationWith30Days(), PurgeListener.EMPTY, new PurgeProfiler()); checkTables("should_delete_old_closed_issues", "issues", "issue_changes"); } @Test public void should_delete_all_closed_issues() { setupData("should_delete_all_closed_issues"); - sut.purge(new PurgeConfiguration(new IdUuidPair(1L, "1"), new String[0], 0), PurgeListener.EMPTY); + sut.purge(new PurgeConfiguration(new IdUuidPair(1L, "1"), new String[0], 0), PurgeListener.EMPTY, new PurgeProfiler()); checkTables("should_delete_all_closed_issues", "issues", "issue_changes"); } diff --git a/sonar-db/src/test/java/org/sonar/db/purge/period/DefaultPeriodCleanerTest.java b/sonar-db/src/test/java/org/sonar/db/purge/period/DefaultPeriodCleanerTest.java index 1aa9d8aebcb..857b58ed48a 100644 --- a/sonar-db/src/test/java/org/sonar/db/purge/period/DefaultPeriodCleanerTest.java +++ b/sonar-db/src/test/java/org/sonar/db/purge/period/DefaultPeriodCleanerTest.java @@ -30,9 +30,11 @@ import org.mockito.stubbing.Answer; import org.sonar.api.utils.System2; import org.sonar.db.DbSession; import org.sonar.db.purge.PurgeDao; +import org.sonar.db.purge.PurgeProfiler; import org.sonar.db.purge.PurgeSnapshotQuery; import org.sonar.db.purge.PurgeableSnapshotDto; +import static org.mockito.Matchers.any; import static org.mockito.Mockito.anyListOf; import static org.mockito.Mockito.argThat; import static org.mockito.Mockito.eq; @@ -52,13 +54,13 @@ public class DefaultPeriodCleanerTest { Filter filter1 = newLazyFilter(); Filter filter2 = newLazyFilter(); - DefaultPeriodCleaner cleaner = new DefaultPeriodCleaner(dao); + DefaultPeriodCleaner cleaner = new DefaultPeriodCleaner(dao, new PurgeProfiler()); cleaner.doClean(123L, Arrays.asList(filter1, filter2), session); verify(filter1).log(); verify(filter2).log(); - verify(dao, times(2)).deleteSnapshots(argThat(newRootSnapshotQuery()), eq(session)); - verify(dao, times(2)).deleteSnapshots(argThat(newSnapshotIdQuery()), eq(session)); + verify(dao, times(2)).deleteSnapshots(argThat(newRootSnapshotQuery()), eq(session), any(PurgeProfiler.class)); + verify(dao, times(2)).deleteSnapshots(argThat(newSnapshotIdQuery()), eq(session), any(PurgeProfiler.class)); } private BaseMatcher<PurgeSnapshotQuery> newRootSnapshotQuery() { diff --git a/sonar-db/src/test/java/org/sonar/db/rule/RuleTesting.java b/sonar-db/src/test/java/org/sonar/db/rule/RuleTesting.java new file mode 100644 index 00000000000..1b744886d6f --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/rule/RuleTesting.java @@ -0,0 +1,105 @@ +/* + * 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.db.rule; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableSet; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.rule.RuleStatus; +import org.sonar.api.rule.Severity; +import org.sonar.db.rule.RuleDto.Format; + +/** + * Utility class for tests involving rules + */ +public class RuleTesting { + + public static final RuleKey XOO_X1 = RuleKey.of("xoo", "x1"); + public static final RuleKey XOO_X2 = RuleKey.of("xoo", "x2"); + public static final RuleKey XOO_X3 = RuleKey.of("xoo", "x3"); + + private RuleTesting() { + // only static helpers + } + + public static RuleDto newXooX1() { + return newDto(XOO_X1).setLanguage("xoo"); + } + + public static RuleDto newXooX2() { + return newDto(XOO_X2).setLanguage("xoo"); + } + + public static RuleDto newXooX3() { + return newDto(XOO_X3).setLanguage("xoo"); + } + + /** + * Full RuleDto used to feed database with fake data. Tests must not rely on the + * field contents declared here. They should override the fields they need to test, + * for example: + * <pre> + * ruleDao.insert(dbSession, RuleTesting.newDto(key).setStatus(RuleStatus.BETA)); + * </pre> + */ + public static RuleDto newDto(RuleKey ruleKey) { + return new RuleDto() + .setRuleKey(ruleKey.rule()) + .setRepositoryKey(ruleKey.repository()) + .setName("Rule " + ruleKey.rule()) + .setDescription("Description " + ruleKey.rule()) + .setDescriptionFormat(Format.HTML) + .setStatus(RuleStatus.READY) + .setConfigKey("InternalKey" + ruleKey.rule()) + .setSeverity(Severity.INFO) + .setIsTemplate(false) + .setTags(ImmutableSet.of("tag1", "tag2")) + .setSystemTags(ImmutableSet.of("systag1", "systag2")) + .setLanguage("js") + .setRemediationFunction("LINEAR") + .setDefaultRemediationFunction("LINEAR_OFFSET") + .setRemediationCoefficient("1h") + .setDefaultRemediationCoefficient("5d") + .setRemediationOffset("5min") + .setDefaultRemediationOffset("10h") + .setEffortToFixDescription(ruleKey.repository() + "." + ruleKey.rule() + ".effortToFix"); + } + + public static RuleDto newTemplateRule(RuleKey ruleKey) { + return newDto(ruleKey) + .setIsTemplate(true); + } + + public static RuleDto newCustomRule(RuleDto templateRule) { + Preconditions.checkNotNull(templateRule.getId(), "The template rule need to be persisted before creating this custom rule."); + return newDto(RuleKey.of(templateRule.getRepositoryKey(), templateRule.getRuleKey() + "_" + System.currentTimeMillis())) + .setLanguage(templateRule.getLanguage()) + .setTemplateId(templateRule.getId()); + } + + public static RuleDto newManualRule(String manualKey) { + return new RuleDto().setRuleKey(manualKey) + .setName("Name " + manualKey) + .setRepositoryKey(RuleKey.MANUAL_REPOSITORY_KEY) + .setDescription("Description " + manualKey) + .setStatus(RuleStatus.READY); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/source/FileSourceDaoTest.java b/sonar-db/src/test/java/org/sonar/db/source/FileSourceDaoTest.java new file mode 100644 index 00000000000..09d7fbcff1b --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/source/FileSourceDaoTest.java @@ -0,0 +1,175 @@ +/* + * 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.db.source; + +import com.google.common.base.Function; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import org.apache.commons.io.IOUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.sonar.db.AbstractDaoTestCase; +import org.sonar.db.DbSession; +import org.sonar.db.source.FileSourceDto.Type; + +import static org.assertj.core.api.Assertions.assertThat; + +public class FileSourceDaoTest extends AbstractDaoTestCase { + + DbSession session; + + FileSourceDao sut; + + @Before + public void setUpTestData() { + session = getMyBatis().openSession(false); + sut = new FileSourceDao(getMyBatis()); + } + + @After + public void tearDown() { + session.close(); + } + + @Test + public void select() { + setupData("shared"); + + FileSourceDto fileSourceDto = sut.selectSource("FILE1_UUID"); + + assertThat(fileSourceDto.getBinaryData()).isNotEmpty(); + assertThat(fileSourceDto.getDataHash()).isEqualTo("hash"); + assertThat(fileSourceDto.getProjectUuid()).isEqualTo("PRJ_UUID"); + assertThat(fileSourceDto.getFileUuid()).isEqualTo("FILE1_UUID"); + assertThat(fileSourceDto.getCreatedAt()).isEqualTo(1500000000000L); + assertThat(fileSourceDto.getUpdatedAt()).isEqualTo(1500000000000L); + assertThat(fileSourceDto.getDataType()).isEqualTo(Type.SOURCE); + } + + @Test + public void select_line_hashes() { + setupData("shared"); + + ReaderToStringFunction fn = new ReaderToStringFunction(); + sut.readLineHashesStream(session, "FILE1_UUID", fn); + + assertThat(fn.result).isEqualTo("ABC\\nDEF\\nGHI"); + } + + @Test + public void no_line_hashes_on_unknown_file() { + setupData("shared"); + + ReaderToStringFunction fn = new ReaderToStringFunction(); + sut.readLineHashesStream(session, "unknown", fn); + + assertThat(fn.result).isNull(); + } + + @Test + public void no_line_hashes_when_only_test_data() { + setupData("no_line_hashes_when_only_test_data"); + + ReaderToStringFunction fn = new ReaderToStringFunction(); + sut.readLineHashesStream(session, "FILE1_UUID", fn); + + assertThat(fn.result).isNull(); + } + + @Test + public void insert() { + setupData("shared"); + + sut.insert(new FileSourceDto() + .setProjectUuid("PRJ_UUID") + .setFileUuid("FILE2_UUID") + .setBinaryData("FILE2_BINARY_DATA".getBytes()) + .setDataHash("FILE2_DATA_HASH") + .setLineHashes("LINE1_HASH\\nLINE2_HASH") + .setSrcHash("FILE2_HASH") + .setDataType(Type.SOURCE) + .setCreatedAt(1500000000000L) + .setUpdatedAt(1500000000001L)); + + checkTable("insert", "file_sources", "project_uuid", "file_uuid", "data_hash", "line_hashes", "src_hash", "created_at", "updated_at", "data_type"); + } + + @Test + public void update() { + setupData("shared"); + + sut.update(new FileSourceDto() + .setId(101L) + .setProjectUuid("PRJ_UUID") + .setFileUuid("FILE1_UUID") + .setBinaryData("updated data".getBytes()) + .setDataHash("NEW_DATA_HASH") + .setSrcHash("NEW_FILE_HASH") + .setLineHashes("NEW_LINE_HASHES") + .setDataType(Type.SOURCE) + .setUpdatedAt(1500000000002L)); + + checkTable("update", "file_sources", "project_uuid", "file_uuid", "data_hash", "line_hashes", "src_hash", "created_at", "updated_at", "data_type"); + } + + @Test + public void update_date_when_updated_date_is_zero() { + setupData("update_date_when_updated_date_is_zero"); + + sut.updateDateWhenUpdatedDateIsZero(session, "ABCD", 1500000000002L); + session.commit(); + + checkTable("update_date_when_updated_date_is_zero", "file_sources", "project_uuid", "file_uuid", "data_hash", "line_hashes", "src_hash", "created_at", "updated_at", + "data_type"); + } + + private static class ReaderToStringFunction implements Function<Reader, String> { + + String result = null; + + @Override + public String apply(Reader input) { + try { + result = IOUtils.toString(input); + return IOUtils.toString(input); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + private static class InputStreamToStringFunction implements Function<InputStream, String> { + + String result = null; + + @Override + public String apply(InputStream input) { + try { + result = IOUtils.toString(input); + return IOUtils.toString(input); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/user/UserGroupDaoTest.java b/sonar-db/src/test/java/org/sonar/db/user/UserGroupDaoTest.java new file mode 100644 index 00000000000..ff1c8cfecef --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/user/UserGroupDaoTest.java @@ -0,0 +1,69 @@ +/* + * 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.db.user; + +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.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.test.DbTests; + +@Category(DbTests.class) +public class UserGroupDaoTest { + + @ClassRule + public static DbTester db = new DbTester(); + + private UserGroupDao dao; + private DbSession session; + + @Before + public void before() { + db.truncateTables(); + this.session = db.myBatis().openSession(false); + this.dao = new UserGroupDao(); + } + + @After + public void after() { + this.session.close(); + } + + @Test + public void insert() { + UserGroupDto userGroupDto = new UserGroupDto().setUserId(1L).setGroupId(2L); + dao.insert(session, userGroupDto); + session.commit(); + + db.assertDbUnit(getClass(), "insert-result.xml", "groups_users"); + } + + @Test + public void delete_members_by_group_id() { + db.prepareDbUnit(getClass(), "delete_members_by_group_id.xml"); + dao.deleteMembersByGroupId(session, 1L); + session.commit(); + db.assertDbUnit(getClass(), "delete_members_by_group_id-result.xml", "groups_users"); + } +} diff --git a/sonar-db/src/test/java/org/sonar/jpa/test/AbstractDbUnitTestCase.java b/sonar-db/src/test/java/org/sonar/jpa/test/AbstractDbUnitTestCase.java deleted file mode 100644 index d4743f578cc..00000000000 --- a/sonar-db/src/test/java/org/sonar/jpa/test/AbstractDbUnitTestCase.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.jpa.test; - -import java.io.InputStream; -import java.sql.SQLException; -import org.apache.commons.io.IOUtils; -import org.apache.ibatis.session.SqlSession; -import org.dbunit.Assertion; -import org.dbunit.DataSourceDatabaseTester; -import org.dbunit.DatabaseUnitException; -import org.dbunit.IDatabaseTester; -import org.dbunit.database.DatabaseConfig; -import org.dbunit.database.IDatabaseConnection; -import org.dbunit.dataset.CompositeDataSet; -import org.dbunit.dataset.IDataSet; -import org.dbunit.dataset.ITable; -import org.dbunit.dataset.ReplacementDataSet; -import org.dbunit.dataset.filter.DefaultColumnFilter; -import org.dbunit.dataset.xml.FlatXmlDataSet; -import org.dbunit.ext.mssql.InsertIdentityOperation; -import org.dbunit.operation.DatabaseOperation; -import org.junit.Before; -import org.junit.BeforeClass; -import org.sonar.db.Database; -import org.sonar.db.DatabaseCommands; -import org.sonar.db.H2Database; -import org.sonar.db.MyBatis; -import org.sonar.db.deprecated.NullQueue; -import org.sonar.db.version.DatabaseVersion; -import org.sonar.db.version.SchemaMigrationMapper; - -import static org.junit.Assert.fail; - -/** - * @deprecated this class does not support non-H2 databases - */ -@Deprecated -public abstract class AbstractDbUnitTestCase { - private static Database database; - private static MyBatis myBatis; - private static DatabaseCommands databaseCommands; - private IDatabaseTester databaseTester; - - @BeforeClass - public static void startDatabase() throws SQLException { - if (database == null) { - database = new H2Database("sonarHibernate", true); - database.start(); - - databaseCommands = DatabaseCommands.forDialect(database.getDialect()); - - myBatis = new MyBatis(database, new NullQueue()); - myBatis.start(); - try (SqlSession session = myBatis.openSession(false)) { - session.getMapper(SchemaMigrationMapper.class).insert(String.valueOf(DatabaseVersion.LAST_VERSION)); - session.commit(); - } - } - } - - @Before - public void startDbUnit() throws Exception { - databaseCommands.truncateDatabase(database.getDataSource()); - databaseTester = new DataSourceDatabaseTester(database.getDataSource()); - } - - protected MyBatis getMyBatis() { - return myBatis; - } - - protected Database getDatabase() { - return database; - } - - protected void setupData(String... testNames) { - InputStream[] streams = new InputStream[testNames.length]; - try { - for (int i = 0; i < testNames.length; i++) { - String className = getClass().getName(); - className = String.format("/%s/%s.xml", className.replace(".", "/"), testNames[i]); - streams[i] = getClass().getResourceAsStream(className); - if (streams[i] == null) { - throw new RuntimeException("Test not found :" + className); - } - } - - setupData(streams); - databaseCommands.resetPrimaryKeys(database.getDataSource()); - } catch (SQLException e) { - throw translateException("Could not setup DBUnit data", e); - } finally { - for (InputStream stream : streams) { - IOUtils.closeQuietly(stream); - } - } - } - - private void setupData(InputStream... dataSetStream) { - IDatabaseConnection connection = null; - try { - IDataSet[] dataSets = new IDataSet[dataSetStream.length]; - for (int i = 0; i < dataSetStream.length; i++) { - dataSets[i] = getData(dataSetStream[i]); - } - databaseTester.setDataSet(new CompositeDataSet(dataSets)); - - connection = createConnection(); - - new InsertIdentityOperation(DatabaseOperation.INSERT).execute(connection, databaseTester.getDataSet()); - } catch (Exception e) { - throw translateException("Could not setup DBUnit data", e); - } finally { - closeQuietly(connection); - } - } - - private void closeQuietly(IDatabaseConnection connection) { - try { - if (connection != null) { - connection.close(); - } - } catch (SQLException ignored) { - - } - } - - protected void checkTables(String testName, String... tables) { - checkTables(testName, new String[0], tables); - } - - protected void checkTables(String testName, String[] excludedColumnNames, String... tables) { - IDatabaseConnection connection = null; - try { - connection = createConnection(); - - IDataSet dataSet = connection.createDataSet(); - IDataSet expectedDataSet = getExpectedData(testName); - for (String table : tables) { - ITable filteredTable = DefaultColumnFilter.excludedColumnsTable(dataSet.getTable(table), excludedColumnNames); - ITable filteredExpectedTable = DefaultColumnFilter.excludedColumnsTable(expectedDataSet.getTable(table), excludedColumnNames); - Assertion.assertEquals(filteredExpectedTable, filteredTable); - } - } catch (DatabaseUnitException e) { - fail(e.getMessage()); - } catch (SQLException e) { - throw translateException("Error while checking results", e); - } finally { - closeQuietly(connection); - } - } - - protected void checkTable(String testName, String table, String... columns) { - IDatabaseConnection connection = null; - try { - connection = createConnection(); - - IDataSet dataSet = connection.createDataSet(); - IDataSet expectedDataSet = getExpectedData(testName); - ITable filteredTable = DefaultColumnFilter.includedColumnsTable(dataSet.getTable(table), columns); - ITable filteredExpectedTable = DefaultColumnFilter.includedColumnsTable(expectedDataSet.getTable(table), columns); - Assertion.assertEquals(filteredExpectedTable, filteredTable); - - } catch (DatabaseUnitException e) { - fail(e.getMessage()); - } catch (SQLException e) { - throw translateException("Error while checking results", e); - } finally { - closeQuietly(connection); - } - } - - private IDatabaseConnection createConnection() { - try { - IDatabaseConnection connection = databaseTester.getConnection(); - connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, databaseCommands.getDbUnitFactory()); - return connection; - } catch (Exception e) { - throw translateException("Error while getting connection", e); - } - } - - private IDataSet getExpectedData(String testName) { - String className = getClass().getName(); - className = String.format("/%s/%s-result.xml", className.replace('.', '/'), testName); - - InputStream in = getClass().getResourceAsStream(className); - try { - return getData(in); - } finally { - IOUtils.closeQuietly(in); - } - } - - private IDataSet getData(InputStream stream) { - try { - ReplacementDataSet dataSet = new ReplacementDataSet(new FlatXmlDataSet(stream)); - dataSet.addReplacementObject("[null]", null); - dataSet.addReplacementObject("[false]", Boolean.FALSE); - dataSet.addReplacementObject("[true]", Boolean.TRUE); - return dataSet; - } catch (Exception e) { - throw translateException("Could not read the dataset stream", e); - } - } - - private static RuntimeException translateException(String msg, Exception cause) { - RuntimeException runtimeException = new RuntimeException(String.format("%s: [%s] %s", msg, cause.getClass().getName(), cause.getMessage())); - runtimeException.setStackTrace(cause.getStackTrace()); - return runtimeException; - } -} diff --git a/sonar-db/src/test/resources/org/sonar/api/database/configuration/DatabaseConfigurationTest/some-properties.xml b/sonar-db/src/test/resources/org/sonar/api/database/configuration/DatabaseConfigurationTest/some-properties.xml deleted file mode 100644 index 64c38fb55ea..00000000000 --- a/sonar-db/src/test/resources/org/sonar/api/database/configuration/DatabaseConfigurationTest/some-properties.xml +++ /dev/null @@ -1,6 +0,0 @@ -<dataset> - - <properties prop_key="key1" resource_id="[null]" text_value="value1" user_id="[null]"/> - <properties prop_key="key2" resource_id="[null]" text_value="value2" user_id="[null]"/> - -</dataset>
\ No newline at end of file diff --git a/sonar-db/src/test/resources/org/sonar/db/ResultSetIteratorTest/feed.xml b/sonar-db/src/test/resources/org/sonar/db/ResultSetIteratorTest/feed.xml new file mode 100644 index 00000000000..e76d538413e --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/ResultSetIteratorTest/feed.xml @@ -0,0 +1,5 @@ +<dataset> + <issues id="10" kee="AB" /> + <issues id="20" kee="CD" /> + <issues id="30" kee="EF" /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/ResultSetIteratorTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/ResultSetIteratorTest/schema.sql new file mode 100644 index 00000000000..333bb0e193e --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/ResultSetIteratorTest/schema.sql @@ -0,0 +1,4 @@ +CREATE TABLE "ISSUES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(200) NOT NULL +); diff --git a/sonar-db/src/test/resources/org/sonar/db/component/ComponentLinkDaoTest/delete.xml b/sonar-db/src/test/resources/org/sonar/db/component/ComponentLinkDaoTest/delete.xml new file mode 100644 index 00000000000..8b89e7223ec --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/component/ComponentLinkDaoTest/delete.xml @@ -0,0 +1,5 @@ +<dataset> + + <project_links id="1" component_uuid="ABCD" link_type="homepage" name="Home" href="http://www.sonarqube.org"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/empty.xml b/sonar-db/src/test/resources/org/sonar/db/component/ComponentLinkDaoTest/empty.xml index 871dedcb5e9..871dedcb5e9 100644 --- a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/empty.xml +++ b/sonar-db/src/test/resources/org/sonar/db/component/ComponentLinkDaoTest/empty.xml diff --git a/sonar-db/src/test/resources/org/sonar/db/component/ComponentLinkDaoTest/insert-result.xml b/sonar-db/src/test/resources/org/sonar/db/component/ComponentLinkDaoTest/insert-result.xml new file mode 100644 index 00000000000..8b89e7223ec --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/component/ComponentLinkDaoTest/insert-result.xml @@ -0,0 +1,5 @@ +<dataset> + + <project_links id="1" component_uuid="ABCD" link_type="homepage" name="Home" href="http://www.sonarqube.org"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/component/ComponentLinkDaoTest/shared.xml b/sonar-db/src/test/resources/org/sonar/db/component/ComponentLinkDaoTest/shared.xml new file mode 100644 index 00000000000..33e9449d1dd --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/component/ComponentLinkDaoTest/shared.xml @@ -0,0 +1,7 @@ +<dataset> + + <project_links id="1" component_uuid="ABCD" link_type="homepage" name="Home" href="http://www.sonarqube.org"/> + <project_links id="2" component_uuid="ABCD" link_type="scm" name="Sources" href="https://github.com/SonarSource/sonar"/> + <project_links id="3" component_uuid="BCDE" link_type="homepage" name="Home" href="http://www.struts.org"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/component/ComponentLinkDaoTest/update-result.xml b/sonar-db/src/test/resources/org/sonar/db/component/ComponentLinkDaoTest/update-result.xml new file mode 100644 index 00000000000..8b89e7223ec --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/component/ComponentLinkDaoTest/update-result.xml @@ -0,0 +1,5 @@ +<dataset> + + <project_links id="1" component_uuid="ABCD" link_type="homepage" name="Home" href="http://www.sonarqube.org"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/component/ComponentLinkDaoTest/update.xml b/sonar-db/src/test/resources/org/sonar/db/component/ComponentLinkDaoTest/update.xml new file mode 100644 index 00000000000..6b80fc9d01c --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/component/ComponentLinkDaoTest/update.xml @@ -0,0 +1,5 @@ +<dataset> + + <project_links id="1" component_uuid="BCDE" link_type="ci" name="CI" href="github"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/component/ResourceIndexerDaoTest/select_project_ids_from_query_and_view_or_sub_view_uuid.xml b/sonar-db/src/test/resources/org/sonar/db/component/ResourceIndexerDaoTest/select_project_ids_from_query_and_view_or_sub_view_uuid.xml new file mode 100644 index 00000000000..aff69473ce1 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/component/ResourceIndexerDaoTest/select_project_ids_from_query_and_view_or_sub_view_uuid.xml @@ -0,0 +1,32 @@ +<dataset> + + <!-- Real projects --> + <projects id="1" uuid="ABCD" project_uuid="ABCD" module_uuid_path=".ABCD." copy_resource_id="[null]" name="Project One" qualifier="TRK" scope="PRJ"/> + <projects id="2" uuid="BCDE" project_uuid="BCDE" module_uuid_path=".BCDE." copy_resource_id="[null]" name="Project Two" qualifier="TRK" scope="PRJ"/> + + <!-- Copy projects --> + <projects id="3" uuid="CDEF" project_uuid="EFGH" module_uuid_path=".EFGH." copy_resource_id="1" name="Copy Project One" qualifier="TRK" scope="FIL"/> + <projects id="4" uuid="DEFG" project_uuid="EFGH" module_uuid_path=".EFGH." copy_resource_id="2" name="Copy Project One" qualifier="TRK" scope="FIL"/> + + <!-- View containing all projects --> + <projects id="5" uuid="EFGH" project_uuid="EFGH" module_uuid_path=".EFGH." copy_resource_id="[null]" name="All projects" qualifier="VW" scope="PRJ"/> + + <resource_index id="1" kee="project one" resource_id="1" root_project_id="1" position="0" name_size="11" qualifier="TRK"/> + <resource_index id="2" kee="roject one" resource_id="1" root_project_id="1" position="1" name_size="11" qualifier="TRK"/> + <resource_index id="3" kee="oject one" resource_id="1" root_project_id="1" position="2" name_size="11" qualifier="TRK"/> + <resource_index id="4" kee="ject one" resource_id="1" root_project_id="1" position="3" name_size="11" qualifier="TRK"/> + <resource_index id="5" kee="ect one" resource_id="1" root_project_id="1" position="4" name_size="11" qualifier="TRK"/> + <resource_index id="6" kee="ct one" resource_id="1" root_project_id="1" position="5" name_size="11" qualifier="TRK"/> + <resource_index id="7" kee="t one" resource_id="1" root_project_id="1" position="6" name_size="11" qualifier="TRK"/> + <resource_index id="8" kee=" one" resource_id="1" root_project_id="1" position="7" name_size="11" qualifier="TRK"/> + <resource_index id="9" kee="one" resource_id="1" root_project_id="1" position="8" name_size="11" qualifier="TRK"/> + <resource_index id="10" kee="project two" resource_id="2" root_project_id="2" position="0" name_size="11" qualifier="TRK"/> + <resource_index id="11" kee="roject two" resource_id="2" root_project_id="2" position="1" name_size="11" qualifier="TRK"/> + <resource_index id="12" kee="oject two" resource_id="2" root_project_id="2" position="2" name_size="11" qualifier="TRK"/> + <resource_index id="13" kee="ject two" resource_id="2" root_project_id="2" position="3" name_size="11" qualifier="TRK"/> + <resource_index id="14" kee="ect two" resource_id="2" root_project_id="2" position="4" name_size="11" qualifier="TRK"/> + <resource_index id="15" kee="ct two" resource_id="2" root_project_id="2" position="5" name_size="11" qualifier="TRK"/> + <resource_index id="16" kee="t two" resource_id="2" root_project_id="2" position="6" name_size="11" qualifier="TRK"/> + <resource_index id="17" kee="two" resource_id="2" root_project_id="2" position="7" name_size="11" qualifier="TRK"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/empty.xml b/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/empty.xml new file mode 100644 index 00000000000..871dedcb5e9 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/empty.xml @@ -0,0 +1,3 @@ +<dataset> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/insert-result.xml b/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/insert-result.xml new file mode 100644 index 00000000000..a138d68b188 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/insert-result.xml @@ -0,0 +1,13 @@ +<dataset> + + <snapshots id="1" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="1500000000001" + period2_mode="days2" period2_param="31" period2_date="1500000000002" + period3_mode="days3" period3_param="32" period3_date="1500000000003" + period4_mode="days4" period4_param="33" period4_date="1500000000004" + period5_mode="days5" period5_param="34" period5_date="1500000000005" + depth="1" scope="DIR" qualifier="PAC" created_at="1403042400000" build_date="1500000000006" + version="2.1-SNAPSHOT" path="1.2."/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/modules.xml b/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/modules.xml new file mode 100644 index 00000000000..9ba70bee6f4 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/modules.xml @@ -0,0 +1,90 @@ +<dataset> + + <!-- root project --> + <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="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]" authorization_updated_at="[null]" /> + <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="TRK" created_at="1228222680000" build_date="1228222680000" + version="[null]" path=""/> + <snapshots id="10" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + status="P" islast="[false]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="TRK" created_at="1228136280000" build_date="1228136280000" + version="[null]" path=""/> + + <!-- module --> + <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" + uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD." + scope="PRJ" qualifier="BRC" long_name="Struts Core" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]" /> + <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="BRC" created_at="1228222680000" build_date="1228222680000" + version="[null]" path="1."/> + + <!-- sub module --> + <projects id="3" root_id="1" kee="org.struts:struts-data" name="Struts Data" + uuid="FGHI" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH." + scope="PRJ" qualifier="BRC" long_name="Struts Data" + description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]" /> + <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="PRJ" qualifier="BRC" created_at="1228222680000" build_date="1228222680000" + version="[null]" path="1.2."/> + + <!-- directory --> + <projects long_name="org.struts" id="4" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts" + uuid="GHIJ" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path=".ABCD.EFGH.FGHI." + name="src/org/struts" root_id="3" + description="[null]" + enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" authorization_updated_at="[null]" /> + <snapshots id="4" project_id="4" parent_snapshot_id="3" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="DIR" qualifier="PAC" created_at="1228222680000" build_date="1228222680000" + version="[null]" path="1.2.3."/> + + <!-- file --> + <projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java" + uuid="HIJK" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path=".ABCD.EFGH.FGHI." + name="RequestContext.java" root_id="3" + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java" authorization_updated_at="[null]" /> + + <snapshots id="5" project_id="5" parent_snapshot_id="4" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="[null]" + period1_mode="[null]" period1_param="[null]" period1_date="[null]" + period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" + period4_mode="[null]" period4_param="[null]" period4_date="[null]" + period5_mode="[null]" period5_param="[null]" period5_date="[null]" + depth="[null]" scope="FIL" qualifier="CLA" created_at="1228222680000" build_date="1228222680000" + version="[null]" path="1.2.3.4."/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/select_previous_version_snapshots.xml b/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/select_previous_version_snapshots.xml new file mode 100644 index 00000000000..3f56960cd92 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/select_previous_version_snapshots.xml @@ -0,0 +1,48 @@ +<dataset> + + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project" + root_id="[null]" uuid="ABCD" + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"/> + + <!-- version 1.0 --> + <snapshots id="1000" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" + period5_param="[null]" period5_date="[null]" + project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + scope="PRJ" qualifier="TRK" created_at="1225630680000" build_date="1225630680000" version="1.0" path="" + status="P" islast="[false]" depth="0"/> + + <!-- version 1.1 --> + <snapshots id="1001" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" + period5_param="[null]" period5_date="[null]" + project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + scope="PRJ" qualifier="TRK" created_at="1225803480000" build_date="1225803480000" version="1.1" path="" + status="P" islast="[false]" depth="0"/> + + <!-- version 1.2-SNAPSHOT --> + <snapshots id="1002" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" + period5_param="[null]" period5_date="[null]" + project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + scope="PRJ" qualifier="TRK" created_at="1225976280000" build_date="1225976280000" version="1.2-SNAPSHOT" path="" + status="P" islast="[false]" depth="0"/> + + <!-- version 1.2-SNAPSHOT, current analysis --> + <snapshots id="1003" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" + period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" + period5_param="[null]" period5_date="[null]" + project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + 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" 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> diff --git a/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/select_snapshots_by_query.xml b/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/select_snapshots_by_query.xml new file mode 100644 index 00000000000..1f32010f385 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/select_snapshots_by_query.xml @@ -0,0 +1,64 @@ +<dataset> + + <!-- PROJECT_ID = 1 --> + <snapshots id="1" project_id="1" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="1316815200000" + period2_mode="days2" period2_param="31" period2_date="1316901600000" + period3_mode="days3" period3_param="32" period3_date="1316988000000" + period4_mode="days4" period4_param="33" period4_date="1317074400000" + period5_mode="days5" period5_param="34" period5_date="1317160800000" + depth="1" scope="PRJ" qualifier="PAC" created_at="1228172400001" build_date="1317247200000" + version="2.0-SNAPSHOT" path="1.2."/> + <snapshots id="2" project_id="1" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="3" + status="P" islast="[false]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="1316815200000" + period2_mode="days2" period2_param="31" period2_date="1316901600000" + period3_mode="days3" period3_param="32" period3_date="1316988000000" + period4_mode="days4" period4_param="33" period4_date="1317074400000" + period5_mode="days5" period5_param="34" period5_date="1317160800000" + depth="1" scope="DIR" qualifier="PAC" created_at="1228172400002" build_date="1317247200000" + version="2.1-SNAPSHOT" path="1.2."/> + <snapshots id="3" project_id="1" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="3" + status="P" islast="[false]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="1316815200000" + period2_mode="days2" period2_param="31" period2_date="1316901600000" + period3_mode="days3" period3_param="32" period3_date="1316988000000" + period4_mode="days4" period4_param="33" period4_date="1317074400000" + period5_mode="days5" period5_param="34" period5_date="1317160800000" + depth="1" scope="DIR" qualifier="PAC" created_at="1228172400003" build_date="1317247200000" + version="2.2-SNAPSHOT" path="1.2."/> + + <!-- PROJECT_ID = 2 --> + <snapshots id="4" project_id="2" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="3" + status="P" islast="[true]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="1316815200000" + period2_mode="days2" period2_param="31" period2_date="1316901600000" + period3_mode="days3" period3_param="32" period3_date="1316988000000" + period4_mode="days4" period4_param="33" period4_date="1317074400000" + period5_mode="days5" period5_param="34" period5_date="1317160800000" + depth="1" scope="DIR" qualifier="PAC" created_at="1228172400000" build_date="1317247200000" + version="2.1-SNAPSHOT" path="1.2."/> + <!-- Unprocessed snapshot --> + <snapshots id="5" project_id="2" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="3" + status="U" islast="[true]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="1316815200000" + period2_mode="days2" period2_param="31" period2_date="1316901600000" + period3_mode="days3" period3_param="32" period3_date="1316988000000" + period4_mode="days4" period4_param="33" period4_date="1317074400000" + period5_mode="days5" period5_param="34" period5_date="1317160800000" + depth="1" scope="DIR" qualifier="PAC" created_at="1228172400000" build_date="1317247200000" + version="2.1-SNAPSHOT" path="1.2."/> + + <!-- PROJECT_ID = 3 - no last snapshot --> + <snapshots id="6" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="3" + status="P" islast="[false]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="1316815200000" + period2_mode="days2" period2_param="31" period2_date="1316901600000" + period3_mode="days3" period3_param="32" period3_date="1316988000000" + period4_mode="days4" period4_param="33" period4_date="1317074400000" + period5_mode="days5" period5_param="34" period5_date="1317160800000" + depth="1" scope="DIR" qualifier="PAC" created_at="1228172400000" build_date="1317247200000" + version="2.1-SNAPSHOT" path="1.2."/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/shared.xml b/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/shared.xml new file mode 100644 index 00000000000..a52b271da32 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/shared.xml @@ -0,0 +1,13 @@ +<dataset> + + <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="1316815200000" + period2_mode="days2" period2_param="31" period2_date="1316901600000" + period3_mode="days3" period3_param="32" period3_date="1316988000000" + period4_mode="days4" period4_param="33" period4_date="1317074400000" + period5_mode="days5" period5_param="34" period5_date="1317160800000" + depth="1" scope="DIR" qualifier="PAC" created_at="1228172400000" build_date="1317247200000" + version="2.1-SNAPSHOT" path="1.2."/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/snapshots.xml b/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/snapshots.xml new file mode 100644 index 00000000000..4c18e257396 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/component/SnapshotDaoTest/snapshots.xml @@ -0,0 +1,65 @@ +<dataset> + + <!-- PROJECT_ID = 1 --> + <snapshots id="1" project_id="1" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="1316815200000" + period2_mode="days2" period2_param="31" period2_date="1316901600000" + period3_mode="days3" period3_param="32" period3_date="1316988000000" + period4_mode="days4" period4_param="33" period4_date="1317074400000" + period5_mode="days5" period5_param="34" period5_date="1317160800000" + depth="1" scope="PRJ" qualifier="PAC" created_at="1228172400000" build_date="1317247200000" + version="2.1-SNAPSHOT" path="1.2."/> + <snapshots id="2" project_id="1" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="3" + status="P" islast="[false]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="1316815200000" + period2_mode="days2" period2_param="31" period2_date="1316901600000" + period3_mode="days3" period3_param="32" period3_date="1316988000000" + period4_mode="days4" period4_param="33" period4_date="1317074400000" + period5_mode="days5" period5_param="34" period5_date="1317160800000" + depth="1" scope="DIR" qualifier="PAC" created_at="1228172400000" build_date="1317247200000" + version="2.1-SNAPSHOT" path="1.2."/> + <snapshots id="3" project_id="1" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="3" + status="P" islast="[false]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="1316815200000" + period2_mode="days2" period2_param="31" period2_date="1316901600000" + period3_mode="days3" period3_param="32" period3_date="1316988000000" + period4_mode="days4" period4_param="33" period4_date="1317074400000" + period5_mode="days5" period5_param="34" period5_date="1317160800000" + depth="1" scope="DIR" qualifier="PAC" created_at="1228172400000" build_date="1317247200000" + version="2.1-SNAPSHOT" path="1.2."/> + + + <!-- PROJECT_ID = 2 --> + <snapshots id="4" project_id="2" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="3" + status="P" islast="[true]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="1316815200000" + period2_mode="days2" period2_param="31" period2_date="1316901600000" + period3_mode="days3" period3_param="32" period3_date="1316988000000" + period4_mode="days4" period4_param="33" period4_date="1317074400000" + period5_mode="days5" period5_param="34" period5_date="1317160800000" + depth="1" scope="DIR" qualifier="PAC" created_at="1228172400000" build_date="1317247200000" + version="2.1-SNAPSHOT" path="1.2."/> + + <!-- PROJECT_ID = 3 - no last snapshot --> + <snapshots id="5" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="3" + status="P" islast="[false]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="1316815200000" + period2_mode="days2" period2_param="31" period2_date="1316901600000" + period3_mode="days3" period3_param="32" period3_date="1316988000000" + period4_mode="days4" period4_param="33" period4_date="1317074400000" + period5_mode="days5" period5_param="34" period5_date="1317160800000" + depth="1" scope="DIR" qualifier="PAC" created_at="1228172400000" build_date="1317247200000" + version="2.1-SNAPSHOT" path="1.2."/> + + <!-- Child of snapshot id=1 --> + <snapshots id="6" project_id="55" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1" + status="P" islast="[true]" purge_status="1" + period1_mode="days1" period1_param="30" period1_date="1316815200000" + period2_mode="days2" period2_param="31" period2_date="1316901600000" + period3_mode="days3" period3_param="32" period3_date="1316988000000" + period4_mode="days4" period4_param="33" period4_date="1317074400000" + period5_mode="days5" period5_param="34" period5_date="1317160800000" + depth="1" scope="PRJ" qualifier="PAC" created_at="1228172400000" build_date="1317247200000" + version="2.1-SNAPSHOT" path="1.2."/> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/any-analysis-reports.xml b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/any-analysis-reports.xml new file mode 100644 index 00000000000..dba17d047a4 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/any-analysis-reports.xml @@ -0,0 +1,26 @@ +<dataset> + <analysis_reports + id="1" + uuid="REPORT_1" + project_key="123456789-987654321" + report_status="WORKING" + created_at="1411509600000" + updated_at="1411509600000" + /> + <analysis_reports + id="2" + uuid="REPORT_2" + project_key="123456789-987654321" + report_status="WORKING" + created_at="1411596000000" + updated_at="1411596000000" + /> + <analysis_reports + id="3" + uuid="REPORT_3" + project_key="123456789-987654321" + report_status="PENDING" + created_at="1411682400000" + updated_at="1411682400000" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/book_available_report_analysis_while_having_one_working_on_another_project.xml b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/book_available_report_analysis_while_having_one_working_on_another_project.xml new file mode 100644 index 00000000000..ae28befd603 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/book_available_report_analysis_while_having_one_working_on_another_project.xml @@ -0,0 +1,18 @@ +<dataset> + <analysis_reports + id="1" + project_key="123456789-987654321" + uuid="REPORT_1" + report_status="PENDING" + created_at="1411509600000" + updated_at="1411596000000" + /> + <analysis_reports + id="2" + project_key="987654321-123456789" + uuid="REPORT_2" + report_status="WORKING" + created_at="1411423200000" + updated_at="1411682400000" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/empty.xml b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/empty.xml new file mode 100644 index 00000000000..871dedcb5e9 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/empty.xml @@ -0,0 +1,3 @@ +<dataset> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/insert-result.xml b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/insert-result.xml new file mode 100644 index 00000000000..d25e3641ce9 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/insert-result.xml @@ -0,0 +1,24 @@ +<dataset> + <analysis_reports + id="1" + project_key="ProjectKey1" + project_name="Project 1" + uuid="UUID_1" + report_status="PENDING" + started_at="[null]" + finished_at="[null]" + created_at="1500000000000" + updated_at="1500000000000" + /> + <analysis_reports + id="2" + project_key="ProjectKey2" + project_name="Project 2" + uuid="UUID_2" + report_status="PENDING" + started_at="[null]" + finished_at="[null]" + created_at="1500000000000" + updated_at="1500000000000" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/one_analysis_report.xml b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/one_analysis_report.xml new file mode 100644 index 00000000000..c38ac125e00 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/one_analysis_report.xml @@ -0,0 +1,12 @@ +<dataset> + <analysis_reports + id="1" + project_key="123456789-987654321" + uuid="REPORT_1" + report_status="WORKING" + created_at="1500000000001" + updated_at="1500000000002" + started_at="1500000000003" + finished_at="1500000000004" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/pop_null_if_no_pending_reports.xml b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/pop_null_if_no_pending_reports.xml new file mode 100644 index 00000000000..82f93e9fec5 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/pop_null_if_no_pending_reports.xml @@ -0,0 +1,27 @@ +<dataset> + <analysis_reports + id="1" + project_key="111111111-987654321" + uuid="UUID_1" + report_status="WORKING" + created_at="1411596000000" + updated_at="1411682400000" + /> + <analysis_reports + id="2" + project_key="123456789-987654321" + uuid="UUID_2" + report_status="WORKING" + created_at="1411509600000" + updated_at="1411682400000" + /> + <!-- not select as the previous report which is working is on the same project --> + <analysis_reports + id="3" + project_key="123456789-987654321" + uuid="UUID_3" + report_status="PENDING" + created_at="1411596000000" + updated_at="1411682400000" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/pop_oldest_pending.xml b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/pop_oldest_pending.xml new file mode 100644 index 00000000000..972fde88fd7 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/pop_oldest_pending.xml @@ -0,0 +1,37 @@ +<dataset> + <!-- WORKING --> + <analysis_reports + id="1" + project_key="P1" + uuid="UUID_1" + report_status="WORKING" + created_at="1411596000000" + updated_at="1411682400000" + /> + + <!-- PENDING on P1, which is already being WORKING--> + <analysis_reports + id="2" + project_key="P1" + uuid="UUID_2" + report_status="PENDING" + created_at="1411509600000" + updated_at="1411682400000" + /> + <analysis_reports + id="3" + project_key="P2" + uuid="UUID_3" + report_status="PENDING" + created_at="1411596000000" + updated_at="1411682400000" + /> + <analysis_reports + id="4" + project_key="P2" + uuid="UUID_4" + report_status="PENDING" + created_at="1420066800000" + updated_at="1420066800000" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/select.xml b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/select.xml new file mode 100644 index 00000000000..de9d5b9f330 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/select.xml @@ -0,0 +1,29 @@ +<dataset> + <analysis_reports + id="1" + project_key="123456789-987654321" + project_name="Project 1" + uuid="UUID_1" + report_status="WORKING" + created_at="1411509600000" + updated_at="1411596000000" + /> + <analysis_reports + id="2" + project_key="987654321-123456789" + project_name="Project 2" + uuid="UUID_2" + report_status="WORKING" + created_at="1411596000000" + updated_at="1411596000000" + /> + <analysis_reports + id="3" + project_key="987654321-123456789" + project_name="Project 2" + uuid="UUID_3" + report_status="PENDING" + created_at="1411682400000" + updated_at="1411682400000" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/three_analysis_reports.xml b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/three_analysis_reports.xml new file mode 100644 index 00000000000..c1e3284f108 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/three_analysis_reports.xml @@ -0,0 +1,26 @@ +<dataset> + <analysis_reports + id="1" + project_key="123456789-987654321" + uuid="UUID_1" + report_status="WORKING" + created_at="1411509600000" + updated_at="1411596000000" + /> + <analysis_reports + id="2" + project_key="987654321-123456789" + uuid="UUID_2" + report_status="WORKING" + created_at="1411596000000" + updated_at="1411596000000" + /> + <analysis_reports + id="3" + project_key="987654321-123456789" + uuid="UUID_3" + report_status="PENDING" + created_at="1411682400000" + updated_at="1411682400000" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/truncate-result.xml b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/truncate-result.xml new file mode 100644 index 00000000000..e573e0c5b06 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/truncate-result.xml @@ -0,0 +1,3 @@ +<dataset> + <analysis_reports/> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/update-all-to-status-pending-result.xml b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/update-all-to-status-pending-result.xml new file mode 100644 index 00000000000..16fb8dc0895 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/update-all-to-status-pending-result.xml @@ -0,0 +1,36 @@ +<dataset> + <!-- all rows are PENDING, updated_at is now, started_at is null --> + <analysis_reports + id="1" + project_key="P1" + project_name="Project1" + uuid="UUID_1" + report_status="PENDING" + created_at="1411509600000" + updated_at="1500000000000" + started_at="[null]" + finished_at="[null]" + /> + <analysis_reports + id="2" + project_key="P2" + project_name="Project2" + uuid="UUID_2" + report_status="PENDING" + created_at="1411596000000" + updated_at="1500000000000" + started_at="[null]" + finished_at="[null]" + /> + <analysis_reports + id="3" + project_key="P1" + project_name="Project1" + uuid="UUID_3" + report_status="PENDING" + created_at="1411682400000" + updated_at="1500000000000" + started_at="[null]" + finished_at="[null]" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/update-all-to-status-pending.xml b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/update-all-to-status-pending.xml new file mode 100644 index 00000000000..a630cb4ec4b --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/update-all-to-status-pending.xml @@ -0,0 +1,35 @@ +<dataset> + <analysis_reports + id="1" + project_key="P1" + project_name="Project1" + uuid="UUID_1" + report_status="WORKING" + created_at="1411509600000" + updated_at="1411509600000" + started_at="1411509600000" + finished_at="[null]" + /> + <analysis_reports + id="2" + project_key="P2" + project_name="Project2" + uuid="UUID_2" + report_status="WORKING" + created_at="1411596000000" + updated_at="1411596000000" + started_at="1411509600000" + finished_at="[null]" + /> + <analysis_reports + id="3" + project_key="P1" + project_name="Project1" + uuid="UUID_3" + report_status="PENDING" + created_at="1411682400000" + updated_at="1411682400000" + started_at="[null]" + finished_at="[null]" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/zip.zip b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/zip.zip Binary files differnew file mode 100644 index 00000000000..a540bc5b5ca --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/compute/AnalysisReportDaoTest/zip.zip diff --git a/sonar-db/src/test/resources/org/sonar/db/dashboard/WidgetDaoTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/dashboard/WidgetDaoTest/before.xml new file mode 100644 index 00000000000..a942341e3d4 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/dashboard/WidgetDaoTest/before.xml @@ -0,0 +1,18 @@ +<dataset> + + <widgets id="1" dashboard_id="1" widget_key="polop" name="Polop" description="Palap" + column_index="1" row_index="1" configured="[true]" created_at="[null]" updated_at="[null]" resource_id="[null]"/> + + <widgets id="2" dashboard_id="1" widget_key="false_positive_reviews" name="Polop" description="Palap" + column_index="1" row_index="2" configured="[true]" created_at="[null]" updated_at="[null]" resource_id="[null]"/> + + <widgets id="3" dashboard_id="1" widget_key="my_reviews" name="Polop" description="Palap" + column_index="1" row_index="3" configured="[true]" created_at="[null]" updated_at="[null]" resource_id="[null]"/> + + <widgets id="4" dashboard_id="1" widget_key="reviews_per_developer" name="Polop" description="Palap" + column_index="1" row_index="4" configured="[true]" created_at="[null]" updated_at="[null]" resource_id="[null]"/> + + <widgets id="5" dashboard_id="1" widget_key="unresolved_issues_statuses" name="Polop" description="Palap" + column_index="1" row_index="5" configured="[true]" created_at="[null]" updated_at="[null]" resource_id="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/event/EventDaoTest/delete.xml b/sonar-db/src/test/resources/org/sonar/db/event/EventDaoTest/delete.xml new file mode 100644 index 00000000000..c22a68ed8e0 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/event/EventDaoTest/delete.xml @@ -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> diff --git a/sonar-db/src/test/resources/org/sonar/db/event/EventDaoTest/empty.xml b/sonar-db/src/test/resources/org/sonar/db/event/EventDaoTest/empty.xml new file mode 100644 index 00000000000..871dedcb5e9 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/event/EventDaoTest/empty.xml @@ -0,0 +1,3 @@ +<dataset> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/event/EventDaoTest/insert-result.xml b/sonar-db/src/test/resources/org/sonar/db/event/EventDaoTest/insert-result.xml new file mode 100644 index 00000000000..27a2a24e080 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/event/EventDaoTest/insert-result.xml @@ -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> diff --git a/sonar-db/src/test/resources/org/sonar/db/event/EventDaoTest/shared.xml b/sonar-db/src/test/resources/org/sonar/db/event/EventDaoTest/shared.xml new file mode 100644 index 00000000000..0002deec3c2 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/event/EventDaoTest/shared.xml @@ -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> diff --git a/sonar-db/src/test/resources/org/sonar/db/issue/IssueDaoTest/find_by_action_plan.xml b/sonar-db/src/test/resources/org/sonar/db/issue/IssueDaoTest/find_by_action_plan.xml new file mode 100644 index 00000000000..a052d421f66 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/issue/IssueDaoTest/find_by_action_plan.xml @@ -0,0 +1,29 @@ +<dataset> + + <issues + id="100" + kee="ABCDE" + component_uuid="CDEF" + project_uuid="ABCD" + rule_id="500" + severity="BLOCKER" + manual_severity="[false]" + message="[null]" + line="200" + effort_to_fix="4.2" + status="OPEN" + resolution="FIXED" + checksum="XXX" + reporter="arthur" + assignee="perceval" + action_plan_key="AP-1" + author_login="karadoc" + issue_attributes="JIRA=FOO-1234" + issue_creation_date="1366063200000" + issue_update_date="1366063200000" + issue_close_date="1366063200000" + created_at="1400000000000" + updated_at="1400000000000" + /> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/issue/IssueDaoTest/get_by_key.xml b/sonar-db/src/test/resources/org/sonar/db/issue/IssueDaoTest/get_by_key.xml new file mode 100644 index 00000000000..154a7a67883 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/issue/IssueDaoTest/get_by_key.xml @@ -0,0 +1,28 @@ +<dataset> + + <issues + id="100" + kee="ABCDE" + component_uuid="CDEF" + project_uuid="ABCD" + rule_id="500" + severity="BLOCKER" + manual_severity="[false]" + message="[null]" + line="200" + effort_to_fix="4.2" + status="OPEN" + resolution="FIXED" + checksum="XXX" + reporter="arthur" + assignee="perceval" + author_login="karadoc" + issue_attributes="JIRA=FOO-1234" + issue_creation_date="1366063200000" + issue_update_date="1366063200000" + issue_close_date="1366063200000" + created_at="1400000000000" + updated_at="1450000000000" + /> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/issue/IssueDaoTest/insert-result.xml b/sonar-db/src/test/resources/org/sonar/db/issue/IssueDaoTest/insert-result.xml new file mode 100644 index 00000000000..fc1543cb2b9 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/issue/IssueDaoTest/insert-result.xml @@ -0,0 +1,29 @@ +<dataset> + <issues + id="100" + kee="ABCDE" + component_uuid="component-uuid" + project_uuid="project-uuid" + rule_id="200" + severity="BLOCKER" + manual_severity="[false]" + message="the message" + line="500" + effort_to_fix="3.14" + technical_debt="10" + status="RESOLVED" + resolution="FIXED" + checksum="123456789" + reporter="emmerik" + author_login="morgan" + assignee="karadoc" + issue_attributes="JIRA=FOO-1234" + tags="[null]" + issue_creation_date="1500000000000" + issue_update_date="1500000000001" + issue_close_date="1500000000002" + created_at="1400000000000" + updated_at="1450000000000" + action_plan_key="current_sprint" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/issue/IssueDaoTest/update-result.xml b/sonar-db/src/test/resources/org/sonar/db/issue/IssueDaoTest/update-result.xml new file mode 100644 index 00000000000..d5959c63659 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/issue/IssueDaoTest/update-result.xml @@ -0,0 +1,29 @@ +<dataset> + <issues + id="100" + kee="ABCDE" + component_uuid="123" + project_uuid="101" + rule_id="200" + severity="BLOCKER" + manual_severity="[false]" + message="the message" + line="500" + effort_to_fix="3.14" + technical_debt="10" + status="RESOLVED" + resolution="FIXED" + checksum="123456789" + reporter="emmerik" + author_login="morgan" + assignee="karadoc" + issue_attributes="JIRA=FOO-1234" + tags="[null]" + issue_creation_date="1368828000000" + issue_update_date="1368914400000" + issue_close_date="1369000800000" + created_at="1400000000000" + updated_at="1450000000000" + action_plan_key="current_sprint" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/issue/IssueDaoTest/update.xml b/sonar-db/src/test/resources/org/sonar/db/issue/IssueDaoTest/update.xml new file mode 100644 index 00000000000..9c41f1922cc --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/issue/IssueDaoTest/update.xml @@ -0,0 +1,28 @@ +<dataset> + <issues + id="100" + kee="ABCDE" + component_uuid="123" + project_uuid="100" + rule_id="200" + severity="INFO" + manual_severity="[false]" + message="old" + line="[null]" + effort_to_fix="[null]" + technical_debt="[null]" + status="OPEN" + resolution="[null]" + checksum="[null]" + reporter="[null]" + author_login="[null]" + assignee="[null]" + issue_attributes="[null]" + issue_creation_date="[null]" + issue_update_date="[null]" + issue_close_date="[null]" + created_at="1400000000000" + updated_at="1400000000000" + action_plan_key="[null]" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/empty.xml b/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/empty.xml new file mode 100644 index 00000000000..dda18829567 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/empty.xml @@ -0,0 +1,3 @@ +<dataset> + <project_measures/> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/insert-result.xml b/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/insert-result.xml new file mode 100644 index 00000000000..26c55c5d3c4 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/insert-result.xml @@ -0,0 +1,27 @@ +<dataset> + <project_measures + id="1" + snapshot_id="2" + metric_id="3" + characteristic_id="4" + rule_id="5" + project_id="6" + person_id="23" + value="2.0" + text_value="measure-value" + tendency="[null]" + rule_priority="[null]" + measure_date="[null]" + measure_data="[null]" + variation_value_1="1.0" + variation_value_2="2.0" + variation_value_3="3.0" + variation_value_4="4.0" + variation_value_5="5.0" + alert_status="alert" + alert_text="alert-text" + url="[null]" + description="measure-description" + rules_category_id="[null]" + /> +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/past_measures.xml b/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/past_measures.xml new file mode 100644 index 00000000000..1a9eaecf522 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/past_measures.xml @@ -0,0 +1,59 @@ +<dataset> + + <metrics id="1" name="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" enabled="[true]"/> + + <metrics id="2" name="coverage" VAL_TYPE="INT" enabled="[true]"/> + + + <rules tags="[null]" system_tags="[null]" id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck" + plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" status="READY" + is_template="[false]" template_id="[null]"/> + + <rules tags="[null]" system_tags="[null]" id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck" + plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" status="READY" + is_template="[false]" template_id="[null]"/> + + <!-- project --> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project" + root_id="[null]" uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD." + enabled="[true]"/> + + <!-- package --> + <projects long_name="[null]" id="2" scope="DIR" qualifier="PAC" kee="project:org.foo" name="org.foo" + root_id="1" uuid="BCDE" project_uuid="ABCD" module_uuid="ABCD" module_uuid_path=".ABCD." + enabled="[true]"/> + + <!-- file --> + <projects long_name="org.foo.Bar" id="3" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar" + name="Bar" root_id="[null]" uuid="CDEF" project_uuid="ABCD" module_uuid="ABCD" module_uuid_path=".ABCD." + enabled="[true]"/> + + + <!-- snapshots --> + <snapshots id="1000" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + scope="PRJ" qualifier="TRK" created_at="1225544280000" build_date="1225544280000" version="[null]" path="" + status="P" islast="[false]" depth="0"/> + <snapshots id="1001" project_id="2" parent_snapshot_id="1000" root_project_id="1" root_snapshot_id="1000" + scope="DIR" qualifier="PAC" created_at="1225544280000" build_date="1225544280000" version="[null]" path="1000." + status="P" islast="[false]" depth="1"/> + <snapshots id="1002" project_id="3" parent_snapshot_id="1001" root_project_id="1" root_snapshot_id="1000" + scope="FIL" qualifier="CLA" created_at="1225544280000" build_date="1225544280000" version="[null]" path="1000.1001." + status="P" islast="[false]" depth="2"/> + + + <!-- project measures --> + <project_measures id="1" VALUE="60" METRIC_ID="1" SNAPSHOT_ID="1000" RULE_ID="[null]" characteristic_id="[null]" person_id="[null]"/> + + <project_measures id="2" VALUE="80" METRIC_ID="2" SNAPSHOT_ID="1000" RULE_ID="[null]" characteristic_id="[null]" person_id="[null]"/> + + <!-- package measures --> + <project_measures id="3" VALUE="20" METRIC_ID="1" SNAPSHOT_ID="1001" RULE_ID="[null]" characteristic_id="[null]" person_id="[null]"/> + + <project_measures id="4" VALUE="70" METRIC_ID="2" SNAPSHOT_ID="1001" RULE_ID="[null]" characteristic_id="[null]" person_id="[null]"/> + + <!-- file measures --> + <project_measures id="5" VALUE="5" METRIC_ID="1" SNAPSHOT_ID="1002" RULE_ID="[null]" characteristic_id="[null]" person_id="[null]"/> + + <project_measures id="6" VALUE="60" METRIC_ID="2" SNAPSHOT_ID="1002" RULE_ID="[null]" characteristic_id="[null]" person_id="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/past_measures_with_characteristic_id.xml b/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/past_measures_with_characteristic_id.xml new file mode 100644 index 00000000000..7e06f10c94c --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/past_measures_with_characteristic_id.xml @@ -0,0 +1,28 @@ +<dataset> + + <metrics id="1" name="sqale_index" VAL_TYPE="WORK_DUR" DESCRIPTION="[null]" short_name="" enabled="[true]"/> + + <!-- Root characteristic --> + <characteristics id="10" kee="PORTABILITY" name="Portability" parent_id="[null]" characteristic_order="1" enabled="[true]" created_at="2013-11-20" updated_at="2013-11-22"/> + + <!-- Characteristic --> + <characteristics id="11" kee="COMPILER_RELATED_PORTABILITY" name="Compiler related portability" parent_id="10" characteristic_order="[null]" enabled="[true]" + created_at="2013-11-20" updated_at="2013-11-22"/> + + <!-- project --> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project" + root_id="[null]" uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD." enabled="[true]"/> + + <!-- snapshots --> + <snapshots id="1000" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + scope="PRJ" qualifier="TRK" created_at="1225544280000" build_date="1225544280000" version="[null]" path="" + status="P" islast="[false]" depth="0"/> + + <!-- project measures --> + <project_measures id="1" VALUE="60" METRIC_ID="1" SNAPSHOT_ID="1000" RULE_ID="[null]" characteristic_id="[null]"/> + + <project_measures id="2" VALUE="20" METRIC_ID="1" SNAPSHOT_ID="1000" RULE_ID="[null]" characteristic_id="10"/> + + <project_measures id="3" VALUE="40" METRIC_ID="1" SNAPSHOT_ID="1000" RULE_ID="[null]" characteristic_id="11"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/past_measures_with_person_id.xml b/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/past_measures_with_person_id.xml new file mode 100644 index 00000000000..47a1c6933e4 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/past_measures_with_person_id.xml @@ -0,0 +1,22 @@ +<dataset> + + <metrics delete_historical_data="[null]" id="1" name="sqale_index" VAL_TYPE="INT" DESCRIPTION="[null]" enabled="[true]"/> + + <!-- project --> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project" + root_id="[null]" uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD." + enabled="[true]"/> + + <!-- snapshots --> + <snapshots id="1000" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + scope="PRJ" qualifier="TRK" created_at="1225544280000" build_date="1225544280000" version="[null]" path="" + status="P" islast="[false]" depth="0"/> + + <!-- project measures --> + <project_measures id="1" VALUE="60" METRIC_ID="1" SNAPSHOT_ID="1000" RULE_ID="[null]" person_id="[null]"/> + + <project_measures id="2" VALUE="20" METRIC_ID="1" SNAPSHOT_ID="1000" RULE_ID="[null]" person_id="20"/> + + <project_measures id="3" VALUE="40" METRIC_ID="1" SNAPSHOT_ID="1000" RULE_ID="[null]" person_id="21"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/past_measures_with_rule_id.xml b/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/past_measures_with_rule_id.xml new file mode 100644 index 00000000000..b6ccf49fca2 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/past_measures_with_rule_id.xml @@ -0,0 +1,32 @@ +<dataset> + + <metrics delete_historical_data="[null]" id="1" name="minor_violations" VAL_TYPE="INT" DESCRIPTION="[null]" enabled="[true]"/> + + <rules tags="[null]" system_tags="[null]" id="30" name="Classes that override clone should be Cloneable and call super.clone()" + plugin_rule_key="S1182" + plugin_config_key="S1182" plugin_name="squid" description="[null]" priority="4" status="READY" + is_template="[false]" template_id="[null]"/> + + <rules tags="[null]" system_tags="[null]" id="31" name="Overriding methods should do more than simply call the same method in the super class" + plugin_rule_key="S1185" + plugin_config_key="S1185" plugin_name="squid" description="[null]" priority="1" status="READY" + is_template="[false]" template_id="[null]"/> + + <!-- project --> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project" + root_id="[null]" uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD." + enabled="[true]"/> + + <!-- snapshots --> + <snapshots id="1000" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" + scope="PRJ" qualifier="TRK" created_at="1225544280000" build_date="1225544280000" version="[null]" path="" + status="P" islast="[false]" depth="0"/> + + <!-- project measures --> + <project_measures id="1" VALUE="60" METRIC_ID="1" SNAPSHOT_ID="1000" RULE_ID="[null]" characteristic_id="[null]" person_id="[null]"/> + + <project_measures id="2" VALUE="20" METRIC_ID="1" SNAPSHOT_ID="1000" RULE_ID="30" characteristic_id="[null]" person_id="[null]"/> + + <project_measures id="3" VALUE="40" METRIC_ID="1" SNAPSHOT_ID="1000" RULE_ID="31" characteristic_id="[null]" person_id="[null]"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/shared.xml b/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/shared.xml new file mode 100644 index 00000000000..c27311c8d38 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/measure/MeasureDaoTest/shared.xml @@ -0,0 +1,21 @@ +<dataset> + + <metrics id="10" name="authors_by_line"/> + <metrics id="11" name="coverage_line_hits_data"/> + <metrics id="12" name="ncloc"/> + + <projects id="1" kee="org.struts:struts-core:src/org/struts/RequestContext.java" enabled="[true]"/> + + <snapshots id="5" project_id="1" islast="[true]" /> + + <project_measures id="20" snapshot_id="5" metric_id="10" value="[null]" text_value="0123456789012345678901234567890123456789" measure_data="[null]" + variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]" + alert_status="[null]" alert_text="[null]" /> + <project_measures id="21" snapshot_id="5" metric_id="11" value="[null]" text_value="36=1;37=1;38=1;39=1;43=1;48=1;53=1" measure_data="[null]" + variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]" + alert_status="[null]" alert_text="[null]" /> + <project_measures id="22" snapshot_id="5" metric_id="12" value="10" text_value="[null]" measure_data="[null]" + variation_value_1="1" variation_value_2="2" variation_value_3="3" variation_value_4="4" variation_value_5="-5" + alert_status="OK" alert_text="Green"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete-result.xml b/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete-result.xml deleted file mode 100644 index 2283bba7d52..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete-result.xml +++ /dev/null @@ -1,11 +0,0 @@ -<dataset> - - <!--<active_rules created_at="[null]" updated_at="[null]" id="1" profile_id="1" rule_id="10" failure_level="2" inheritance="INHERITED"--> - - <active_rules created_at="[null]" updated_at="[null]" id="2" profile_id="2" rule_id="10" failure_level="0" - inheritance="[null]"/> - - <active_rules created_at="[null]" updated_at="[null]" id="3" profile_id="2" rule_id="11" failure_level="1" - inheritance="[null]"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete_from_profile-result.xml b/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete_from_profile-result.xml deleted file mode 100644 index 617cd7e08b0..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete_from_profile-result.xml +++ /dev/null @@ -1,10 +0,0 @@ -<dataset> - - <active_rules created_at="[null]" updated_at="[null]" id="1" profile_id="1" rule_id="10" failure_level="2" - inheritance="INHERITED"/> - - <!--<active_rules created_at="[null]" updated_at="[null]" id="2" profile_id="2" rule_id="10" failure_level="0" inheritance="[null]"--> - - <!--<active_rules created_at="[null]" updated_at="[null]" id="3" profile_id="2" rule_id="11" failure_level="1" inheritance="[null]"--> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete_from_rule-result.xml b/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete_from_rule-result.xml deleted file mode 100644 index a06288e57b6..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete_from_rule-result.xml +++ /dev/null @@ -1,11 +0,0 @@ -<dataset> - - <active_rules created_at="[null]" updated_at="[null]" id="1" profile_id="1" rule_id="10" failure_level="2" - inheritance="INHERITED"/> - - <active_rules created_at="[null]" updated_at="[null]" id="2" profile_id="2" rule_id="10" failure_level="0" - inheritance="[null]"/> - - <!--<active_rules created_at="[null]" updated_at="[null]" id="3" profile_id="2" rule_id="11" failure_level="1" inheritance="[null]"/>--> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete_parameter-result.xml b/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete_parameter-result.xml deleted file mode 100644 index 900eb2c2874..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete_parameter-result.xml +++ /dev/null @@ -1,14 +0,0 @@ -<dataset> - - <active_rules created_at="[null]" updated_at="[null]" id="1" profile_id="1" rule_id="10" failure_level="2" - inheritance="INHERITED"/> - - <active_rules created_at="[null]" updated_at="[null]" id="2" profile_id="2" rule_id="10" failure_level="0" - inheritance="[null]"/> - - <!--<active_rule_parameters id="1" active_rule_id="1" rules_parameter_id="1" rules_parameter_key="max" value="20"/>--> - <active_rule_parameters id="2" active_rule_id="1" rules_parameter_id="2" rules_parameter_key="format" value="html"/> - - <active_rule_parameters id="3" active_rule_id="2" rules_parameter_id="1" rules_parameter_key="max" value="15"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete_parameters-result.xml b/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete_parameters-result.xml deleted file mode 100644 index b8aba08833d..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete_parameters-result.xml +++ /dev/null @@ -1,14 +0,0 @@ -<dataset> - - <active_rules created_at="[null]" updated_at="[null]" id="1" profile_id="1" rule_id="10" failure_level="2" - inheritance="INHERITED"/> - - <active_rules created_at="[null]" updated_at="[null]" id="2" profile_id="2" rule_id="10" failure_level="0" - inheritance="[null]"/> - - <!--<active_rule_parameters id="1" active_rule_id="1" rules_parameter_id="1" rules_parameter_key="max" value="20"/>--> - <!--<active_rule_parameters id="2" active_rule_id="1" rules_parameter_id="2" rules_parameter_key="format" value="html"/>--> - - <active_rule_parameters id="3" active_rule_id="2" rules_parameter_id="1" rules_parameter_key="max" value="15"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete_parameters_from_profile_id-result.xml b/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete_parameters_from_profile_id-result.xml deleted file mode 100644 index d1bbff5912e..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete_parameters_from_profile_id-result.xml +++ /dev/null @@ -1,19 +0,0 @@ -<dataset> - - <active_rules created_at="[null]" updated_at="[null]" id="1" profile_id="1" rule_id="10" failure_level="2" - inheritance="INHERITED"/> - - <!-- Parent of Active rule 1 --> - <active_rules created_at="[null]" updated_at="[null]" id="2" profile_id="2" rule_id="10" failure_level="0" - inheritance="[null]"/> - - <active_rules created_at="[null]" updated_at="[null]" id="3" profile_id="2" rule_id="11" failure_level="1" - inheritance="[null]"/> - - <active_rule_parameters id="1" active_rule_id="1" rules_parameter_id="1" rules_parameter_key="max" value="20"/> - <active_rule_parameters id="2" active_rule_id="1" rules_parameter_id="2" rules_parameter_key="format" value="html"/> - - <!--<active_rule_parameters id="3" active_rule_id="2" rules_parameter_id="1" rules_parameter_key="max" value="15"/>--> - <!--<active_rule_parameters id="4" active_rule_id="3" rules_parameter_id="2" rules_parameter_key="format" value="text"/>--> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete_parameters_from_profile_id.xml b/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete_parameters_from_profile_id.xml deleted file mode 100644 index 47c6ceeac24..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/delete_parameters_from_profile_id.xml +++ /dev/null @@ -1,19 +0,0 @@ -<dataset> - - <active_rules created_at="[null]" updated_at="[null]" id="1" profile_id="1" rule_id="10" failure_level="2" - inheritance="INHERITED"/> - - <!-- Parent of Active rule 1 --> - <active_rules created_at="[null]" updated_at="[null]" id="2" profile_id="2" rule_id="10" failure_level="0" - inheritance="[null]"/> - - <active_rules created_at="[null]" updated_at="[null]" id="3" profile_id="2" rule_id="11" failure_level="1" - inheritance="[null]"/> - - <active_rule_parameters id="1" active_rule_id="1" rules_parameter_id="1" rules_parameter_key="max" value="20"/> - <active_rule_parameters id="2" active_rule_id="1" rules_parameter_id="2" rules_parameter_key="format" value="html"/> - - <active_rule_parameters id="3" active_rule_id="2" rules_parameter_id="1" rules_parameter_key="max" value="15"/> - <active_rule_parameters id="4" active_rule_id="3" rules_parameter_id="2" rules_parameter_key="format" value="text"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/insert-result.xml b/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/insert-result.xml deleted file mode 100644 index 574cbabdd56..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/insert-result.xml +++ /dev/null @@ -1,6 +0,0 @@ -<dataset> - - <active_rules created_at="[null]" updated_at="[null]" id="1" profile_id="1" rule_id="10" failure_level="2" - inheritance="INHERITED"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/insert_parameter-result.xml b/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/insert_parameter-result.xml deleted file mode 100644 index ed2e17d48d3..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/insert_parameter-result.xml +++ /dev/null @@ -1,5 +0,0 @@ -<dataset> - - <active_rule_parameters id="1" active_rule_id="1" rules_parameter_id="1" rules_parameter_key="max" value="20"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/shared.xml b/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/shared.xml deleted file mode 100644 index b6d5461c10d..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/shared.xml +++ /dev/null @@ -1,22 +0,0 @@ -<dataset> - - <active_rules created_at="[null]" updated_at="[null]" id="1" profile_id="1" rule_id="10" failure_level="2" - inheritance="INHERITED"/> - - <!-- Parent of Active rule 1 --> - <active_rules created_at="[null]" updated_at="[null]" id="2" profile_id="2" rule_id="10" failure_level="0" - inheritance="[null]"/> - - <active_rules created_at="[null]" updated_at="[null]" id="3" profile_id="2" rule_id="11" failure_level="1" - inheritance="[null]"/> - - <active_rule_parameters id="1" active_rule_id="1" rules_parameter_id="1" rules_parameter_key="max" value="20"/> - <active_rule_parameters id="2" active_rule_id="1" rules_parameter_id="2" rules_parameter_key="format" value="html"/> - - <active_rule_parameters id="3" active_rule_id="2" rules_parameter_id="1" rules_parameter_key="max" value="15"/> - - <rules_profiles id="1" name="Child" language="java" parent_kee="parent" kee="child" is_default="[false]"/> - - <rules_profiles id="2" name="Parent" language="java" parent_kee="[null]" kee="parent" is_default="[false]"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/update-result.xml b/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/update-result.xml deleted file mode 100644 index 30111d636a7..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/update-result.xml +++ /dev/null @@ -1,12 +0,0 @@ -<dataset> - - <active_rules created_at="[null]" updated_at="[null]" id="1" profile_id="1" rule_id="10" failure_level="4" - inheritance="[null]"/> - - <active_rules created_at="[null]" updated_at="[null]" id="2" profile_id="2" rule_id="10" failure_level="0" - inheritance="[null]"/> - - <active_rules created_at="[null]" updated_at="[null]" id="3" profile_id="2" rule_id="11" failure_level="1" - inheritance="[null]"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/update_parameter-result.xml b/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/update_parameter-result.xml deleted file mode 100644 index 289da2f39f2..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/qualityprofile/ActiveRuleDaoTest/update_parameter-result.xml +++ /dev/null @@ -1,8 +0,0 @@ -<dataset> - - <active_rule_parameters id="1" active_rule_id="2" rules_parameter_id="3" rules_parameter_key="newMax" value="30"/> - <active_rule_parameters id="2" active_rule_id="1" rules_parameter_id="2" rules_parameter_key="format" value="html"/> - - <active_rule_parameters id="3" active_rule_id="2" rules_parameter_id="1" rules_parameter_key="max" value="15"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/source/FileSourceDaoTest/insert-result.xml b/sonar-db/src/test/resources/org/sonar/db/source/FileSourceDaoTest/insert-result.xml new file mode 100644 index 00000000000..4f347782dca --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/source/FileSourceDaoTest/insert-result.xml @@ -0,0 +1,17 @@ +<dataset> + + <file_sources id="101" project_uuid="PRJ_UUID" file_uuid="FILE1_UUID" + binary_data="abcde" data_hash="hash" + line_hashes="ABC\nDEF\nGHI" + src_hash="FILE_HASH" + created_at="1500000000000" updated_at="1500000000000" data_type="SOURCE" /> + + + <file_sources id="102" project_uuid="PRJ_UUID" file_uuid="FILE2_UUID" + binary_data="[ignore]" + data_hash="FILE2_DATA_HASH" + line_hashes="LINE1_HASH\nLINE2_HASH" + src_hash="FILE2_HASH" + created_at="1500000000000" updated_at="1500000000001" data_type="SOURCE" /> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/source/FileSourceDaoTest/no_line_hashes_when_only_test_data.xml b/sonar-db/src/test/resources/org/sonar/db/source/FileSourceDaoTest/no_line_hashes_when_only_test_data.xml new file mode 100644 index 00000000000..010394a156e --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/source/FileSourceDaoTest/no_line_hashes_when_only_test_data.xml @@ -0,0 +1,9 @@ +<dataset> + + <file_sources id="101" project_uuid="PRJ_UUID" file_uuid="FILE1_UUID" + binary_data="abcde" data_hash="[null]" + line_hashes="[null]" + src_hash="[null]" + created_at="1500000000000" updated_at="1500000000000" data_type="TEST" /> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/source/FileSourceDaoTest/shared.xml b/sonar-db/src/test/resources/org/sonar/db/source/FileSourceDaoTest/shared.xml new file mode 100644 index 00000000000..5187ca217af --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/source/FileSourceDaoTest/shared.xml @@ -0,0 +1,9 @@ +<dataset> + + <file_sources id="101" project_uuid="PRJ_UUID" file_uuid="FILE1_UUID" + binary_data="abcde" data_hash="hash" + line_hashes="ABC\nDEF\nGHI" + src_hash="FILE_HASH" + created_at="1500000000000" updated_at="1500000000000" data_type="SOURCE" /> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/source/FileSourceDaoTest/update-result.xml b/sonar-db/src/test/resources/org/sonar/db/source/FileSourceDaoTest/update-result.xml new file mode 100644 index 00000000000..8dbe32d946d --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/source/FileSourceDaoTest/update-result.xml @@ -0,0 +1,11 @@ +<dataset> + + <file_sources id="101" project_uuid="PRJ_UUID" file_uuid="FILE1_UUID" + binary_data="[ignore]" + data_hash="NEW_DATA_HASH" + line_hashes="NEW_LINE_HASHES" + src_hash="NEW_FILE_HASH" + created_at="1500000000000" updated_at="1500000000002" data_type="SOURCE" /> + + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/source/FileSourceDaoTest/update_date_when_updated_date_is_zero-result.xml b/sonar-db/src/test/resources/org/sonar/db/source/FileSourceDaoTest/update_date_when_updated_date_is_zero-result.xml new file mode 100644 index 00000000000..1ba1fe63a55 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/source/FileSourceDaoTest/update_date_when_updated_date_is_zero-result.xml @@ -0,0 +1,18 @@ +<dataset> + + <!-- Updated --> + <file_sources id="101" project_uuid="ABCD" file_uuid="FILE1_UUID" + binary_data="abcde" data_hash="hash" line_hashes="ABC\nDEF\nGHI" src_hash="FILE_HASH" + created_at="1500000000000" updated_at="1500000000002" data_type="SOURCE" /> + + <!-- Not updated because updated_at is not null --> + <file_sources id="102" project_uuid="ABCD" file_uuid="FILE2_UUID" + binary_data="abcde" data_hash="hash" line_hashes="ABC\nDEF\nGHI" src_hash="FILE_HASH" + created_at="1500000000000" updated_at="1500000000000" data_type="SOURCE" /> + + <!-- Not updated because on another project --> + <file_sources id="103" project_uuid="BCDE" file_uuid="FILE3_UUID" + binary_data="abcde" data_hash="hash" line_hashes="ABC\nDEF\nGHI" src_hash="FILE_HASH" + created_at="1500000000000" updated_at="0" data_type="SOURCE" /> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/source/FileSourceDaoTest/update_date_when_updated_date_is_zero.xml b/sonar-db/src/test/resources/org/sonar/db/source/FileSourceDaoTest/update_date_when_updated_date_is_zero.xml new file mode 100644 index 00000000000..77a1f85b06a --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/source/FileSourceDaoTest/update_date_when_updated_date_is_zero.xml @@ -0,0 +1,16 @@ +<dataset> + + <!-- Only this source should be updated --> + <file_sources id="101" project_uuid="ABCD" file_uuid="FILE1_UUID" + binary_data="abcde" data_hash="hash" line_hashes="ABC\nDEF\nGHI" src_hash="FILE_HASH" + created_at="1500000000000" updated_at="0" data_type="SOURCE" /> + + <file_sources id="102" project_uuid="ABCD" file_uuid="FILE2_UUID" + binary_data="abcde" data_hash="hash" line_hashes="ABC\nDEF\nGHI" src_hash="FILE_HASH" + created_at="1500000000000" updated_at="1500000000000" data_type="SOURCE" /> + + <file_sources id="103" project_uuid="BCDE" file_uuid="FILE3_UUID" + binary_data="abcde" data_hash="hash" line_hashes="ABC\nDEF\nGHI" src_hash="FILE_HASH" + created_at="1500000000000" updated_at="0" data_type="SOURCE" /> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/user/UserGroupDaoTest/delete_members_by_group_id-result.xml b/sonar-db/src/test/resources/org/sonar/db/user/UserGroupDaoTest/delete_members_by_group_id-result.xml new file mode 100644 index 00000000000..edac414e636 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/user/UserGroupDaoTest/delete_members_by_group_id-result.xml @@ -0,0 +1,6 @@ +<dataset> + + <groups_users user_id="1" group_id="2"/> + <groups_users user_id="2" group_id="2"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/user/UserGroupDaoTest/delete_members_by_group_id.xml b/sonar-db/src/test/resources/org/sonar/db/user/UserGroupDaoTest/delete_members_by_group_id.xml new file mode 100644 index 00000000000..2430e53dd8e --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/user/UserGroupDaoTest/delete_members_by_group_id.xml @@ -0,0 +1,8 @@ +<dataset> + + <groups_users user_id="1" group_id="1"/> + <groups_users user_id="2" group_id="1"/> + <groups_users user_id="1" group_id="2"/> + <groups_users user_id="2" group_id="2"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/user/UserGroupDaoTest/insert-result.xml b/sonar-db/src/test/resources/org/sonar/db/user/UserGroupDaoTest/insert-result.xml new file mode 100644 index 00000000000..2e5bb1ada57 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/user/UserGroupDaoTest/insert-result.xml @@ -0,0 +1,5 @@ +<dataset> + + <groups_users user_id="1" group_id="2"/> + +</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/jpa/dao/ProfilesDaoTest/shouldGetProfiles.xml b/sonar-db/src/test/resources/org/sonar/jpa/dao/ProfilesDaoTest/shouldGetProfiles.xml deleted file mode 100644 index aeb851beb8e..00000000000 --- a/sonar-db/src/test/resources/org/sonar/jpa/dao/ProfilesDaoTest/shouldGetProfiles.xml +++ /dev/null @@ -1,7 +0,0 @@ -<dataset> - - <rules_profiles id="1" name="profile one" language="java" is_default="[false]"/> - <rules_profiles id="2" name="profile two" language="java" is_default="[false]"/> - <rules_profiles id="3" name="profile three" language="plsql" is_default="[false]"/> - -</dataset>
\ No newline at end of file |