All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.db.MyBatis Maven / Gradle / Ivy

There is a newer version: 6.3.1
Show newest version
/*
 * SonarQube
 * Copyright (C) 2009-2016 SonarSource SA
 * mailto:contact 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 java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
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.sonar.api.utils.log.Loggers;
import org.sonar.db.activity.ActivityDto;
import org.sonar.db.activity.ActivityMapper;
import org.sonar.db.ce.CeActivityMapper;
import org.sonar.db.ce.CeQueueMapper;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentDtoWithSnapshotId;
import org.sonar.db.component.ComponentLinkDto;
import org.sonar.db.component.ComponentLinkMapper;
import org.sonar.db.component.ComponentMapper;
import org.sonar.db.component.FilePathWithHashDto;
import org.sonar.db.component.ResourceDto;
import org.sonar.db.component.ResourceIndexDto;
import org.sonar.db.component.ResourceIndexMapper;
import org.sonar.db.component.ResourceKeyUpdaterMapper;
import org.sonar.db.component.ResourceMapper;
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.dashboard.ActiveDashboardDto;
import org.sonar.db.dashboard.ActiveDashboardMapper;
import org.sonar.db.dashboard.DashboardDto;
import org.sonar.db.dashboard.DashboardMapper;
import org.sonar.db.dashboard.WidgetDto;
import org.sonar.db.dashboard.WidgetMapper;
import org.sonar.db.dashboard.WidgetPropertyDto;
import org.sonar.db.dashboard.WidgetPropertyMapper;
import org.sonar.db.debt.CharacteristicDto;
import org.sonar.db.debt.CharacteristicMapper;
import org.sonar.db.debt.RequirementMigrationDto;
import org.sonar.db.deprecated.WorkQueue;
import org.sonar.db.duplication.DuplicationMapper;
import org.sonar.db.duplication.DuplicationUnitDto;
import org.sonar.db.event.EventDto;
import org.sonar.db.event.EventMapper;
import org.sonar.db.issue.ActionPlanDto;
import org.sonar.db.issue.ActionPlanMapper;
import org.sonar.db.issue.ActionPlanStatsDto;
import org.sonar.db.issue.ActionPlanStatsMapper;
import org.sonar.db.issue.IssueChangeDto;
import org.sonar.db.issue.IssueChangeMapper;
import org.sonar.db.issue.IssueDto;
import org.sonar.db.issue.IssueFilterDto;
import org.sonar.db.issue.IssueFilterFavouriteDto;
import org.sonar.db.issue.IssueFilterFavouriteMapper;
import org.sonar.db.issue.IssueFilterMapper;
import org.sonar.db.issue.IssueMapper;
import org.sonar.db.loadedtemplate.LoadedTemplateDto;
import org.sonar.db.loadedtemplate.LoadedTemplateMapper;
import org.sonar.db.measure.MeasureDto;
import org.sonar.db.measure.MeasureFilterDto;
import org.sonar.db.measure.MeasureFilterFavouriteDto;
import org.sonar.db.measure.MeasureFilterFavouriteMapper;
import org.sonar.db.measure.MeasureFilterMapper;
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.notification.NotificationQueueDto;
import org.sonar.db.notification.NotificationQueueMapper;
import org.sonar.db.permission.GroupWithPermissionDto;
import org.sonar.db.permission.PermissionTemplateDto;
import org.sonar.db.permission.PermissionTemplateGroupDto;
import org.sonar.db.permission.PermissionTemplateMapper;
import org.sonar.db.permission.PermissionTemplateUserDto;
import org.sonar.db.permission.UserWithPermissionDto;
import org.sonar.db.property.PropertiesMapper;
import org.sonar.db.property.PropertyDto;
import org.sonar.db.purge.IdUuidPair;
import org.sonar.db.purge.PurgeMapper;
import org.sonar.db.purge.PurgeableSnapshotDto;
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.QualityProfileDto;
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.source.FileSourceMapper;
import org.sonar.db.user.AuthorDto;
import org.sonar.db.user.AuthorMapper;
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.GroupRoleDto;
import org.sonar.db.user.RoleMapper;
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.UserRoleDto;
import org.sonar.db.user.UserTokenCount;
import org.sonar.db.user.UserTokenDto;
import org.sonar.db.user.UserTokenMapper;
import org.sonar.db.version.SchemaMigrationDto;
import org.sonar.db.version.SchemaMigrationMapper;
import org.sonar.db.version.v45.Migration45Mapper;
import org.sonar.db.version.v50.Migration50Mapper;
import org.sonar.db.version.v53.Migration53Mapper;

public class MyBatis {

  private final Database database;
  private SqlSessionFactory sessionFactory;
  private WorkQueue queue;

  public MyBatis(Database database, WorkQueue queue) {
    this.database = database;
    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) {
        Loggers.get(MyBatis.class).warn("Fail to close db session", e);
        // do not re-throw the exception
      }
    }
  }

  public MyBatis start() {
    LogFactory.useSlf4jLogging();

    MyBatisConfBuilder confBuilder = new MyBatisConfBuilder(database);

    confBuilder.loadAlias("ActiveDashboard", ActiveDashboardDto.class);
    confBuilder.loadAlias("Author", AuthorDto.class);
    confBuilder.loadAlias("Component", ComponentDto.class);
    confBuilder.loadAlias("ComponentWithSnapshot", ComponentDtoWithSnapshotId.class);
    confBuilder.loadAlias("ComponentLink", ComponentLinkDto.class);
    confBuilder.loadAlias("Dashboard", DashboardDto.class);
    confBuilder.loadAlias("DuplicationUnit", DuplicationUnitDto.class);
    confBuilder.loadAlias("Group", GroupDto.class);
    confBuilder.loadAlias("GroupRole", GroupRoleDto.class);
    confBuilder.loadAlias("GroupMembership", GroupMembershipDto.class);
    confBuilder.loadAlias("LoadedTemplate", LoadedTemplateDto.class);
    confBuilder.loadAlias("MeasureFilter", MeasureFilterDto.class);
    confBuilder.loadAlias("MeasureFilterFavourite", MeasureFilterFavouriteDto.class);
    confBuilder.loadAlias("NotificationQueue", NotificationQueueDto.class);
    confBuilder.loadAlias("Property", PropertyDto.class);
    confBuilder.loadAlias("PurgeableSnapshot", PurgeableSnapshotDto.class);
    confBuilder.loadAlias("QualityGate", QualityGateDto.class);
    confBuilder.loadAlias("QualityGateCondition", QualityGateConditionDto.class);
    confBuilder.loadAlias("ProjectQgateAssociation", ProjectQgateAssociationDto.class);
    confBuilder.loadAlias("Resource", ResourceDto.class);
    confBuilder.loadAlias("ResourceIndex", ResourceIndexDto.class);
    confBuilder.loadAlias("Rule", RuleDto.class);
    confBuilder.loadAlias("RuleParam", RuleParamDto.class);
    confBuilder.loadAlias("Snapshot", SnapshotDto.class);
    confBuilder.loadAlias("SchemaMigration", SchemaMigrationDto.class);
    confBuilder.loadAlias("User", UserDto.class);
    confBuilder.loadAlias("UserRole", UserRoleDto.class);
    confBuilder.loadAlias("UserGroup", UserGroupDto.class);
    confBuilder.loadAlias("Widget", WidgetDto.class);
    confBuilder.loadAlias("WidgetProperty", WidgetPropertyDto.class);
    confBuilder.loadAlias("Measure", MeasureDto.class);
    confBuilder.loadAlias("Issue", IssueDto.class);
    confBuilder.loadAlias("IssueChange", IssueChangeDto.class);
    confBuilder.loadAlias("IssueFilter", IssueFilterDto.class);
    confBuilder.loadAlias("IssueFilterFavourite", IssueFilterFavouriteDto.class);
    confBuilder.loadAlias("ActionPlanIssue", ActionPlanDto.class);
    confBuilder.loadAlias("ActionPlanStats", ActionPlanStatsDto.class);
    confBuilder.loadAlias("PermissionTemplate", PermissionTemplateDto.class);
    confBuilder.loadAlias("PermissionTemplateUser", PermissionTemplateUserDto.class);
    confBuilder.loadAlias("PermissionTemplateGroup", PermissionTemplateGroupDto.class);
    confBuilder.loadAlias("Characteristic", CharacteristicDto.class);
    confBuilder.loadAlias("UserWithPermission", UserWithPermissionDto.class);
    confBuilder.loadAlias("GroupWithPermission", GroupWithPermissionDto.class);
    confBuilder.loadAlias("QualityProfile", QualityProfileDto.class);
    confBuilder.loadAlias("ActiveRule", ActiveRuleDto.class);
    confBuilder.loadAlias("ActiveRuleParam", ActiveRuleParamDto.class);
    confBuilder.loadAlias("RequirementMigration", RequirementMigrationDto.class);
    confBuilder.loadAlias("Activity", ActivityDto.class);
    confBuilder.loadAlias("IdUuidPair", IdUuidPair.class);
    confBuilder.loadAlias("FilePathWithHash", FilePathWithHashDto.class);
    confBuilder.loadAlias("UuidWithProjectUuid", UuidWithProjectUuidDto.class);
    confBuilder.loadAlias("Event", EventDto.class);
    confBuilder.loadAlias("CustomMeasure", CustomMeasureDto.class);
    confBuilder.loadAlias("ViewsSnapshot", ViewsSnapshotDto.class);
    confBuilder.loadAlias("UserToken", UserTokenDto.class);
    confBuilder.loadAlias("UserTokenCount", UserTokenCount.class);

    // AuthorizationMapper has to be loaded before IssueMapper because this last one used it
    confBuilder.loadMapper("org.sonar.db.user.AuthorizationMapper");
    // ResourceMapper has to be loaded before IssueMapper because this last one used it
    confBuilder.loadMapper(ResourceMapper.class);

    confBuilder.loadMapper("org.sonar.db.permission.PermissionMapper");
    Class[] mappers = {ActivityMapper.class, ActiveDashboardMapper.class, AuthorMapper.class, DashboardMapper.class,
      DuplicationMapper.class,
      IssueMapper.class, IssueChangeMapper.class, IssueFilterMapper.class, IssueFilterFavouriteMapper.class,
      IsAliveMapper.class,
      LoadedTemplateMapper.class, MeasureFilterMapper.class, MeasureFilterFavouriteMapper.class, PermissionTemplateMapper.class, PropertiesMapper.class, PurgeMapper.class,
      ResourceKeyUpdaterMapper.class, ResourceIndexMapper.class, RoleMapper.class, RuleMapper.class,
      SchemaMigrationMapper.class, WidgetMapper.class, WidgetPropertyMapper.class,
      UserMapper.class, GroupMapper.class, UserGroupMapper.class, UserTokenMapper.class,
      FileSourceMapper.class, ActionPlanMapper.class, ActionPlanStatsMapper.class,
      NotificationQueueMapper.class, CharacteristicMapper.class,
      GroupMembershipMapper.class, QualityProfileMapper.class, ActiveRuleMapper.class,
      MeasureMapper.class, MetricMapper.class, CustomMeasureMapper.class, QualityGateMapper.class, QualityGateConditionMapper.class, ComponentMapper.class, SnapshotMapper.class,
      ProjectQgateAssociationMapper.class, EventMapper.class,
      CeQueueMapper.class, CeActivityMapper.class, ComponentLinkMapper.class,
      Migration45Mapper.class, Migration50Mapper.class, Migration53Mapper.class
    };
    confBuilder.loadMappers(mappers);

    sessionFactory = new SqlSessionFactoryBuilder().build(confBuilder.build());
    return this;
  }

  public SqlSessionFactory getSessionFactory() {
    return sessionFactory;
  }

  /**
   * @deprecated since 4.4. Replaced by openSession(false).
   */
  @Deprecated
  public SqlSession openSession() {
    return openSession(false);
  }

  /**
   * @since 4.4
   */
  public DbSession openSession(boolean batch) {
    if (batch) {
      SqlSession session = sessionFactory.openSession(ExecutorType.BATCH);
      return new BatchSession(queue, session);
    }
    SqlSession session = sessionFactory.openSession(ExecutorType.REUSE);
    return new DbSession(queue, 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);
  }

  /**
   * 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 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);
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy