123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- /*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.annotations.VisibleForTesting;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.List;
- import javax.annotation.Nullable;
- import org.apache.ibatis.logging.LogFactory;
- import org.apache.ibatis.session.ExecutorType;
- import org.apache.ibatis.session.SqlSession;
- import org.apache.ibatis.session.SqlSessionFactory;
- import org.apache.ibatis.session.SqlSessionFactoryBuilder;
- import org.apache.ibatis.session.TransactionIsolationLevel;
- import org.sonar.api.Startable;
- import org.sonar.db.alm.pat.AlmPatMapper;
- import org.sonar.db.alm.setting.AlmSettingMapper;
- import org.sonar.db.alm.setting.ProjectAlmSettingMapper;
- import org.sonar.db.ce.CeActivityMapper;
- import org.sonar.db.ce.CeQueueMapper;
- import org.sonar.db.ce.CeScannerContextMapper;
- import org.sonar.db.ce.CeTaskCharacteristicDto;
- import org.sonar.db.ce.CeTaskCharacteristicMapper;
- import org.sonar.db.ce.CeTaskInputMapper;
- import org.sonar.db.ce.CeTaskMessageMapper;
- import org.sonar.db.component.AnalysisPropertiesMapper;
- import org.sonar.db.component.ApplicationProjectsMapper;
- import org.sonar.db.component.BranchMapper;
- import org.sonar.db.component.ComponentDto;
- import org.sonar.db.component.ComponentDtoWithSnapshotId;
- import org.sonar.db.component.ComponentKeyUpdaterMapper;
- import org.sonar.db.component.ComponentMapper;
- import org.sonar.db.component.ComponentWithModuleUuidDto;
- import org.sonar.db.component.FilePathWithHashDto;
- import org.sonar.db.component.KeyWithUuidDto;
- import org.sonar.db.component.ProjectLinkMapper;
- import org.sonar.db.component.ResourceDto;
- import org.sonar.db.component.ScrapAnalysisPropertyDto;
- import org.sonar.db.component.SnapshotDto;
- import org.sonar.db.component.SnapshotMapper;
- import org.sonar.db.component.UuidWithProjectUuidDto;
- import org.sonar.db.component.ViewsSnapshotDto;
- import org.sonar.db.duplication.DuplicationMapper;
- import org.sonar.db.duplication.DuplicationUnitDto;
- import org.sonar.db.es.EsQueueMapper;
- import org.sonar.db.event.EventComponentChangeMapper;
- import org.sonar.db.event.EventDto;
- import org.sonar.db.event.EventMapper;
- import org.sonar.db.issue.IssueChangeDto;
- import org.sonar.db.issue.IssueChangeMapper;
- import org.sonar.db.issue.IssueDto;
- import org.sonar.db.issue.IssueMapper;
- import org.sonar.db.issue.PrIssueDto;
- import org.sonar.db.mapping.ProjectMappingDto;
- import org.sonar.db.mapping.ProjectMappingsMapper;
- import org.sonar.db.measure.LiveMeasureMapper;
- import org.sonar.db.measure.MeasureDto;
- import org.sonar.db.measure.MeasureMapper;
- import org.sonar.db.measure.custom.CustomMeasureDto;
- import org.sonar.db.measure.custom.CustomMeasureMapper;
- import org.sonar.db.metric.MetricMapper;
- import org.sonar.db.newcodeperiod.NewCodePeriodMapper;
- import org.sonar.db.notification.NotificationQueueDto;
- import org.sonar.db.notification.NotificationQueueMapper;
- import org.sonar.db.permission.AuthorizationMapper;
- import org.sonar.db.permission.GroupPermissionDto;
- import org.sonar.db.permission.GroupPermissionMapper;
- import org.sonar.db.permission.UserPermissionDto;
- import org.sonar.db.permission.UserPermissionMapper;
- import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto;
- import org.sonar.db.permission.template.PermissionTemplateCharacteristicMapper;
- import org.sonar.db.permission.template.PermissionTemplateDto;
- import org.sonar.db.permission.template.PermissionTemplateGroupDto;
- import org.sonar.db.permission.template.PermissionTemplateMapper;
- import org.sonar.db.permission.template.PermissionTemplateUserDto;
- import org.sonar.db.plugin.PluginDto;
- import org.sonar.db.plugin.PluginMapper;
- import org.sonar.db.project.ProjectDto;
- import org.sonar.db.project.ProjectMapper;
- import org.sonar.db.property.InternalComponentPropertiesMapper;
- import org.sonar.db.property.InternalComponentPropertyDto;
- import org.sonar.db.property.InternalPropertiesMapper;
- import org.sonar.db.property.InternalPropertyDto;
- import org.sonar.db.property.PropertiesMapper;
- import org.sonar.db.property.ScrapPropertyDto;
- import org.sonar.db.purge.PurgeMapper;
- import org.sonar.db.purge.PurgeableAnalysisDto;
- import org.sonar.db.qualitygate.ProjectQgateAssociationDto;
- import org.sonar.db.qualitygate.ProjectQgateAssociationMapper;
- import org.sonar.db.qualitygate.QualityGateConditionDto;
- import org.sonar.db.qualitygate.QualityGateConditionMapper;
- import org.sonar.db.qualitygate.QualityGateDto;
- import org.sonar.db.qualitygate.QualityGateMapper;
- import org.sonar.db.qualityprofile.ActiveRuleDto;
- import org.sonar.db.qualityprofile.ActiveRuleMapper;
- import org.sonar.db.qualityprofile.ActiveRuleParamDto;
- import org.sonar.db.qualityprofile.DefaultQProfileMapper;
- import org.sonar.db.qualityprofile.QProfileChangeMapper;
- import org.sonar.db.qualityprofile.QProfileEditGroupsMapper;
- import org.sonar.db.qualityprofile.QProfileEditUsersMapper;
- import org.sonar.db.qualityprofile.QualityProfileExportMapper;
- import org.sonar.db.qualityprofile.QualityProfileMapper;
- import org.sonar.db.rule.RuleDto;
- import org.sonar.db.rule.RuleMapper;
- import org.sonar.db.rule.RuleParamDto;
- import org.sonar.db.rule.RuleRepositoryMapper;
- import org.sonar.db.schemamigration.SchemaMigrationDto;
- import org.sonar.db.schemamigration.SchemaMigrationMapper;
- import org.sonar.db.source.FileSourceMapper;
- import org.sonar.db.user.GroupDto;
- import org.sonar.db.user.GroupMapper;
- import org.sonar.db.user.GroupMembershipDto;
- import org.sonar.db.user.GroupMembershipMapper;
- import org.sonar.db.user.RoleMapper;
- import org.sonar.db.user.SamlMessageIdMapper;
- import org.sonar.db.user.SessionTokenMapper;
- import org.sonar.db.user.UserDismissedMessagesMapper;
- import org.sonar.db.user.UserDto;
- import org.sonar.db.user.UserGroupDto;
- import org.sonar.db.user.UserGroupMapper;
- import org.sonar.db.user.UserMapper;
- import org.sonar.db.user.UserPropertiesMapper;
- import org.sonar.db.user.UserTokenCount;
- import org.sonar.db.user.UserTokenDto;
- import org.sonar.db.user.UserTokenMapper;
- import org.sonar.db.webhook.WebhookDeliveryMapper;
- import org.sonar.db.webhook.WebhookMapper;
-
- public class MyBatis implements Startable {
- private final List<MyBatisConfExtension> confExtensions;
- private final Database database;
- private SqlSessionFactory sessionFactory;
-
- public MyBatis(Database database) {
- this(database, null);
- }
-
- public MyBatis(Database database, @Nullable MyBatisConfExtension[] confExtensions) {
- this.confExtensions = confExtensions == null ? Collections.emptyList() : Arrays.asList(confExtensions);
- this.database = database;
- }
-
- @Override
- public void start() {
- LogFactory.useSlf4jLogging();
-
- MyBatisConfBuilder confBuilder = new MyBatisConfBuilder(database);
-
- // DTO aliases, keep them sorted alphabetically
- confBuilder.loadAlias("ActiveRule", ActiveRuleDto.class);
- confBuilder.loadAlias("ActiveRuleParam", ActiveRuleParamDto.class);
- confBuilder.loadAlias("CeTaskCharacteristic", CeTaskCharacteristicDto.class);
- confBuilder.loadAlias("Component", ComponentDto.class);
- confBuilder.loadAlias("ComponentWithModuleUuid", ComponentWithModuleUuidDto.class);
- confBuilder.loadAlias("ComponentWithSnapshot", ComponentDtoWithSnapshotId.class);
- confBuilder.loadAlias("CustomMeasure", CustomMeasureDto.class);
- confBuilder.loadAlias("DuplicationUnit", DuplicationUnitDto.class);
- confBuilder.loadAlias("Event", EventDto.class);
- confBuilder.loadAlias("FilePathWithHash", FilePathWithHashDto.class);
- confBuilder.loadAlias("KeyWithUuid", KeyWithUuidDto.class);
- confBuilder.loadAlias("Group", GroupDto.class);
- confBuilder.loadAlias("GroupMembership", GroupMembershipDto.class);
- confBuilder.loadAlias("GroupPermission", GroupPermissionDto.class);
- confBuilder.loadAlias("InternalProperty", InternalPropertyDto.class);
- confBuilder.loadAlias("InternalComponentProperty", InternalComponentPropertyDto.class);
- confBuilder.loadAlias("IssueChange", IssueChangeDto.class);
- confBuilder.loadAlias("KeyLongValue", KeyLongValue.class);
- confBuilder.loadAlias("Issue", IssueDto.class);
- confBuilder.loadAlias("Measure", MeasureDto.class);
- confBuilder.loadAlias("NotificationQueue", NotificationQueueDto.class);
- confBuilder.loadAlias("PermissionTemplateCharacteristic", PermissionTemplateCharacteristicDto.class);
- confBuilder.loadAlias("PermissionTemplateGroup", PermissionTemplateGroupDto.class);
- confBuilder.loadAlias("PermissionTemplate", PermissionTemplateDto.class);
- confBuilder.loadAlias("PermissionTemplateUser", PermissionTemplateUserDto.class);
- confBuilder.loadAlias("Plugin", PluginDto.class);
- confBuilder.loadAlias("PrIssue", PrIssueDto.class);
- confBuilder.loadAlias("ProjectQgateAssociation", ProjectQgateAssociationDto.class);
- confBuilder.loadAlias("Project", ProjectDto.class);
- confBuilder.loadAlias("ProjectMapping", ProjectMappingDto.class);
- confBuilder.loadAlias("PurgeableAnalysis", PurgeableAnalysisDto.class);
- confBuilder.loadAlias("QualityGateCondition", QualityGateConditionDto.class);
- confBuilder.loadAlias("QualityGate", QualityGateDto.class);
- confBuilder.loadAlias("Resource", ResourceDto.class);
- confBuilder.loadAlias("RuleParam", RuleParamDto.class);
- confBuilder.loadAlias("Rule", RuleDto.class);
- confBuilder.loadAlias("SchemaMigration", SchemaMigrationDto.class);
- confBuilder.loadAlias("ScrapProperty", ScrapPropertyDto.class);
- confBuilder.loadAlias("ScrapAnalysisProperty", ScrapAnalysisPropertyDto.class);
- confBuilder.loadAlias("Snapshot", SnapshotDto.class);
- confBuilder.loadAlias("UserGroup", UserGroupDto.class);
- confBuilder.loadAlias("UserPermission", UserPermissionDto.class);
- confBuilder.loadAlias("UserTokenCount", UserTokenCount.class);
- confBuilder.loadAlias("UserToken", UserTokenDto.class);
- confBuilder.loadAlias("User", UserDto.class);
- confBuilder.loadAlias("UuidWithProjectUuid", UuidWithProjectUuidDto.class);
- confBuilder.loadAlias("ViewsSnapshot", ViewsSnapshotDto.class);
- confExtensions.forEach(ext -> ext.loadAliases(confBuilder::loadAlias));
-
- // keep them sorted alphabetically
- Class<?>[] mappers = {
- ActiveRuleMapper.class,
- AlmPatMapper.class,
- AlmSettingMapper.class,
- AnalysisPropertiesMapper.class,
- ApplicationProjectsMapper.class,
- AuthorizationMapper.class,
- BranchMapper.class,
- CeActivityMapper.class,
- CeQueueMapper.class,
- CeScannerContextMapper.class,
- CeTaskInputMapper.class,
- CeTaskCharacteristicMapper.class,
- CeTaskMessageMapper.class,
- ComponentKeyUpdaterMapper.class,
- ComponentMapper.class,
- LiveMeasureMapper.class,
- CustomMeasureMapper.class,
- DefaultQProfileMapper.class,
- DuplicationMapper.class,
- EsQueueMapper.class,
- EventMapper.class,
- EventComponentChangeMapper.class,
- FileSourceMapper.class,
- GroupMapper.class,
- GroupMembershipMapper.class,
- GroupPermissionMapper.class,
- InternalComponentPropertiesMapper.class,
- InternalPropertiesMapper.class,
- IsAliveMapper.class,
- IssueChangeMapper.class,
- IssueMapper.class,
- MeasureMapper.class,
- MetricMapper.class,
- NewCodePeriodMapper.class,
- NotificationQueueMapper.class,
- PermissionTemplateCharacteristicMapper.class,
- PermissionTemplateMapper.class,
- PluginMapper.class,
- ProjectAlmSettingMapper.class,
- ProjectLinkMapper.class,
- ProjectMapper.class,
- ProjectMappingsMapper.class,
- ProjectQgateAssociationMapper.class,
- PropertiesMapper.class,
- PurgeMapper.class,
- QProfileChangeMapper.class,
- QProfileEditGroupsMapper.class,
- QProfileEditUsersMapper.class,
- QualityGateConditionMapper.class,
- QualityGateMapper.class,
- QualityProfileMapper.class,
- QualityProfileExportMapper.class,
- RoleMapper.class,
- RuleMapper.class,
- RuleRepositoryMapper.class,
- SamlMessageIdMapper.class,
- SchemaMigrationMapper.class,
- SessionTokenMapper.class,
- SnapshotMapper.class,
- UserDismissedMessagesMapper.class,
- UserGroupMapper.class,
- UserMapper.class,
- UserPermissionMapper.class,
- UserPropertiesMapper.class,
- UserTokenMapper.class,
- WebhookMapper.class,
- WebhookDeliveryMapper.class
- };
- confBuilder.loadMappers(mappers);
- confExtensions.stream()
- .flatMap(MyBatisConfExtension::getMapperClasses)
- .forEach(confBuilder::loadMapper);
-
- sessionFactory = new SqlSessionFactoryBuilder().build(confBuilder.build());
- }
-
- @Override
- public void stop() {
- // nothing to do
- }
-
- @VisibleForTesting
- SqlSessionFactory getSessionFactory() {
- return sessionFactory;
- }
-
- public DbSession openSession(boolean batch) {
- if (batch) {
- SqlSession session = sessionFactory.openSession(ExecutorType.BATCH, TransactionIsolationLevel.READ_COMMITTED);
- return new BatchSession(session);
- }
- SqlSession session = sessionFactory.openSession(ExecutorType.REUSE, TransactionIsolationLevel.READ_COMMITTED);
- return new DbSessionImpl(session);
- }
-
- /**
- * 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);
- }
-
- private static 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);
- }
- }
- }
|