content: package store.service;
  
  import com.sleepycat.je.DatabaseException;
  import com.sleepycat.persist.EntityCursor;
  import config.profile.SqlColProfile;
  import core.manager.ConfigurationManager;
  import core.parameter.ParameterBuilder;
  import lombok.Getter;
  import lombok.Setter;
  import lombok.extern.slf4j.Slf4j;
  import store.BerkleyDB;
  import store.ConvertManager;
  import store.dao.database.*;
  import store.entity.database.MainData;
  
  import javax.inject.Inject;
  import javax.inject.Singleton;
  import java.util.ArrayList;
  import java.util.Iterator;
  import java.util.List;
  import java.util.stream.Stream;
  
  @Slf4j
  @Singleton
  public class DatabaseDAO extends QueryService {
      private BerkleyDB berkleyDB;
      private ConfigurationManager configurationManager;
  
      @Getter @Setter private ConvertManager convertManager;
  
      @Getter public IMainDataDAO mainDataDAO;
      @Getter public IParameterStringDAO parameterStringDAO;
      @Getter public IParameterDoubleDAO parameterDoubleDAO;
      @Getter public IParamStringStringDAO paramStringStringDAO;
      @Getter public ISqlPlan iSqlPlan;
  
      @Inject
      public DatabaseDAO (BerkleyDB berkleyDB,
                          ConfigurationManager configurationManager) {
          this.berkleyDB = berkleyDB;
          this.configurationManager = configurationManager;
      }
  
      public void init () throws DatabaseException {
          this.mainDataDAO = new MainDataDAO(berkleyDB.getStore());
          this.parameterStringDAO = new ParameterStringDAO(berkleyDB.getStore());
          this.parameterDoubleDAO = new ParameterDoubleDAO(berkleyDB.getStore());
          this.paramStringStringDAO = new ParamStringStringDAO(berkleyDB.getStore());
          this.iSqlPlan = new SqlPlanDAO(berkleyDB.getStore());
      }
  
      public long getMax(ParameterBuilder parameterBuilder) {
          long out = 0;
          long start = (long) parameterBuilder.getBeginTime();
          long end = (long) parameterBuilder.getEndTime();
  
          EntityCursor<Long> cursor
                  = this.mainDataDAO.getPrimaryIndex().keys(start, true, end, true);
  
          if (cursor != null) {
              try {
                  if (cursor.last() != null) out = cursor.last();
              } finally {
                  cursor.close();
              }
          }
  
          return out;
      }
  
      public List<Object[][]> getMatrixDataForJTable(long begin, long end,
                                                          String waitClassColName, String waitClassValue,
                                                                  List<SqlColProfile> colMetadataList){
  
          List<Object[][]> out = new ArrayList<>();
  
          EntityCursor<MainData> cursor = getAshAggrEntityCursorRangeQuery(begin, end);
          Iterator<MainData> iterator = cursor.iterator();
  
          try {
              while (iterator.hasNext()) {
                  MainData sl = iterator.next();
  
                      Object[][] data = new Object[sl.getMainMatrix().length][colMetadataList.size()];
  
                      for (int row = 0; row < sl.getMainMatrix().length; row++) {
                          if (!waitClassValue.isEmpty()){
  
                              Stream<SqlColProfile> sqlColMetadataStream
                                      = colMetadataList.stream().filter(x -> x.getColName().equalsIgnoreCase(waitClassColName));
  
                              SqlColProfile sColMetaD = sqlColMetadataStream.findFirst().get();
  
                              String waitVal = (String) convertManager.getMatrixDataForJTable(sColMetaD.getColDbTypeName(),
                                      sColMetaD.getColId(), sl, row);
  
                              if (!waitVal.isEmpty() & !waitVal.equalsIgnoreCase(waitClassValue)){
                                  continue;
                              }
  
                              // CPU used - oracle/pg specific
                              if (waitVal.isEmpty()
                                      & !waitClassValue.equalsIgnoreCase(configurationManager.getIProfile().getWaitClass((byte) 0))){
                                  continue;
                              }
                          }
  
                          int rowF = row;
                              colMetadataList.forEach(e -> {
                                  data[rowF][e.getColId()-1] =
                                          convertManager.getMatrixDataForJTable(e.getColDbTypeName(), e.getColId(), sl, rowF);
                              });
                      }
                      out.add(data);
              }
          } finally {
              cursor.close();
          }
  
          return out;
      }
  
      public EntityCursor<MainData> getAshAggrEntityCursorRangeQuery(long start, long end){
          EntityCursor<MainData> entityCursor =
                  doRangeQuery(this.mainDataDAO.getPrimaryIndex(), start, true, end, true);
          return entityCursor;
      }
  
      public void deleteMainData(long start, long end){
          EntityCursor<MainData> entityCursor =
                  doRangeQuery(this.mainDataDAO.getPrimaryIndex(), start, true, end, true);
  
          try {
              for (MainData entity = entityCursor.first(); entity != null; entity = entityCursor.next()) {
                      entityCursor.delete();
              }
          } catch (Exception e){
              log.error(e.getMessage());
          } finally {
              entityCursor.close();
           }
  
      }
  
  }
  