aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-db/src/main/java
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2015-07-05 10:06:55 +0200
committerSimon Brandhof <simon.brandhof@sonarsource.com>2015-07-06 09:22:44 +0200
commit32af292b745b7226bacc3f34d612437664af0ba3 (patch)
tree538d0b9852eaeb08ad685d426ea61c8170210e40 /sonar-db/src/main/java
parent1df148803610cd54f182b8636f01c0e6ece92b19 (diff)
downloadsonarqube-32af292b745b7226bacc3f34d612437664af0ba3.tar.gz
sonarqube-32af292b745b7226bacc3f34d612437664af0ba3.zip
Move some classes from sonar-server to sonar-db
Diffstat (limited to 'sonar-db/src/main/java')
-rw-r--r--sonar-db/src/main/java/org/sonar/core/timemachine/Periods.java2
-rw-r--r--sonar-db/src/main/java/org/sonar/db/AbstractDao.java (renamed from sonar-db/src/main/java/org/sonar/db/component/ComponentIndexMapper.java)22
-rw-r--r--sonar-db/src/main/java/org/sonar/db/DaoUtils.java88
-rw-r--r--sonar-db/src/main/java/org/sonar/db/DatabaseChecker.java86
-rw-r--r--sonar-db/src/main/java/org/sonar/db/DatabaseUtils.java61
-rw-r--r--sonar-db/src/main/java/org/sonar/db/DbClient2.java253
-rw-r--r--sonar-db/src/main/java/org/sonar/db/DefaultDatabase.java17
-rw-r--r--sonar-db/src/main/java/org/sonar/db/MyBatis.java47
-rw-r--r--sonar-db/src/main/java/org/sonar/db/ResultSetIterator.java115
-rw-r--r--sonar-db/src/main/java/org/sonar/db/activity/ActivityDao.java49
-rw-r--r--sonar-db/src/main/java/org/sonar/db/component/ComponentLinkDao.java45
-rw-r--r--sonar-db/src/main/java/org/sonar/db/component/ResourceDao.java71
-rw-r--r--sonar-db/src/main/java/org/sonar/db/component/ResourceIndexerDao.java21
-rw-r--r--sonar-db/src/main/java/org/sonar/db/component/ResourceIndexerMapper.java5
-rw-r--r--sonar-db/src/main/java/org/sonar/db/component/ResourceKeyUpdaterDao.java3
-rw-r--r--sonar-db/src/main/java/org/sonar/db/component/SnapshotDao.java107
-rw-r--r--sonar-db/src/main/java/org/sonar/db/compute/AnalysisReportDao.java107
-rw-r--r--sonar-db/src/main/java/org/sonar/db/dashboard/ActiveDashboardDao.java2
-rw-r--r--sonar-db/src/main/java/org/sonar/db/dashboard/DashboardDao.java20
-rw-r--r--sonar-db/src/main/java/org/sonar/db/dashboard/WidgetDao.java76
-rw-r--r--sonar-db/src/main/java/org/sonar/db/dashboard/WidgetPropertyDao.java90
-rw-r--r--sonar-db/src/main/java/org/sonar/db/duplication/DuplicationDao.java3
-rw-r--r--sonar-db/src/main/java/org/sonar/db/event/EventDao.java (renamed from sonar-db/src/main/java/org/sonar/batch/index/ResourceCopy.java)24
-rw-r--r--sonar-db/src/main/java/org/sonar/db/issue/ActionPlanDao.java2
-rw-r--r--sonar-db/src/main/java/org/sonar/db/issue/ActionPlanStatsDao.java12
-rw-r--r--sonar-db/src/main/java/org/sonar/db/issue/IssueDao.java49
-rw-r--r--sonar-db/src/main/java/org/sonar/db/issue/IssueFilterFavouriteDao.java3
-rw-r--r--sonar-db/src/main/java/org/sonar/db/measure/MeasureDao.java87
-rw-r--r--sonar-db/src/main/java/org/sonar/db/measure/MeasureFilterDao.java3
-rw-r--r--sonar-db/src/main/java/org/sonar/db/notification/NotificationQueueDao.java3
-rw-r--r--sonar-db/src/main/java/org/sonar/db/permission/PermissionDao.java5
-rw-r--r--sonar-db/src/main/java/org/sonar/db/property/PropertiesDao.java3
-rw-r--r--sonar-db/src/main/java/org/sonar/db/purge/PurgeDao.java24
-rw-r--r--sonar-db/src/main/java/org/sonar/db/purge/period/DefaultPeriodCleaner.java11
-rw-r--r--sonar-db/src/main/java/org/sonar/db/qualityprofile/ActiveRuleDao.java67
-rw-r--r--sonar-db/src/main/java/org/sonar/db/rule/RuleDao.java3
-rw-r--r--sonar-db/src/main/java/org/sonar/db/semaphore/SemaphoreDao.java6
-rw-r--r--sonar-db/src/main/java/org/sonar/db/source/FileSourceDao.java146
-rw-r--r--sonar-db/src/main/java/org/sonar/db/user/AuthorDao.java3
-rw-r--r--sonar-db/src/main/java/org/sonar/db/user/AuthorizationDao.java3
-rw-r--r--sonar-db/src/main/java/org/sonar/db/user/GroupMembershipDao.java5
-rw-r--r--sonar-db/src/main/java/org/sonar/db/user/UserGroupDao.java (renamed from sonar-db/src/main/java/org/sonar/core/issue/db/package-info.java)26
42 files changed, 1509 insertions, 266 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);
+ }
+}