19 package org.sleuthkit.autopsy.centralrepository.datamodel;
 
   21 import com.google.common.cache.Cache;
 
   22 import com.google.common.cache.CacheBuilder;
 
   23 import com.google.common.cache.CacheLoader;
 
   24 import java.net.UnknownHostException;
 
   25 import java.util.ArrayList;
 
   26 import java.util.List;
 
   27 import java.util.Collection;
 
   28 import java.util.LinkedHashSet;
 
   29 import java.util.stream.Collectors;
 
   30 import java.sql.Connection;
 
   31 import java.sql.PreparedStatement;
 
   32 import java.sql.ResultSet;
 
   33 import java.sql.SQLException;
 
   34 import java.sql.Statement;
 
   35 import java.sql.Types;
 
   36 import java.time.LocalDate;
 
   37 import java.util.Arrays;
 
   38 import java.util.HashMap;
 
   41 import java.util.concurrent.ExecutionException;
 
   42 import java.util.concurrent.TimeUnit;
 
   43 import java.util.logging.Level;
 
   44 import org.openide.util.NbBundle.Messages;
 
   50 import org.
sleuthkit.datamodel.CaseDbSchemaVersionNumber;
 
   58 abstract class AbstractSqlEamDb 
implements EamDb {
 
   61     static final String SCHEMA_MAJOR_VERSION_KEY = 
"SCHEMA_VERSION";
 
   62     static final String SCHEMA_MINOR_VERSION_KEY = 
"SCHEMA_MINOR_VERSION";
 
   63     static final String CREATION_SCHEMA_MAJOR_VERSION_KEY = 
"CREATION_SCHEMA_MAJOR_VERSION";
 
   64     static final String CREATION_SCHEMA_MINOR_VERSION_KEY = 
"CREATION_SCHEMA_MINOR_VERSION";
 
   65     static final CaseDbSchemaVersionNumber SOFTWARE_CR_DB_SCHEMA_VERSION = 
new CaseDbSchemaVersionNumber(1, 3);
 
   69     private int bulkArtifactsCount;
 
   70     protected int bulkArtifactsThreshold;
 
   71     private final Map<String, Collection<CorrelationAttributeInstance>> bulkArtifacts;
 
   72     private static final int CASE_CACHE_TIMEOUT = 5;
 
   73     private static final int DATA_SOURCE_CACHE_TIMEOUT = 5;
 
   75     private static final Cache<String, CorrelationCase> caseCacheByUUID = CacheBuilder.newBuilder()
 
   76             .expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES).
 
   78     private static final Cache<Integer, CorrelationCase> caseCacheById = CacheBuilder.newBuilder()
 
   79             .expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES).
 
   81     private static final Cache<String, CorrelationDataSource> dataSourceCacheByDsObjectId = CacheBuilder.newBuilder()
 
   82             .expireAfterWrite(DATA_SOURCE_CACHE_TIMEOUT, TimeUnit.MINUTES).
 
   84     private static final Cache<String, CorrelationDataSource> dataSourceCacheById = CacheBuilder.newBuilder()
 
   85             .expireAfterWrite(DATA_SOURCE_CACHE_TIMEOUT, TimeUnit.MINUTES).
 
   88     static final int MAX_VALUE_LENGTH = 256;
 
   92     static final int DEFAULT_BULK_THRESHHOLD = 1000;
 
  100         bulkArtifactsCount = 0;
 
  101         bulkArtifacts = 
new HashMap<>();
 
  104         defaultCorrelationTypes.forEach((type) -> {
 
  112     protected abstract Connection connect(
boolean foreignKeys) 
throws EamDbException;
 
  117     protected abstract Connection connect() 
throws EamDbException;
 
  128     public void newDbInfo(String name, String value) 
throws EamDbException {
 
  129         Connection conn = connect();
 
  131         PreparedStatement preparedStatement = null;
 
  132         String sql = 
"INSERT INTO db_info (name, value) VALUES (?, ?) " 
  133                 + getConflictClause();
 
  135             preparedStatement = conn.prepareStatement(sql);
 
  136             preparedStatement.setString(1, name);
 
  137             preparedStatement.setString(2, value);
 
  138             preparedStatement.executeUpdate();
 
  139         } 
catch (SQLException ex) {
 
  140             throw new EamDbException(
"Error adding new name/value pair to db_info.", ex);
 
  149     public void addDataSourceObjectId(
int rowId, 
long dataSourceObjectId) 
throws EamDbException {
 
  150         Connection conn = connect();
 
  151         PreparedStatement preparedStatement = null;
 
  152         String sql = 
"UPDATE data_sources SET datasource_obj_id=? WHERE id=?";
 
  154             preparedStatement = conn.prepareStatement(sql);
 
  155             preparedStatement.setLong(1, dataSourceObjectId);
 
  156             preparedStatement.setInt(2, rowId);
 
  157             preparedStatement.executeUpdate();
 
  158         } 
catch (SQLException ex) {
 
  159             throw new EamDbException(
"Error updating data source object id for data_sources row " + rowId, ex);
 
  176     public String getDbInfo(String name) 
throws EamDbException {
 
  177         Connection conn = connect();
 
  179         PreparedStatement preparedStatement = null;
 
  180         ResultSet resultSet = null;
 
  182         String sql = 
"SELECT value FROM db_info WHERE name=?";
 
  184             preparedStatement = conn.prepareStatement(sql);
 
  185             preparedStatement.setString(1, name);
 
  186             resultSet = preparedStatement.executeQuery();
 
  187             if (resultSet.next()) {
 
  188                 value = resultSet.getString(
"value");
 
  190         } 
catch (SQLException ex) {
 
  191             throw new EamDbException(
"Error getting value for name.", ex);
 
  204     protected final void clearCaches() {
 
  205         typeCache.invalidateAll();
 
  206         caseCacheByUUID.invalidateAll();
 
  207         caseCacheById.invalidateAll();
 
  208         dataSourceCacheByDsObjectId.invalidateAll();
 
  209         dataSourceCacheById.invalidateAll();
 
  221     public void updateDbInfo(String name, String value) 
throws EamDbException {
 
  222         Connection conn = connect();
 
  224         PreparedStatement preparedStatement = null;
 
  225         String sql = 
"UPDATE db_info SET value=? WHERE name=?";
 
  227             preparedStatement = conn.prepareStatement(sql);
 
  228             preparedStatement.setString(1, value);
 
  229             preparedStatement.setString(2, name);
 
  230             preparedStatement.executeUpdate();
 
  231         } 
catch (SQLException ex) {
 
  232             throw new EamDbException(
"Error updating value for name.", ex);
 
  252             throw new EamDbException(
"Case UUID is null");
 
  257         if (cRCase != null) {
 
  261         Connection conn = connect();
 
  262         PreparedStatement preparedStatement = null;
 
  264         String sql = 
"INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, " 
  265                 + 
"examiner_name, examiner_email, examiner_phone, notes) " 
  266                 + 
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) " 
  267                 + getConflictClause();
 
  268         ResultSet resultSet = null;
 
  270             preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
 
  272             preparedStatement.setString(1, eamCase.
getCaseUUID());
 
  273             if (null == eamCase.
getOrg()) {
 
  274                 preparedStatement.setNull(2, Types.INTEGER);
 
  281                 preparedStatement.setNull(5, Types.INTEGER);
 
  286                 preparedStatement.setNull(6, Types.INTEGER);
 
  291                 preparedStatement.setNull(7, Types.INTEGER);
 
  296                 preparedStatement.setNull(8, Types.INTEGER);
 
  300             if (
"".equals(eamCase.
getNotes())) {
 
  301                 preparedStatement.setNull(9, Types.INTEGER);
 
  303                 preparedStatement.setString(9, eamCase.
getNotes());
 
  306             preparedStatement.executeUpdate();
 
  308             resultSet = preparedStatement.getGeneratedKeys();
 
  309             if (!resultSet.next()) {
 
  310                 throw new EamDbException(String.format(
"Failed to INSERT case %s in central repo", eamCase.
getCaseUUID()));
 
  312             int caseID = resultSet.getInt(1); 
 
  316             caseCacheByUUID.put(eamCase.
getCaseUUID(), correlationCase);
 
  317             caseCacheById.put(caseID, correlationCase);
 
  318         } 
catch (SQLException ex) {
 
  319             throw new EamDbException(
"Error inserting new case.", ex); 
 
  337         if (autopsyCase == null) {
 
  338             throw new EamDbException(
"Case is null");
 
  352         return newCase(curCeCase);
 
  357         return getCaseByUUID(autopsyCase.
getName());
 
  366     public void updateCase(
CorrelationCase eamCase) 
throws EamDbException {
 
  367         if (eamCase == null) {
 
  368             throw new EamDbException(
"Correlation case is null");
 
  371         Connection conn = connect();
 
  373         PreparedStatement preparedStatement = null;
 
  374         String sql = 
"UPDATE cases " 
  375                 + 
"SET org_id=?, case_name=?, creation_date=?, case_number=?, examiner_name=?, examiner_email=?, examiner_phone=?, notes=? " 
  376                 + 
"WHERE case_uid=?";
 
  379             preparedStatement = conn.prepareStatement(sql);
 
  381             if (null == eamCase.
getOrg()) {
 
  382                 preparedStatement.setNull(1, Types.INTEGER);
 
  390                 preparedStatement.setNull(4, Types.INTEGER);
 
  395                 preparedStatement.setNull(5, Types.INTEGER);
 
  400                 preparedStatement.setNull(6, Types.INTEGER);
 
  405                 preparedStatement.setNull(7, Types.INTEGER);
 
  409             if (
"".equals(eamCase.
getNotes())) {
 
  410                 preparedStatement.setNull(8, Types.INTEGER);
 
  412                 preparedStatement.setString(8, eamCase.
getNotes());
 
  415             preparedStatement.setString(9, eamCase.
getCaseUUID());
 
  417             preparedStatement.executeUpdate();
 
  419             caseCacheById.put(eamCase.
getID(), eamCase);
 
  420             caseCacheByUUID.put(eamCase.
getCaseUUID(), eamCase);
 
  421         } 
catch (SQLException ex) {
 
  422             throw new EamDbException(
"Error updating case.", ex); 
 
  437     public CorrelationCase getCaseByUUID(String caseUUID) 
throws EamDbException {
 
  439             return caseCacheByUUID.get(caseUUID, () -> getCaseByUUIDFromCr(caseUUID));
 
  440         } 
catch (CacheLoader.InvalidCacheLoadException ignored) {
 
  443         } 
catch (ExecutionException ex) {
 
  444             throw new EamDbException(
"Error getting autopsy case from Central repo", ex);
 
  455     private CorrelationCase getCaseByUUIDFromCr(String caseUUID) 
throws EamDbException {
 
  456         Connection conn = connect();
 
  459         PreparedStatement preparedStatement = null;
 
  460         ResultSet resultSet = null;
 
  462         String sql = 
"SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, " 
  463                 + 
"examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone " 
  465                 + 
"LEFT JOIN organizations ON cases.org_id=organizations.id " 
  466                 + 
"WHERE case_uid=?";
 
  469             preparedStatement = conn.prepareStatement(sql);
 
  470             preparedStatement.setString(1, caseUUID);
 
  471             resultSet = preparedStatement.executeQuery();
 
  472             if (resultSet.next()) {
 
  473                 eamCaseResult = getEamCaseFromResultSet(resultSet);
 
  475             if (eamCaseResult != null) {
 
  477                 caseCacheById.put(eamCaseResult.
getID(), eamCaseResult);
 
  479         } 
catch (SQLException ex) {
 
  480             throw new EamDbException(
"Error getting case details.", ex); 
 
  487         return eamCaseResult;
 
  500             return caseCacheById.get(caseId, () -> getCaseByIdFromCr(caseId));
 
  501         } 
catch (CacheLoader.InvalidCacheLoadException ignored) {
 
  504         } 
catch (ExecutionException ex) {
 
  505             throw new EamDbException(
"Error getting autopsy case from Central repo", ex);
 
  516     private CorrelationCase getCaseByIdFromCr(
int caseId) 
throws EamDbException {
 
  517         Connection conn = connect();
 
  520         PreparedStatement preparedStatement = null;
 
  521         ResultSet resultSet = null;
 
  523         String sql = 
"SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, " 
  524                 + 
"examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone " 
  526                 + 
"LEFT JOIN organizations ON cases.org_id=organizations.id " 
  527                 + 
"WHERE cases.id=?";
 
  529             preparedStatement = conn.prepareStatement(sql);
 
  530             preparedStatement.setInt(1, caseId);
 
  531             resultSet = preparedStatement.executeQuery();
 
  532             if (resultSet.next()) {
 
  533                 eamCaseResult = getEamCaseFromResultSet(resultSet);
 
  535             if (eamCaseResult != null) {
 
  537                 caseCacheByUUID.put(eamCaseResult.
getCaseUUID(), eamCaseResult);
 
  539         } 
catch (SQLException ex) {
 
  540             throw new EamDbException(
"Error getting case details.", ex); 
 
  547         return eamCaseResult;
 
  556     public List<CorrelationCase> getCases() 
throws EamDbException {
 
  557         Connection conn = connect();
 
  559         List<CorrelationCase> cases = 
new ArrayList<>();
 
  561         PreparedStatement preparedStatement = null;
 
  562         ResultSet resultSet = null;
 
  564         String sql = 
"SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, " 
  565                 + 
"examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone " 
  567                 + 
"LEFT JOIN organizations ON cases.org_id=organizations.id";
 
  570             preparedStatement = conn.prepareStatement(sql);
 
  571             resultSet = preparedStatement.executeQuery();
 
  572             while (resultSet.next()) {
 
  573                 eamCaseResult = getEamCaseFromResultSet(resultSet);
 
  574                 cases.add(eamCaseResult);
 
  576         } 
catch (SQLException ex) {
 
  577             throw new EamDbException(
"Error getting all cases.", ex); 
 
  597     private static String getDataSourceByDSObjectIdCacheKey(
int caseId, Long dataSourceObjectId) {
 
  598         return "Case" + caseId + 
"DsObjectId" + dataSourceObjectId; 
 
  610     private static String getDataSourceByIdCacheKey(
int caseId, 
int dataSourceId) {
 
  611         return "Case" + caseId + 
"Id" + dataSourceId; 
 
  622             throw new EamDbException(
"Case ID is -1");
 
  625             throw new EamDbException(
"Device ID is null");
 
  627         if (eamDataSource.
getName() == null) {
 
  628             throw new EamDbException(
"Name is null");
 
  630         if (eamDataSource.
getID() != -1) {
 
  632             return eamDataSource;
 
  635         Connection conn = connect();
 
  637         PreparedStatement preparedStatement = null;
 
  639         String sql = 
"INSERT INTO data_sources(device_id, case_id, name, datasource_obj_id, md5, sha1, sha256) VALUES (?, ?, ?, ?, ?, ?, ?) " 
  640                 + getConflictClause();
 
  641         ResultSet resultSet = null;
 
  643             preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
 
  645             preparedStatement.setString(1, eamDataSource.
getDeviceID());
 
  646             preparedStatement.setInt(2, eamDataSource.
getCaseID());
 
  647             preparedStatement.setString(3, eamDataSource.
getName());
 
  649             preparedStatement.setString(5, eamDataSource.
getMd5());
 
  650             preparedStatement.setString(6, eamDataSource.
getSha1());
 
  651             preparedStatement.setString(7, eamDataSource.
getSha256());
 
  653             preparedStatement.executeUpdate();
 
  654             resultSet = preparedStatement.getGeneratedKeys();
 
  655             if (!resultSet.next()) {
 
  664                     return dataSourceCacheByDsObjectId.get(getDataSourceByDSObjectIdCacheKey(
 
  667                 } 
catch (CacheLoader.InvalidCacheLoadException | ExecutionException getException) {
 
  668                     throw new EamDbException(String.format(
"Unable to to INSERT or get data source %s in central repo:", eamDataSource.
getName()), getException);
 
  672                 int dataSourceId = resultSet.getInt(1); 
 
  675                 dataSourceCacheById.put(getDataSourceByIdCacheKey(dataSource.
getCaseID(), dataSource.
getID()), dataSource);
 
  679         } 
catch (SQLException insertException) {
 
  689                 return dataSourceCacheByDsObjectId.get(getDataSourceByDSObjectIdCacheKey(
 
  692             } 
catch (CacheLoader.InvalidCacheLoadException | ExecutionException getException) {
 
  693                 throw new EamDbException(String.format(
"Unable to to INSERT or get data source %s in central repo, insert failed due to Exception: %s", eamDataSource.
getName(), insertException.getMessage()), getException);
 
  716         if (correlationCase == null) {
 
  717             throw new EamDbException(
"Correlation case is null");
 
  720             return dataSourceCacheByDsObjectId.get(getDataSourceByDSObjectIdCacheKey(correlationCase.
getID(), dataSourceObjectId), () -> getDataSourceFromCr(correlationCase.
getID(), dataSourceObjectId));
 
  721         } 
catch (CacheLoader.InvalidCacheLoadException ignored) {
 
  724         } 
catch (ExecutionException ex) {
 
  725             throw new EamDbException(
"Error getting data source from central repository", ex);
 
  741     private CorrelationDataSource getDataSourceFromCr(
int correlationCaseId, Long dataSourceObjectId) 
throws EamDbException {
 
  742         Connection conn = connect();
 
  745         PreparedStatement preparedStatement = null;
 
  746         ResultSet resultSet = null;
 
  748         String sql = 
"SELECT * FROM data_sources WHERE datasource_obj_id=? AND case_id=?"; 
 
  751             preparedStatement = conn.prepareStatement(sql);
 
  752             preparedStatement.setLong(1, dataSourceObjectId);
 
  753             preparedStatement.setInt(2, correlationCaseId);
 
  754             resultSet = preparedStatement.executeQuery();
 
  755             if (resultSet.next()) {
 
  756                 eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
 
  758             if (eamDataSourceResult != null) {
 
  759                 dataSourceCacheById.put(getDataSourceByIdCacheKey(correlationCaseId, eamDataSourceResult.
getID()), eamDataSourceResult);
 
  761         } 
catch (SQLException ex) {
 
  762             throw new EamDbException(
"Error getting data source.", ex); 
 
  769         return eamDataSourceResult;
 
  783         if (correlationCase == null) {
 
  784             throw new EamDbException(
"Correlation case is null");
 
  787             return dataSourceCacheById.get(getDataSourceByIdCacheKey(correlationCase.
getID(), dataSourceId), () -> getDataSourceByIdFromCr(correlationCase, dataSourceId));
 
  788         } 
catch (CacheLoader.InvalidCacheLoadException ignored) {
 
  791         } 
catch (ExecutionException ex) {
 
  792             throw new EamDbException(
"Error getting data source from central repository", ex);
 
  806         Connection conn = connect();
 
  809         PreparedStatement preparedStatement = null;
 
  810         ResultSet resultSet = null;
 
  812         String sql = 
"SELECT * FROM data_sources WHERE id=? AND case_id=?"; 
 
  815             preparedStatement = conn.prepareStatement(sql);
 
  816             preparedStatement.setInt(1, dataSourceId);
 
  817             preparedStatement.setInt(2, correlationCase.
getID());
 
  818             resultSet = preparedStatement.executeQuery();
 
  819             if (resultSet.next()) {
 
  820                 eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
 
  822             if (eamDataSourceResult != null) {
 
  823                 dataSourceCacheByDsObjectId.put(getDataSourceByDSObjectIdCacheKey(correlationCase.
getID(), eamDataSourceResult.
getDataSourceObjectID()), eamDataSourceResult);
 
  825         } 
catch (SQLException ex) {
 
  826             throw new EamDbException(
"Error getting data source.", ex); 
 
  833         return eamDataSourceResult;
 
  842     public List<CorrelationDataSource> getDataSources() 
throws EamDbException {
 
  843         Connection conn = connect();
 
  845         List<CorrelationDataSource> dataSources = 
new ArrayList<>();
 
  847         PreparedStatement preparedStatement = null;
 
  848         ResultSet resultSet = null;
 
  850         String sql = 
"SELECT * FROM data_sources";
 
  853             preparedStatement = conn.prepareStatement(sql);
 
  854             resultSet = preparedStatement.executeQuery();
 
  855             while (resultSet.next()) {
 
  856                 eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
 
  857                 dataSources.add(eamDataSourceResult);
 
  859         } 
catch (SQLException ex) {
 
  860             throw new EamDbException(
"Error getting all data sources.", ex); 
 
  877         updateDataSourceStringValue(eamDataSource, 
"md5", eamDataSource.
getMd5());
 
  887         updateDataSourceStringValue(eamDataSource, 
"sha1", eamDataSource.
getSha1());
 
  898         updateDataSourceStringValue(eamDataSource, 
"sha256", eamDataSource.
getSha256());
 
  908     private void updateDataSourceStringValue(
CorrelationDataSource eamDataSource, String column, String value) 
throws EamDbException {
 
  909         if (eamDataSource == null) {
 
  910             throw new EamDbException(
"Correlation data source is null");
 
  913         Connection conn = connect();
 
  915         PreparedStatement preparedStatement = null;
 
  916         String sql = 
"UPDATE data_sources " 
  917                 + 
"SET " + column + 
"=? " 
  921             preparedStatement = conn.prepareStatement(sql);
 
  923             preparedStatement.setString(1, value);
 
  924             preparedStatement.setInt(2, eamDataSource.
getID());
 
  926             preparedStatement.executeUpdate();
 
  928             dataSourceCacheByDsObjectId.put(getDataSourceByDSObjectIdCacheKey(eamDataSource.
getCaseID(), eamDataSource.
getDataSourceObjectID()), eamDataSource);
 
  929             dataSourceCacheById.put(getDataSourceByIdCacheKey(eamDataSource.
getCaseID(), eamDataSource.
getID()), eamDataSource);
 
  930         } 
catch (SQLException ex) {
 
  931             throw new EamDbException(String.format(
"Error updating data source (obj_id=%d).", eamDataSource.
getDataSourceObjectID()), ex); 
 
  947     public void updateDataSourceName(
CorrelationDataSource eamDataSource, String newName) 
throws EamDbException {
 
  949         Connection conn = connect();
 
  951         PreparedStatement preparedStatement = null;
 
  953         String sql = 
"UPDATE data_sources SET name = ? WHERE id = ?";
 
  956             preparedStatement = conn.prepareStatement(sql);
 
  957             preparedStatement.setString(1, newName);
 
  958             preparedStatement.setInt(2, eamDataSource.
getID());
 
  959             preparedStatement.executeUpdate();
 
  963                     eamDataSource.
getID(),
 
  971             dataSourceCacheByDsObjectId.put(getDataSourceByDSObjectIdCacheKey(updatedDataSource.
getCaseID(), updatedDataSource.
getDataSourceObjectID()), updatedDataSource);
 
  972             dataSourceCacheById.put(getDataSourceByIdCacheKey(updatedDataSource.
getCaseID(), updatedDataSource.
getID()), updatedDataSource);
 
  973         } 
catch (SQLException ex) {
 
  974             throw new EamDbException(
"Error updating name of data source with ID " + eamDataSource.
getDataSourceObjectID()
 
  975                     + 
" to " + newName, ex); 
 
  990         checkAddArtifactInstanceNulls(eamArtifact);
 
  992         Connection conn = connect();
 
  994         PreparedStatement preparedStatement = null;
 
 1001                 + 
"(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) " 
 1002                 + 
"VALUES (?, ?, ?, ?, ?, ?, ?) " 
 1003                 + getConflictClause();
 
 1006             preparedStatement = conn.prepareStatement(sql);
 
 1012                 preparedStatement.setString(4, eamArtifact.
getFilePath().toLowerCase());
 
 1013                 preparedStatement.setByte(5, eamArtifact.
getKnownStatus().getFileKnownValue());
 
 1016                     preparedStatement.setNull(6, Types.INTEGER);
 
 1018                     preparedStatement.setString(6, eamArtifact.
getComment());
 
 1022                 preparedStatement.executeUpdate();
 
 1025         } 
catch (SQLException ex) {
 
 1026             throw new EamDbException(
"Error inserting new artifact into artifacts table.", ex); 
 
 1034         if (eamArtifact == null) {
 
 1035             throw new EamDbException(
"CorrelationAttribute is null");
 
 1038             throw new EamDbException(
"Correlation type is null");
 
 1041             throw new EamDbException(
"Correlation value is null");
 
 1044             throw new EamDbException(
"Artifact value too long for central repository." 
 1045                     + 
"\nCorrelationArtifact ID: " + eamArtifact.
getID()
 
 1051             throw new EamDbException(
"CorrelationAttributeInstance case is null");
 
 1054             throw new EamDbException(
"CorrelationAttributeInstance data source is null");
 
 1057             throw new EamDbException(
"CorrelationAttributeInstance known status is null");
 
 1063         if (value == null) {
 
 1066         return getArtifactInstancesByTypeValues(aType, Arrays.asList(value));
 
 1071         if (aType == null) {
 
 1074         if (values == null || values.isEmpty()) {
 
 1077         return getArtifactInstances(prepareGetInstancesSql(aType, values), aType);
 
 1082         if (aType == null) {
 
 1085         if (values == null || values.isEmpty()) {
 
 1088         if (caseIds == null || caseIds.isEmpty()) {
 
 1096         StringBuilder inValuesBuilder = 
new StringBuilder(prepareGetInstancesSql(aType, values));
 
 1097         inValuesBuilder.append(sql);
 
 1098         inValuesBuilder.append(caseIds.stream().map(String::valueOf).collect(Collectors.joining(
"', '")));
 
 1099         inValuesBuilder.append(
"')");
 
 1100         return getArtifactInstances(inValuesBuilder.toString(), aType);
 
 1120                 + 
".id as instance_id," 
 1125                 + 
" cases.*, organizations.org_name, organizations.poc_name, organizations.poc_email, organizations.poc_phone, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.datasource_obj_id, data_sources.md5, data_sources.sha1, data_sources.sha256 FROM " 
 1127                 + 
" LEFT JOIN cases ON " 
 1129                 + 
".case_id=cases.id" 
 1130                 + 
" LEFT JOIN organizations ON cases.org_id=organizations.id" 
 1131                 + 
" LEFT JOIN data_sources ON " 
 1133                 + 
".data_source_id=data_sources.id" 
 1134                 + 
" WHERE value IN (";
 
 1135         StringBuilder inValuesBuilder = 
new StringBuilder(sql);
 
 1136         for (String value : values) {
 
 1137             if (value != null) {
 
 1138                 inValuesBuilder.append(
"'");
 
 1140                 inValuesBuilder.append(
"',");
 
 1143         inValuesBuilder.deleteCharAt(inValuesBuilder.length() - 1); 
 
 1144         inValuesBuilder.append(
")");
 
 1145         return inValuesBuilder.toString();
 
 1163         Connection conn = connect();
 
 1164         List<CorrelationAttributeInstance> artifactInstances = 
new ArrayList<>();
 
 1166         PreparedStatement preparedStatement = null;
 
 1167         ResultSet resultSet = null;
 
 1169             preparedStatement = conn.prepareStatement(sql);
 
 1170             resultSet = preparedStatement.executeQuery();
 
 1171             while (resultSet.next()) {
 
 1172                 artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
 
 1173                 artifactInstances.add(artifactInstance);
 
 1175         } 
catch (SQLException ex) {
 
 1176             throw new EamDbException(
"Error getting artifact instances by artifactType and artifactValue.", ex); 
 
 1182         return artifactInstances;
 
 1196     public Long getCountArtifactInstancesByTypeValue(
CorrelationAttributeInstance.
Type aType, String value) 
throws EamDbException, CorrelationAttributeNormalizationException {
 
 1199         Connection conn = connect();
 
 1201         Long instanceCount = 0L;
 
 1202         PreparedStatement preparedStatement = null;
 
 1203         ResultSet resultSet = null;
 
 1207                 = 
"SELECT count(*) FROM " 
 1212             preparedStatement = conn.prepareStatement(sql);
 
 1213             preparedStatement.setString(1, normalizedValue);
 
 1214             resultSet = preparedStatement.executeQuery();
 
 1216             instanceCount = resultSet.getLong(1);
 
 1217         } 
catch (SQLException ex) {
 
 1218             throw new EamDbException(
"Error getting count of artifact instances by artifactType and artifactValue.", ex); 
 
 1225         return instanceCount;
 
 1229     public int getFrequencyPercentage(
CorrelationAttributeInstance corAttr) 
throws EamDbException, CorrelationAttributeNormalizationException {
 
 1230         if (corAttr == null) {
 
 1231             throw new EamDbException(
"CorrelationAttribute is null");
 
 1234         Double uniqueCaseDataSourceTuples = getCountUniqueDataSources().doubleValue();
 
 1235         Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100;
 
 1236         return commonalityPercentage.intValue();
 
 1250     public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(
CorrelationAttributeInstance.
Type aType, String value) 
throws EamDbException, CorrelationAttributeNormalizationException {
 
 1253         Connection conn = connect();
 
 1255         Long instanceCount = 0L;
 
 1256         PreparedStatement preparedStatement = null;
 
 1257         ResultSet resultSet = null;
 
 1261                 = 
"SELECT count(*) FROM (SELECT DISTINCT case_id, data_source_id FROM " 
 1263                 + 
" WHERE value=?) AS " 
 1265                 + 
"_distinct_case_data_source_tuple";
 
 1268             preparedStatement = conn.prepareStatement(sql);
 
 1269             preparedStatement.setString(1, normalizedValue);
 
 1270             resultSet = preparedStatement.executeQuery();
 
 1272             instanceCount = resultSet.getLong(1);
 
 1273         } 
catch (SQLException ex) {
 
 1274             throw new EamDbException(
"Error counting unique caseDisplayName/dataSource tuples having artifactType and artifactValue.", ex); 
 
 1281         return instanceCount;
 
 1285     public Long getCountUniqueDataSources() 
throws EamDbException {
 
 1286         Connection conn = connect();
 
 1288         Long instanceCount = 0L;
 
 1289         PreparedStatement preparedStatement = null;
 
 1290         ResultSet resultSet = null;
 
 1292         String stmt = 
"SELECT count(*) FROM data_sources";
 
 1295             preparedStatement = conn.prepareStatement(stmt);
 
 1296             resultSet = preparedStatement.executeQuery();
 
 1298             instanceCount = resultSet.getLong(1);
 
 1299         } 
catch (SQLException ex) {
 
 1300             throw new EamDbException(
"Error counting data sources.", ex); 
 
 1307         return instanceCount;
 
 1322     public Long getCountArtifactInstancesByCaseDataSource(
CorrelationDataSource correlationDataSource) 
throws EamDbException {
 
 1323         Connection conn = connect();
 
 1325         Long instanceCount = 0L;
 
 1327         PreparedStatement preparedStatement = null;
 
 1328         ResultSet resultSet = null;
 
 1331         String sql = 
"SELECT 0 ";
 
 1336                     += 
"+ (SELECT count(*) FROM " 
 1338                     + 
" WHERE data_source_id=" + correlationDataSource.
getID() + 
")";
 
 1341             preparedStatement = conn.prepareStatement(sql);
 
 1343             resultSet = preparedStatement.executeQuery();
 
 1345             instanceCount = resultSet.getLong(1);
 
 1346         } 
catch (SQLException ex) {
 
 1347             throw new EamDbException(
"Error counting artifact instances by caseName/dataSource.", ex); 
 
 1354         return instanceCount;
 
 1368             throw new EamDbException(
"Correlation type is null");
 
 1371         synchronized (bulkArtifacts) {
 
 1373             bulkArtifactsCount++;
 
 1375             if (bulkArtifactsCount >= bulkArtifactsThreshold) {
 
 1376                 commitAttributeInstancesBulk();
 
 1386     protected abstract String getConflictClause();
 
 1393     public void commitAttributeInstancesBulk() 
throws EamDbException {
 
 1396         Connection conn = connect();
 
 1397         PreparedStatement bulkPs = null;
 
 1400             synchronized (bulkArtifacts) {
 
 1401                 if (bulkArtifactsCount == 0) {
 
 1405                 for (String tableName : bulkArtifacts.keySet()) {
 
 1410                             + 
" (case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) " 
 1411                             + 
"VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), " 
 1412                             + 
"(SELECT id FROM data_sources WHERE datasource_obj_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?, ?) " 
 1413                             + getConflictClause();
 
 1415                     bulkPs = conn.prepareStatement(sql);
 
 1417                     Collection<CorrelationAttributeInstance> eamArtifacts = bulkArtifacts.get(tableName);
 
 1423                                 throw new EamDbException(
"CorrelationAttributeInstance case is null for: " 
 1424                                         + 
"\n\tCorrelationArtifact ID: " + eamArtifact.
getID()
 
 1429                                 throw new EamDbException(
"CorrelationAttributeInstance data source is null for: " 
 1430                                         + 
"\n\tCorrelationArtifact ID: " + eamArtifact.
getID()
 
 1435                                 throw new EamDbException(
"CorrelationAttributeInstance known status is null for: " 
 1436                                         + 
"\n\tCorrelationArtifact ID: " + eamArtifact.
getID()
 
 1439                                         + 
"\n\tEam Instance: " 
 1450                                 bulkPs.setByte(6, eamArtifact.
getKnownStatus().getFileKnownValue());
 
 1452                                     bulkPs.setNull(7, Types.INTEGER);
 
 1454                                     bulkPs.setString(7, eamArtifact.
getComment());
 
 1459                                 logger.log(Level.WARNING, (
"Artifact value too long for central repository." 
 1460                                         + 
"\n\tCorrelationArtifact ID: " + eamArtifact.
getID()
 
 1463                                         + 
"\n\tEam Instance: " 
 1466                                         + 
"\n\t\tFilePath: " + eamArtifact.
getFilePath());
 
 1472                     bulkPs.executeBatch();
 
 1473                     bulkArtifacts.get(tableName).clear();
 
 1480                 bulkArtifactsCount = 0;
 
 1482         } 
catch (SQLException ex) {
 
 1483             throw new EamDbException(
"Error inserting bulk artifacts.", ex); 
 
 1494     public void bulkInsertCases(List<CorrelationCase> cases) 
throws EamDbException {
 
 1495         if (cases == null) {
 
 1496             throw new EamDbException(
"cases argument is null");
 
 1499         if (cases.isEmpty()) {
 
 1503         Connection conn = connect();
 
 1506         PreparedStatement bulkPs = null;
 
 1508             String sql = 
"INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, " 
 1509                     + 
"examiner_name, examiner_email, examiner_phone, notes) " 
 1510                     + 
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) " 
 1511                     + getConflictClause();
 
 1512             bulkPs = conn.prepareStatement(sql);
 
 1516                 if (null == eamCase.
getOrg()) {
 
 1517                     bulkPs.setNull(2, Types.INTEGER);
 
 1525                     bulkPs.setNull(5, Types.INTEGER);
 
 1530                     bulkPs.setNull(6, Types.INTEGER);
 
 1535                     bulkPs.setNull(7, Types.INTEGER);
 
 1540                     bulkPs.setNull(8, Types.INTEGER);
 
 1544                 if (
"".equals(eamCase.
getNotes())) {
 
 1545                     bulkPs.setNull(9, Types.INTEGER);
 
 1547                     bulkPs.setString(9, eamCase.
getNotes());
 
 1555                 if (counter >= bulkArtifactsThreshold) {
 
 1556                     bulkPs.executeBatch();
 
 1561             bulkPs.executeBatch();
 
 1562         } 
catch (SQLException ex) {
 
 1563             throw new EamDbException(
"Error inserting bulk cases.", ex); 
 
 1582         if (eamArtifact == null) {
 
 1583             throw new EamDbException(
"CorrelationAttributeInstance is null");
 
 1586             throw new EamDbException(
"Correlation case is null");
 
 1589             throw new EamDbException(
"Correlation data source is null");
 
 1591         Connection conn = connect();
 
 1592         PreparedStatement preparedQuery = null;
 
 1598                 + 
"WHERE case_id=? " 
 1599                 + 
"AND data_source_id=? " 
 1601                 + 
"AND file_path=?";
 
 1604             preparedQuery = conn.prepareStatement(sqlUpdate);
 
 1605             preparedQuery.setString(1, eamArtifact.
getComment());
 
 1609             preparedQuery.setString(5, eamArtifact.
getFilePath().toLowerCase());
 
 1610             preparedQuery.executeUpdate();
 
 1611         } 
catch (SQLException ex) {
 
 1612             throw new EamDbException(
"Error getting/setting artifact instance comment=" + eamArtifact.
getComment(), ex); 
 
 1635             CorrelationDataSource correlationDataSource, 
long objectID) 
throws EamDbException, CorrelationAttributeNormalizationException {
 
 1637         if (correlationCase == null) {
 
 1638             throw new EamDbException(
"Correlation case is null");
 
 1641         Connection conn = connect();
 
 1643         PreparedStatement preparedStatement = null;
 
 1644         ResultSet resultSet = null;
 
 1651                     = 
"SELECT id, value, file_path, known_status, comment FROM " 
 1653                     + 
" WHERE case_id=?" 
 1654                     + 
" AND file_obj_id=?";
 
 1656             preparedStatement = conn.prepareStatement(sql);
 
 1657             preparedStatement.setInt(1, correlationCase.
getID());
 
 1658             preparedStatement.setInt(2, (
int) objectID);
 
 1659             resultSet = preparedStatement.executeQuery();
 
 1660             if (resultSet.next()) {
 
 1661                 int instanceId = resultSet.getInt(1);
 
 1662                 String value = resultSet.getString(2);
 
 1663                 String filePath = resultSet.getString(3);
 
 1664                 int knownStatus = resultSet.getInt(4);
 
 1665                 String comment = resultSet.getString(5);
 
 1668                         instanceId, correlationCase, correlationDataSource, filePath, comment, TskData.FileKnown.valueOf((byte) knownStatus), objectID);
 
 1670         } 
catch (SQLException ex) {
 
 1671             throw new EamDbException(
"Error getting notable artifact instances.", ex); 
 
 1678         return correlationAttributeInstance;
 
 1697             CorrelationDataSource correlationDataSource, String value, String filePath) 
throws EamDbException, CorrelationAttributeNormalizationException {
 
 1699         if (correlationCase == null) {
 
 1700             throw new EamDbException(
"Correlation case is null");
 
 1702         if (correlationDataSource == null) {
 
 1703             throw new EamDbException(
"Correlation data source is null");
 
 1705         if (filePath == null) {
 
 1706             throw new EamDbException(
"Correlation file path is null");
 
 1709         Connection conn = connect();
 
 1711         PreparedStatement preparedStatement = null;
 
 1712         ResultSet resultSet = null;
 
 1720                     = 
"SELECT id, known_status, comment FROM " 
 1722                     + 
" WHERE case_id=?" 
 1723                     + 
" AND data_source_id=?" 
 1725                     + 
" AND file_path=?";
 
 1727             preparedStatement = conn.prepareStatement(sql);
 
 1728             preparedStatement.setInt(1, correlationCase.
getID());
 
 1729             preparedStatement.setInt(2, correlationDataSource.
getID());
 
 1730             preparedStatement.setString(3, normalizedValue);
 
 1731             preparedStatement.setString(4, filePath.toLowerCase());
 
 1732             resultSet = preparedStatement.executeQuery();
 
 1733             if (resultSet.next()) {
 
 1734                 int instanceId = resultSet.getInt(1);
 
 1735                 int knownStatus = resultSet.getInt(2);
 
 1736                 String comment = resultSet.getString(3);
 
 1739                         instanceId, correlationCase, correlationDataSource, filePath, comment, TskData.FileKnown.valueOf((byte) knownStatus), null);
 
 1741         } 
catch (SQLException ex) {
 
 1742             throw new EamDbException(
"Error getting notable artifact instances.", ex); 
 
 1749         return correlationAttributeInstance;
 
 1763     public void setAttributeInstanceKnownStatus(
CorrelationAttributeInstance eamArtifact, TskData.FileKnown knownStatus) 
throws EamDbException {
 
 1764         if (eamArtifact == null) {
 
 1765             throw new EamDbException(
"CorrelationAttribute is null");
 
 1767         if (knownStatus == null) {
 
 1768             throw new EamDbException(
"Known status is null");
 
 1772             throw new EamDbException(
"Correlation case is null");
 
 1775             throw new EamDbException(
"Correlation data source is null");
 
 1778         Connection conn = connect();
 
 1780         PreparedStatement preparedUpdate = null;
 
 1781         PreparedStatement preparedQuery = null;
 
 1782         ResultSet resultSet = null;
 
 1789                 + 
" WHERE case_id=? " 
 1790                 + 
"AND data_source_id=? " 
 1792                 + 
"AND file_path=?";
 
 1797                 + 
" SET known_status=?, comment=? " 
 1801             preparedQuery = conn.prepareStatement(sqlQuery);
 
 1805             preparedQuery.setString(4, eamArtifact.
getFilePath());
 
 1806             resultSet = preparedQuery.executeQuery();
 
 1807             if (resultSet.next()) {
 
 1808                 int instance_id = resultSet.getInt(
"id");
 
 1809                 preparedUpdate = conn.prepareStatement(sqlUpdate);
 
 1811                 preparedUpdate.setByte(1, knownStatus.getFileKnownValue());
 
 1816                     preparedUpdate.setNull(2, Types.INTEGER);
 
 1818                     preparedUpdate.setString(2, eamArtifact.
getComment());
 
 1820                 preparedUpdate.setInt(3, instance_id);
 
 1822                 preparedUpdate.executeUpdate();
 
 1834                 addArtifactInstance(eamArtifact);
 
 1837         } 
catch (SQLException ex) {
 
 1838             throw new EamDbException(
"Error getting/setting artifact instance knownStatus=" + knownStatus.getName(), ex); 
 
 1856     public Long getCountArtifactInstancesKnownBad(
CorrelationAttributeInstance.
Type aType, String value) 
throws EamDbException, CorrelationAttributeNormalizationException {
 
 1860         Connection conn = connect();
 
 1862         Long badInstances = 0L;
 
 1863         PreparedStatement preparedStatement = null;
 
 1864         ResultSet resultSet = null;
 
 1868                 = 
"SELECT count(*) FROM " 
 1870                 + 
" WHERE value=? AND known_status=?";
 
 1873             preparedStatement = conn.prepareStatement(sql);
 
 1874             preparedStatement.setString(1, normalizedValue);
 
 1875             preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
 
 1876             resultSet = preparedStatement.executeQuery();
 
 1878             badInstances = resultSet.getLong(1);
 
 1879         } 
catch (SQLException ex) {
 
 1880             throw new EamDbException(
"Error getting count of notable artifact instances.", ex); 
 
 1887         return badInstances;
 
 1903     public List<String> getListCasesHavingArtifactInstancesKnownBad(
CorrelationAttributeInstance.
Type aType, String value) 
throws EamDbException, CorrelationAttributeNormalizationException {
 
 1907         Connection conn = connect();
 
 1909         Collection<String> caseNames = 
new LinkedHashSet<>();
 
 1911         PreparedStatement preparedStatement = null;
 
 1912         ResultSet resultSet = null;
 
 1916                 = 
"SELECT DISTINCT case_name FROM " 
 1918                 + 
" INNER JOIN cases ON " 
 1920                 + 
".case_id=cases.id WHERE " 
 1924                 + 
".known_status=?";
 
 1927             preparedStatement = conn.prepareStatement(sql);
 
 1928             preparedStatement.setString(1, normalizedValue);
 
 1929             preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
 
 1930             resultSet = preparedStatement.executeQuery();
 
 1931             while (resultSet.next()) {
 
 1932                 caseNames.add(resultSet.getString(
"case_name"));
 
 1934         } 
catch (SQLException ex) {
 
 1935             throw new EamDbException(
"Error getting notable artifact instances.", ex); 
 
 1942         return caseNames.stream().collect(Collectors.toList());
 
 1953     public void deleteReferenceSet(
int referenceSetID) 
throws EamDbException {
 
 1954         deleteReferenceSetEntries(referenceSetID);
 
 1955         deleteReferenceSetEntry(referenceSetID);
 
 1965     private void deleteReferenceSetEntry(
int referenceSetID) 
throws EamDbException {
 
 1966         Connection conn = connect();
 
 1968         PreparedStatement preparedStatement = null;
 
 1969         String sql = 
"DELETE FROM reference_sets WHERE id=?";
 
 1972             preparedStatement = conn.prepareStatement(sql);
 
 1973             preparedStatement.setInt(1, referenceSetID);
 
 1974             preparedStatement.executeUpdate();
 
 1975         } 
catch (SQLException ex) {
 
 1976             throw new EamDbException(
"Error deleting reference set " + referenceSetID, ex); 
 
 1991     private void deleteReferenceSetEntries(
int referenceSetID) 
throws EamDbException {
 
 1992         Connection conn = connect();
 
 1994         PreparedStatement preparedStatement = null;
 
 1995         String sql = 
"DELETE FROM %s WHERE reference_set_id=?";
 
 2001             preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
 
 2002             preparedStatement.setInt(1, referenceSetID);
 
 2003             preparedStatement.executeUpdate();
 
 2004         } 
catch (SQLException ex) {
 
 2005             throw new EamDbException(
"Error deleting files from reference set " + referenceSetID, ex); 
 
 2026     public boolean referenceSetIsValid(
int referenceSetID, String setName, String version) 
throws EamDbException {
 
 2027         EamGlobalSet refSet = this.getReferenceSetByID(referenceSetID);
 
 2028         if (refSet == null) {
 
 2047     public boolean isFileHashInReferenceSet(String hash, 
int referenceSetID) 
throws EamDbException, CorrelationAttributeNormalizationException {
 
 2061     public boolean isValueInReferenceSet(String value, 
int referenceSetID, 
int correlationTypeID) 
throws EamDbException, CorrelationAttributeNormalizationException {
 
 2065         Connection conn = connect();
 
 2067         Long matchingInstances = 0L;
 
 2068         PreparedStatement preparedStatement = null;
 
 2069         ResultSet resultSet = null;
 
 2070         String sql = 
"SELECT count(*) FROM %s WHERE value=? AND reference_set_id=?";
 
 2075             preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
 
 2076             preparedStatement.setString(1, normalizeValued);
 
 2077             preparedStatement.setInt(2, referenceSetID);
 
 2078             resultSet = preparedStatement.executeQuery();
 
 2080             matchingInstances = resultSet.getLong(1);
 
 2081         } 
catch (SQLException ex) {
 
 2082             throw new EamDbException(
"Error determining if value (" + normalizeValued + 
") is in reference set " + referenceSetID, ex); 
 
 2089         return 0 < matchingInstances;
 
 2101     public boolean isArtifactKnownBadByReference(
CorrelationAttributeInstance.
Type aType, String value) 
throws EamDbException, CorrelationAttributeNormalizationException {
 
 2111         Connection conn = connect();
 
 2113         Long badInstances = 0L;
 
 2114         PreparedStatement preparedStatement = null;
 
 2115         ResultSet resultSet = null;
 
 2116         String sql = 
"SELECT count(*) FROM %s WHERE value=? AND known_status=?";
 
 2120             preparedStatement.setString(1, normalizeValued);
 
 2121             preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
 
 2122             resultSet = preparedStatement.executeQuery();
 
 2124             badInstances = resultSet.getLong(1);
 
 2125         } 
catch (SQLException ex) {
 
 2126             throw new EamDbException(
"Error determining if artifact is notable by reference.", ex); 
 
 2133         return 0 < badInstances;
 
 2147             throw new EamDbException(
"Correlation type is null");
 
 2150         if (instanceTableCallback == null) {
 
 2151             throw new EamDbException(
"Callback interface is null");
 
 2154         Connection conn = connect();
 
 2155         PreparedStatement preparedStatement = null;
 
 2156         ResultSet resultSet = null;
 
 2158         StringBuilder sql = 
new StringBuilder();
 
 2159         sql.append(
"select * from ");
 
 2160         sql.append(tableName);
 
 2163             preparedStatement = conn.prepareStatement(sql.toString());
 
 2164             resultSet = preparedStatement.executeQuery();
 
 2165             instanceTableCallback.
process(resultSet);
 
 2166         } 
catch (SQLException ex) {
 
 2167             throw new EamDbException(
"Error getting all artifact instances from instances table", ex);
 
 2187             throw new EamDbException(
"Correlation type is null");
 
 2190         if (instanceTableCallback == null) {
 
 2191             throw new EamDbException(
"Callback interface is null");
 
 2194         if (whereClause == null) {
 
 2195             throw new EamDbException(
"Where clause is null");
 
 2198         Connection conn = connect();
 
 2199         PreparedStatement preparedStatement = null;
 
 2200         ResultSet resultSet = null;
 
 2202         StringBuilder sql = 
new StringBuilder(300);
 
 2203         sql.append(
"select * from ")
 
 2206                 .append(whereClause);
 
 2209             preparedStatement = conn.prepareStatement(sql.toString());
 
 2210             resultSet = preparedStatement.executeQuery();
 
 2211             instanceTableCallback.
process(resultSet);
 
 2212         } 
catch (SQLException ex) {
 
 2213             throw new EamDbException(
"Error getting all artifact instances from instances table", ex);
 
 2223         if (eamOrg == null) {
 
 2224             throw new EamDbException(
"EamOrganization is null");
 
 2225         } 
else if (eamOrg.
getOrgID() != -1) {
 
 2226             throw new EamDbException(
"EamOrganization already has an ID");
 
 2229         Connection conn = connect();
 
 2230         ResultSet generatedKeys = null;
 
 2231         PreparedStatement preparedStatement = null;
 
 2232         String sql = 
"INSERT INTO organizations(org_name, poc_name, poc_email, poc_phone) VALUES (?, ?, ?, ?) " 
 2233                 + getConflictClause();
 
 2236             preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
 
 2237             preparedStatement.setString(1, eamOrg.
getName());
 
 2238             preparedStatement.setString(2, eamOrg.
getPocName());
 
 2239             preparedStatement.setString(3, eamOrg.
getPocEmail());
 
 2240             preparedStatement.setString(4, eamOrg.
getPocPhone());
 
 2242             preparedStatement.executeUpdate();
 
 2243             generatedKeys = preparedStatement.getGeneratedKeys();
 
 2244             if (generatedKeys.next()) {
 
 2245                 eamOrg.setOrgID((
int) generatedKeys.getLong(1));
 
 2248                 throw new SQLException(
"Creating user failed, no ID obtained.");
 
 2250         } 
catch (SQLException ex) {
 
 2251             throw new EamDbException(
"Error inserting new organization.", ex); 
 
 2267     public List<EamOrganization> getOrganizations() 
throws EamDbException {
 
 2268         Connection conn = connect();
 
 2270         List<EamOrganization> orgs = 
new ArrayList<>();
 
 2271         PreparedStatement preparedStatement = null;
 
 2272         ResultSet resultSet = null;
 
 2273         String sql = 
"SELECT * FROM organizations";
 
 2276             preparedStatement = conn.prepareStatement(sql);
 
 2277             resultSet = preparedStatement.executeQuery();
 
 2278             while (resultSet.next()) {
 
 2279                 orgs.add(getEamOrganizationFromResultSet(resultSet));
 
 2283         } 
catch (SQLException ex) {
 
 2284             throw new EamDbException(
"Error getting all organizations.", ex); 
 
 2302     public EamOrganization getOrganizationByID(
int orgID) 
throws EamDbException {
 
 2303         Connection conn = connect();
 
 2305         PreparedStatement preparedStatement = null;
 
 2306         ResultSet resultSet = null;
 
 2307         String sql = 
"SELECT * FROM organizations WHERE id=?";
 
 2310             preparedStatement = conn.prepareStatement(sql);
 
 2311             preparedStatement.setInt(1, orgID);
 
 2312             resultSet = preparedStatement.executeQuery();
 
 2314             return getEamOrganizationFromResultSet(resultSet);
 
 2316         } 
catch (SQLException ex) {
 
 2317             throw new EamDbException(
"Error getting organization by id.", ex); 
 
 2335     public EamOrganization getReferenceSetOrganization(
int referenceSetID) 
throws EamDbException {
 
 2337         EamGlobalSet globalSet = getReferenceSetByID(referenceSetID);
 
 2338         if (globalSet == null) {
 
 2339             throw new EamDbException(
"Reference set with ID " + referenceSetID + 
" not found");
 
 2341         return (getOrganizationByID(globalSet.
getOrgID()));
 
 2353             throw new EamDbException(
"EamOrganization is null");
 
 2355             throw new EamDbException(
"Organization  has -1 row ID");
 
 2368     public void updateOrganization(
EamOrganization updatedOrganization) 
throws EamDbException {
 
 2369         testArgument(updatedOrganization);
 
 2371         Connection conn = connect();
 
 2372         PreparedStatement preparedStatement = null;
 
 2373         String sql = 
"UPDATE organizations SET org_name = ?, poc_name = ?, poc_email = ?, poc_phone = ? WHERE id = ?";
 
 2375             preparedStatement = conn.prepareStatement(sql);
 
 2376             preparedStatement.setString(1, updatedOrganization.
getName());
 
 2377             preparedStatement.setString(2, updatedOrganization.
getPocName());
 
 2378             preparedStatement.setString(3, updatedOrganization.
getPocEmail());
 
 2379             preparedStatement.setString(4, updatedOrganization.
getPocPhone());
 
 2380             preparedStatement.setInt(5, updatedOrganization.
getOrgID());
 
 2381             preparedStatement.executeUpdate();
 
 2382         } 
catch (SQLException ex) {
 
 2383             throw new EamDbException(
"Error updating organization.", ex); 
 
 2391     public void deleteOrganization(
EamOrganization organizationToDelete) 
throws EamDbException {
 
 2392         testArgument(organizationToDelete);
 
 2394         Connection conn = connect();
 
 2395         PreparedStatement checkIfUsedStatement = null;
 
 2396         ResultSet resultSet = null;
 
 2397         String checkIfUsedSql = 
"SELECT (select count(*) FROM cases WHERE org_id=?) + (select count(*) FROM reference_sets WHERE org_id=?)";
 
 2398         PreparedStatement deleteOrgStatement = null;
 
 2399         String deleteOrgSql = 
"DELETE FROM organizations WHERE id=?";
 
 2401             checkIfUsedStatement = conn.prepareStatement(checkIfUsedSql);
 
 2402             checkIfUsedStatement.setInt(1, organizationToDelete.
getOrgID());
 
 2403             checkIfUsedStatement.setInt(2, organizationToDelete.
getOrgID());
 
 2404             resultSet = checkIfUsedStatement.executeQuery();
 
 2406             if (resultSet.getLong(1) > 0) {
 
 2407                 throw new EamDbException(
"Can not delete organization which is currently in use by a case or reference set in the central repository.");
 
 2409             deleteOrgStatement = conn.prepareStatement(deleteOrgSql);
 
 2410             deleteOrgStatement.setInt(1, organizationToDelete.
getOrgID());
 
 2411             deleteOrgStatement.executeUpdate();
 
 2412         } 
catch (SQLException ex) {
 
 2413             throw new EamDbException(
"Error executing query when attempting to delete organization by id.", ex); 
 
 2432     public int newReferenceSet(
EamGlobalSet eamGlobalSet) 
throws EamDbException {
 
 2433         if (eamGlobalSet == null) {
 
 2434             throw new EamDbException(
"EamGlobalSet is null");
 
 2438             throw new EamDbException(
"File known status on the EamGlobalSet is null");
 
 2441         if (eamGlobalSet.
getType() == null) {
 
 2442             throw new EamDbException(
"Type on the EamGlobalSet is null");
 
 2445         Connection conn = connect();
 
 2447         PreparedStatement preparedStatement1 = null;
 
 2448         PreparedStatement preparedStatement2 = null;
 
 2449         ResultSet resultSet = null;
 
 2450         String sql1 = 
"INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, type, import_date) VALUES (?, ?, ?, ?, ?, ?, ?) " 
 2451                 + getConflictClause();
 
 2452         String sql2 = 
"SELECT id FROM reference_sets WHERE org_id=? AND set_name=? AND version=? AND import_date=? LIMIT 1";
 
 2455             preparedStatement1 = conn.prepareStatement(sql1);
 
 2456             preparedStatement1.setInt(1, eamGlobalSet.
getOrgID());
 
 2457             preparedStatement1.setString(2, eamGlobalSet.
getSetName());
 
 2458             preparedStatement1.setString(3, eamGlobalSet.
getVersion());
 
 2460             preparedStatement1.setBoolean(5, eamGlobalSet.
isReadOnly());
 
 2461             preparedStatement1.setInt(6, eamGlobalSet.
getType().getId());
 
 2462             preparedStatement1.setString(7, eamGlobalSet.
getImportDate().toString());
 
 2464             preparedStatement1.executeUpdate();
 
 2466             preparedStatement2 = conn.prepareStatement(sql2);
 
 2467             preparedStatement2.setInt(1, eamGlobalSet.
getOrgID());
 
 2468             preparedStatement2.setString(2, eamGlobalSet.
getSetName());
 
 2469             preparedStatement2.setString(3, eamGlobalSet.
getVersion());
 
 2470             preparedStatement2.setString(4, eamGlobalSet.
getImportDate().toString());
 
 2472             resultSet = preparedStatement2.executeQuery();
 
 2474             return resultSet.getInt(
"id");
 
 2476         } 
catch (SQLException ex) {
 
 2477             throw new EamDbException(
"Error inserting new global set.", ex); 
 
 2496     public EamGlobalSet getReferenceSetByID(
int referenceSetID) 
throws EamDbException {
 
 2497         Connection conn = connect();
 
 2499         PreparedStatement preparedStatement1 = null;
 
 2500         ResultSet resultSet = null;
 
 2501         String sql1 = 
"SELECT * FROM reference_sets WHERE id=?";
 
 2504             preparedStatement1 = conn.prepareStatement(sql1);
 
 2505             preparedStatement1.setInt(1, referenceSetID);
 
 2506             resultSet = preparedStatement1.executeQuery();
 
 2507             if (resultSet.next()) {
 
 2508                 return getEamGlobalSetFromResultSet(resultSet);
 
 2513         } 
catch (SQLException ex) {
 
 2514             throw new EamDbException(
"Error getting reference set by id.", ex); 
 
 2534         if (correlationType == null) {
 
 2535             throw new EamDbException(
"Correlation type is null");
 
 2538         List<EamGlobalSet> results = 
new ArrayList<>();
 
 2539         Connection conn = connect();
 
 2541         PreparedStatement preparedStatement1 = null;
 
 2542         ResultSet resultSet = null;
 
 2543         String sql1 = 
"SELECT * FROM reference_sets WHERE type=" + correlationType.getId();
 
 2546             preparedStatement1 = conn.prepareStatement(sql1);
 
 2547             resultSet = preparedStatement1.executeQuery();
 
 2548             while (resultSet.next()) {
 
 2549                 results.add(getEamGlobalSetFromResultSet(resultSet));
 
 2552         } 
catch (SQLException ex) {
 
 2553             throw new EamDbException(
"Error getting reference sets.", ex); 
 
 2574             throw new EamDbException(
"Known status of EamGlobalFileInstance is null");
 
 2576         if (correlationType == null) {
 
 2577             throw new EamDbException(
"Correlation type is null");
 
 2580         Connection conn = connect();
 
 2582         PreparedStatement preparedStatement = null;
 
 2584         String sql = 
"INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) " 
 2585                 + getConflictClause();
 
 2589             preparedStatement.setInt(1, eamGlobalFileInstance.
getGlobalSetID());
 
 2590             preparedStatement.setString(2, eamGlobalFileInstance.
getMD5Hash());
 
 2591             preparedStatement.setByte(3, eamGlobalFileInstance.
getKnownStatus().getFileKnownValue());
 
 2592             preparedStatement.setString(4, eamGlobalFileInstance.
getComment());
 
 2593             preparedStatement.executeUpdate();
 
 2594         } 
catch (SQLException ex) {
 
 2595             throw new EamDbException(
"Error inserting new reference instance into reference_ table.", ex); 
 
 2615     public boolean referenceSetExists(String referenceSetName, String version) 
throws EamDbException {
 
 2616         Connection conn = connect();
 
 2618         PreparedStatement preparedStatement1 = null;
 
 2619         ResultSet resultSet = null;
 
 2620         String sql1 = 
"SELECT * FROM reference_sets WHERE set_name=? AND version=?";
 
 2623             preparedStatement1 = conn.prepareStatement(sql1);
 
 2624             preparedStatement1.setString(1, referenceSetName);
 
 2625             preparedStatement1.setString(2, version);
 
 2626             resultSet = preparedStatement1.executeQuery();
 
 2627             return (resultSet.next());
 
 2629         } 
catch (SQLException ex) {
 
 2630             throw new EamDbException(
"Error testing whether reference set exists (name: " + referenceSetName
 
 2631                     + 
" version: " + version, ex); 
 
 2645     public void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances, 
CorrelationAttributeInstance.
Type contentType) 
throws EamDbException {
 
 2646         if (contentType == null) {
 
 2647             throw new EamDbException(
"Correlation type is null");
 
 2649         if (globalInstances == null) {
 
 2650             throw new EamDbException(
"Null set of EamGlobalFileInstance");
 
 2653         Connection conn = connect();
 
 2655         PreparedStatement bulkPs = null;
 
 2657             conn.setAutoCommit(
false);
 
 2660             String sql = 
"INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) " 
 2661                     + getConflictClause();
 
 2666                 if (globalInstance.getKnownStatus() == null) {
 
 2667                     throw new EamDbException(
"EamGlobalFileInstance with value " + globalInstance.getMD5Hash() + 
" has null known status");
 
 2670                 bulkPs.setInt(1, globalInstance.getGlobalSetID());
 
 2671                 bulkPs.setString(2, globalInstance.getMD5Hash());
 
 2672                 bulkPs.setByte(3, globalInstance.getKnownStatus().getFileKnownValue());
 
 2673                 bulkPs.setString(4, globalInstance.getComment());
 
 2677             bulkPs.executeBatch();
 
 2679         } 
catch (SQLException | EamDbException ex) {
 
 2682             } 
catch (SQLException ex2) {
 
 2685             throw new EamDbException(
"Error inserting bulk artifacts.", ex); 
 
 2703     public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(
CorrelationAttributeInstance.
Type aType, String aValue) 
throws EamDbException, CorrelationAttributeNormalizationException {
 
 2706         Connection conn = connect();
 
 2708         List<EamGlobalFileInstance> globalFileInstances = 
new ArrayList<>();
 
 2709         PreparedStatement preparedStatement1 = null;
 
 2710         ResultSet resultSet = null;
 
 2711         String sql1 = 
"SELECT * FROM %s WHERE value=?";
 
 2715             preparedStatement1.setString(1, normalizeValued);
 
 2716             resultSet = preparedStatement1.executeQuery();
 
 2717             while (resultSet.next()) {
 
 2718                 globalFileInstances.add(getEamGlobalFileInstanceFromResultSet(resultSet));
 
 2721         } 
catch (SQLException ex) {
 
 2722             throw new EamDbException(
"Error getting reference instances by type and value.", ex); 
 
 2729         return globalFileInstances;
 
 2743         if (newType == null) {
 
 2744             throw new EamDbException(
"Correlation type is null");
 
 2747         if (-1 == newType.getId()) {
 
 2748             typeId = newCorrelationTypeNotKnownId(newType);
 
 2750             typeId = newCorrelationTypeKnownId(newType);
 
 2767         Connection conn = connect();
 
 2769         PreparedStatement preparedStatement = null;
 
 2770         PreparedStatement preparedStatementQuery = null;
 
 2771         ResultSet resultSet = null;
 
 2776         insertSql = 
"INSERT INTO correlation_types(display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?) " + getConflictClause();
 
 2778         querySql = 
"SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
 
 2781             preparedStatement = conn.prepareStatement(insertSql);
 
 2783             preparedStatement.setString(1, newType.getDisplayName());
 
 2784             preparedStatement.setString(2, newType.getDbTableName());
 
 2785             preparedStatement.setInt(3, newType.isSupported() ? 1 : 0);
 
 2786             preparedStatement.setInt(4, newType.isEnabled() ? 1 : 0);
 
 2788             preparedStatement.executeUpdate();
 
 2790             preparedStatementQuery = conn.prepareStatement(querySql);
 
 2791             preparedStatementQuery.setString(1, newType.getDisplayName());
 
 2792             preparedStatementQuery.setString(2, newType.getDbTableName());
 
 2794             resultSet = preparedStatementQuery.executeQuery();
 
 2795             if (resultSet.next()) {
 
 2797                 typeId = correlationType.getId();
 
 2799         } 
catch (SQLException ex) {
 
 2800             throw new EamDbException(
"Error inserting new correlation type.", ex); 
 
 2820         Connection conn = connect();
 
 2822         PreparedStatement preparedStatement = null;
 
 2823         PreparedStatement preparedStatementQuery = null;
 
 2824         ResultSet resultSet = null;
 
 2829         insertSql = 
"INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause();
 
 2831         querySql = 
"SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
 
 2834             preparedStatement = conn.prepareStatement(insertSql);
 
 2836             preparedStatement.setInt(1, newType.getId());
 
 2837             preparedStatement.setString(2, newType.getDisplayName());
 
 2838             preparedStatement.setString(3, newType.getDbTableName());
 
 2839             preparedStatement.setInt(4, newType.isSupported() ? 1 : 0);
 
 2840             preparedStatement.setInt(5, newType.isEnabled() ? 1 : 0);
 
 2842             preparedStatement.executeUpdate();
 
 2844             preparedStatementQuery = conn.prepareStatement(querySql);
 
 2845             preparedStatementQuery.setString(1, newType.getDisplayName());
 
 2846             preparedStatementQuery.setString(2, newType.getDbTableName());
 
 2848             resultSet = preparedStatementQuery.executeQuery();
 
 2849             if (resultSet.next()) {
 
 2851                 typeId = correlationType.getId();
 
 2853         } 
catch (SQLException ex) {
 
 2854             throw new EamDbException(
"Error inserting new correlation type.", ex); 
 
 2866         Connection conn = connect();
 
 2869         PreparedStatement preparedStatement = null;
 
 2870         ResultSet resultSet = null;
 
 2871         String sql = 
"SELECT * FROM correlation_types";
 
 2874             preparedStatement = conn.prepareStatement(sql);
 
 2875             resultSet = preparedStatement.executeQuery();
 
 2876             while (resultSet.next()) {
 
 2877                 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
 
 2881         } 
catch (SQLException ex) {
 
 2882             throw new EamDbException(
"Error getting all correlation types.", ex); 
 
 2901         Connection conn = connect();
 
 2904         PreparedStatement preparedStatement = null;
 
 2905         ResultSet resultSet = null;
 
 2906         String sql = 
"SELECT * FROM correlation_types WHERE enabled=1";
 
 2909             preparedStatement = conn.prepareStatement(sql);
 
 2910             resultSet = preparedStatement.executeQuery();
 
 2911             while (resultSet.next()) {
 
 2912                 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
 
 2916         } 
catch (SQLException ex) {
 
 2917             throw new EamDbException(
"Error getting enabled correlation types.", ex); 
 
 2936         Connection conn = connect();
 
 2939         PreparedStatement preparedStatement = null;
 
 2940         ResultSet resultSet = null;
 
 2941         String sql = 
"SELECT * FROM correlation_types WHERE supported=1";
 
 2944             preparedStatement = conn.prepareStatement(sql);
 
 2945             resultSet = preparedStatement.executeQuery();
 
 2946             while (resultSet.next()) {
 
 2947                 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
 
 2951         } 
catch (SQLException ex) {
 
 2952             throw new EamDbException(
"Error getting supported correlation types.", ex); 
 
 2969         Connection conn = connect();
 
 2971         PreparedStatement preparedStatement = null;
 
 2972         String sql = 
"UPDATE correlation_types SET display_name=?, db_table_name=?, supported=?, enabled=? WHERE id=?";
 
 2975             preparedStatement = conn.prepareStatement(sql);
 
 2976             preparedStatement.setString(1, aType.getDisplayName());
 
 2977             preparedStatement.setString(2, aType.getDbTableName());
 
 2978             preparedStatement.setInt(3, aType.isSupported() ? 1 : 0);
 
 2979             preparedStatement.setInt(4, aType.isEnabled() ? 1 : 0);
 
 2980             preparedStatement.setInt(5, aType.getId());
 
 2981             preparedStatement.executeUpdate();
 
 2982             typeCache.put(aType.getId(), aType);
 
 2983         } 
catch (SQLException ex) {
 
 2984             throw new EamDbException(
"Error updating correlation type.", ex); 
 
 3004             return typeCache.get(typeId, () -> getCorrelationTypeByIdFromCr(typeId));
 
 3005         } 
catch (CacheLoader.InvalidCacheLoadException ignored) {
 
 3008         } 
catch (ExecutionException ex) {
 
 3009             throw new EamDbException(
"Error getting correlation type", ex);
 
 3023         Connection conn = connect();
 
 3026         PreparedStatement preparedStatement = null;
 
 3027         ResultSet resultSet = null;
 
 3028         String sql = 
"SELECT * FROM correlation_types WHERE id=?";
 
 3031             preparedStatement = conn.prepareStatement(sql);
 
 3032             preparedStatement.setInt(1, typeId);
 
 3033             resultSet = preparedStatement.executeQuery();
 
 3034             if (resultSet.next()) {
 
 3035                 aType = getCorrelationTypeFromResultSet(resultSet);
 
 3038                 throw new EamDbException(
"Failed to find entry for correlation type ID = " + typeId);
 
 3041         } 
catch (SQLException ex) {
 
 3042             throw new EamDbException(
"Error getting correlation type by id.", ex); 
 
 3060     private CorrelationCase getEamCaseFromResultSet(ResultSet resultSet) 
throws SQLException {
 
 3061         if (null == resultSet) {
 
 3067         resultSet.getInt(
"org_id");
 
 3068         if (!resultSet.wasNull()) {
 
 3071                     resultSet.getString(
"org_name"),
 
 3072                     resultSet.getString(
"poc_name"),
 
 3073                     resultSet.getString(
"poc_email"),
 
 3074                     resultSet.getString(
"poc_phone"));
 
 3077         CorrelationCase eamCase = 
new CorrelationCase(resultSet.getInt(
"case_id"), resultSet.getString(
"case_uid"), eamOrg, resultSet.getString(
"case_name"),
 
 3078                 resultSet.getString(
"creation_date"), resultSet.getString(
"case_number"), resultSet.getString(
"examiner_name"),
 
 3079                 resultSet.getString(
"examiner_email"), resultSet.getString(
"examiner_phone"), resultSet.getString(
"notes"));
 
 3084     private CorrelationDataSource getEamDataSourceFromResultSet(ResultSet resultSet) 
throws SQLException {
 
 3085         if (null == resultSet) {
 
 3090                 resultSet.getInt(
"case_id"),
 
 3091                 resultSet.getInt(
"id"),
 
 3092                 resultSet.getString(
"device_id"),
 
 3093                 resultSet.getString(
"name"),
 
 3094                 resultSet.getLong(
"datasource_obj_id"),
 
 3095                 resultSet.getString(
"md5"),
 
 3096                 resultSet.getString(
"sha1"),
 
 3097                 resultSet.getString(
"sha256")
 
 3100         return eamDataSource;
 
 3104         if (null == resultSet) {
 
 3109                 resultSet.getInt(
"id"),
 
 3110                 resultSet.getString(
"display_name"),
 
 3111                 resultSet.getString(
"db_table_name"),
 
 3112                 resultSet.getBoolean(
"supported"),
 
 3113                 resultSet.getBoolean(
"enabled")
 
 3116         return eamArtifactType;
 
 3130         if (null == resultSet) {
 
 3135                 resultSet.getString(
"org_name"),
 
 3136                 resultSet.getString(
"poc_name"),
 
 3137                 resultSet.getString(
"poc_email"),
 
 3138                 resultSet.getString(
"poc_phone"));
 
 3142                 resultSet.getString(
"value"),
 
 3143                 resultSet.getInt(
"instance_id"),
 
 3144                 new CorrelationCase(resultSet.getInt(
"id"), resultSet.getString(
"case_uid"), eamOrg, resultSet.getString(
"case_name"),
 
 3145                         resultSet.getString(
"creation_date"), resultSet.getString(
"case_number"), resultSet.getString(
"examiner_name"),
 
 3146                         resultSet.getString(
"examiner_email"), resultSet.getString(
"examiner_phone"), resultSet.getString(
"notes")),
 
 3148                         resultSet.getInt(
"id"), resultSet.getInt(
"data_source_id"), resultSet.getString(
"device_id"), resultSet.getString(
"name"),
 
 3149                         resultSet.getLong(
"datasource_obj_id"), resultSet.getString(
"md5"), resultSet.getString(
"sha1"), resultSet.getString(
"sha256")),
 
 3150                 resultSet.getString(
"file_path"),
 
 3151                 resultSet.getString(
"comment"),
 
 3152                 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
 
 3153                 resultSet.getLong(
"file_obj_id"));
 
 3156     private EamOrganization getEamOrganizationFromResultSet(ResultSet resultSet) 
throws SQLException {
 
 3157         if (null == resultSet) {
 
 3162                 resultSet.getInt(
"id"),
 
 3163                 resultSet.getString(
"org_name"),
 
 3164                 resultSet.getString(
"poc_name"),
 
 3165                 resultSet.getString(
"poc_email"),
 
 3166                 resultSet.getString(
"poc_phone")
 
 3170     private EamGlobalSet getEamGlobalSetFromResultSet(ResultSet resultSet) 
throws SQLException, EamDbException {
 
 3171         if (null == resultSet) {
 
 3176                 resultSet.getInt(
"id"),
 
 3177                 resultSet.getInt(
"org_id"),
 
 3178                 resultSet.getString(
"set_name"),
 
 3179                 resultSet.getString(
"version"),
 
 3180                 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
 
 3181                 resultSet.getBoolean(
"read_only"),
 
 3183                 LocalDate.parse(resultSet.getString(
"import_date"))
 
 3187     private EamGlobalFileInstance getEamGlobalFileInstanceFromResultSet(ResultSet resultSet) 
throws SQLException, EamDbException, CorrelationAttributeNormalizationException {
 
 3188         if (null == resultSet) {
 
 3193                 resultSet.getInt(
"id"),
 
 3194                 resultSet.getInt(
"reference_set_id"),
 
 3195                 resultSet.getString(
"value"),
 
 3196                 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
 
 3197                 resultSet.getString(
"comment")
 
 3211     abstract boolean doesColumnExist(Connection conn, String tableName, String columnName) 
throws SQLException;
 
 3218     @Messages({
"AbstractSqlEamDb.upgradeSchema.incompatible=The selected Central Repository is not compatible with the current version of the application, please upgrade the application if you wish to use this Central Repository.",
 
 3219         "# {0} - minorVersion",
 
 3220         "AbstractSqlEamDb.badMinorSchema.message=Bad value for schema minor version ({0}) - database is corrupt.",
 
 3221         "AbstractSqlEamDb.failedToReadMinorVersion.message=Failed to read schema minor version for Central Repository.",
 
 3222         "# {0} - majorVersion",
 
 3223         "AbstractSqlEamDb.badMajorSchema.message=Bad value for schema version ({0}) - database is corrupt.",
 
 3224         "AbstractSqlEamDb.failedToReadMajorVersion.message=Failed to read schema version for Central Repository.",
 
 3225         "# {0} - platformName",
 
 3226         "AbstractSqlEamDb.cannotUpgrage.message=Currently selected database platform \"{0}\" can not be upgraded."})
 
 3230         ResultSet resultSet = null;
 
 3231         Statement statement = null;
 
 3232         PreparedStatement preparedStatement = null;
 
 3233         Connection conn = null;
 
 3237             conn = connect(
false);
 
 3238             conn.setAutoCommit(
false);
 
 3239             statement = conn.createStatement();
 
 3241             int minorVersion = 0;
 
 3242             String minorVersionStr = null;
 
 3243             resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name='" + AbstractSqlEamDb.SCHEMA_MINOR_VERSION_KEY + 
"'");
 
 3244             if (resultSet.next()) {
 
 3245                 minorVersionStr = resultSet.getString(
"value");
 
 3247                     minorVersion = Integer.parseInt(minorVersionStr);
 
 3248                 } 
catch (NumberFormatException ex) {
 
 3249                     throw new EamDbException(Bundle.AbstractSqlEamDb_badMinorSchema_message(minorVersionStr), ex);
 
 3252                 throw new EamDbException(Bundle.AbstractSqlEamDb_failedToReadMinorVersion_message());
 
 3255             int majorVersion = 0;
 
 3256             String majorVersionStr = null;
 
 3257             resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name='" + AbstractSqlEamDb.SCHEMA_MAJOR_VERSION_KEY + 
"'");
 
 3258             if (resultSet.next()) {
 
 3259                 majorVersionStr = resultSet.getString(
"value");
 
 3261                     majorVersion = Integer.parseInt(majorVersionStr);
 
 3262                 } 
catch (NumberFormatException ex) {
 
 3263                     throw new EamDbException(Bundle.AbstractSqlEamDb_badMajorSchema_message(majorVersionStr), ex);
 
 3266                 throw new EamDbException(Bundle.AbstractSqlEamDb_failedToReadMajorVersion_message());
 
 3277             CaseDbSchemaVersionNumber dbSchemaVersion = 
new CaseDbSchemaVersionNumber(majorVersion, minorVersion);
 
 3282             if (SOFTWARE_CR_DB_SCHEMA_VERSION.getMajor() < dbSchemaVersion.getMajor()) {
 
 3285             if (dbSchemaVersion.equals(SOFTWARE_CR_DB_SCHEMA_VERSION)) {
 
 3286                 logger.log(Level.INFO, 
"Central Repository is up to date");
 
 3289             if (dbSchemaVersion.compareTo(SOFTWARE_CR_DB_SCHEMA_VERSION) > 0) {
 
 3290                 logger.log(Level.INFO, 
"Central Repository is of newer version than software creates");
 
 3297             if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 1)) < 0) {
 
 3298                 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN known_status INTEGER;"); 
 
 3299                 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN read_only BOOLEAN;"); 
 
 3300                 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN type INTEGER;"); 
 
 3305                 EamDbUtil.insertDefaultOrganization(conn);
 
 3311             if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 2)) < 0) {
 
 3312                 final String addIntegerColumnTemplate = 
"ALTER TABLE %s ADD COLUMN %s INTEGER;";  
 
 3313                 final String addSsidTableTemplate;
 
 3314                 final String addCaseIdIndexTemplate;
 
 3315                 final String addDataSourceIdIndexTemplate;
 
 3316                 final String addValueIndexTemplate;
 
 3317                 final String addKnownStatusIndexTemplate;
 
 3318                 final String addObjectIdIndexTemplate;
 
 3320                 final String addAttributeSql;
 
 3322                 switch (selectedPlatform) {
 
 3324                         addAttributeSql = 
"INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause();  
 
 3334                         addAttributeSql = 
"INSERT OR IGNORE INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?)";  
 
 3344                         throw new EamDbException(Bundle.AbstractSqlEamDb_cannotUpgrage_message(selectedPlatform.name()));
 
 3346                 final String dataSourcesTableName = 
"data_sources";
 
 3347                 final String dataSourceObjectIdColumnName = 
"datasource_obj_id";
 
 3348                 if (!doesColumnExist(conn, dataSourcesTableName, dataSourceObjectIdColumnName)) {
 
 3349                     statement.execute(String.format(addIntegerColumnTemplate, dataSourcesTableName, dataSourceObjectIdColumnName)); 
 
 3351                 final String dataSourceObjectIdIndexTemplate = 
"CREATE INDEX IF NOT EXISTS datasource_object_id ON data_sources (%s)";
 
 3352                 statement.execute(String.format(dataSourceObjectIdIndexTemplate, dataSourceObjectIdColumnName));
 
 3353                 List<String> instaceTablesToAdd = 
new ArrayList<>();
 
 3355                 final String wirelessNetworksDbTableName = 
"wireless_networks";
 
 3356                 instaceTablesToAdd.add(wirelessNetworksDbTableName + 
"_instances");
 
 3357                 final String macAddressDbTableName = 
"mac_address";
 
 3358                 instaceTablesToAdd.add(macAddressDbTableName + 
"_instances");
 
 3359                 final String imeiNumberDbTableName = 
"imei_number";
 
 3360                 instaceTablesToAdd.add(imeiNumberDbTableName + 
"_instances");
 
 3361                 final String iccidNumberDbTableName = 
"iccid_number";
 
 3362                 instaceTablesToAdd.add(iccidNumberDbTableName + 
"_instances");
 
 3363                 final String imsiNumberDbTableName = 
"imsi_number";
 
 3364                 instaceTablesToAdd.add(imsiNumberDbTableName + 
"_instances");
 
 3367                 preparedStatement = conn.prepareStatement(addAttributeSql);
 
 3369                 preparedStatement.setString(2, Bundle.CorrelationType_SSID_displayName());
 
 3370                 preparedStatement.setString(3, wirelessNetworksDbTableName);
 
 3371                 preparedStatement.setInt(4, 1);
 
 3372                 preparedStatement.setInt(5, 1);
 
 3373                 preparedStatement.execute();
 
 3376                 preparedStatement = conn.prepareStatement(addAttributeSql);
 
 3378                 preparedStatement.setString(2, Bundle.CorrelationType_MAC_displayName());
 
 3379                 preparedStatement.setString(3, macAddressDbTableName);
 
 3380                 preparedStatement.setInt(4, 1);
 
 3381                 preparedStatement.setInt(5, 1);
 
 3382                 preparedStatement.execute();
 
 3385                 preparedStatement = conn.prepareStatement(addAttributeSql);
 
 3387                 preparedStatement.setString(2, Bundle.CorrelationType_IMEI_displayName());
 
 3388                 preparedStatement.setString(3, imeiNumberDbTableName);
 
 3389                 preparedStatement.setInt(4, 1);
 
 3390                 preparedStatement.setInt(5, 1);
 
 3391                 preparedStatement.execute();
 
 3394                 preparedStatement = conn.prepareStatement(addAttributeSql);
 
 3396                 preparedStatement.setString(2, Bundle.CorrelationType_IMSI_displayName());
 
 3397                 preparedStatement.setString(3, imsiNumberDbTableName);
 
 3398                 preparedStatement.setInt(4, 1);
 
 3399                 preparedStatement.setInt(5, 1);
 
 3400                 preparedStatement.execute();
 
 3403                 preparedStatement = conn.prepareStatement(addAttributeSql);
 
 3405                 preparedStatement.setString(2, Bundle.CorrelationType_ICCID_displayName());
 
 3406                 preparedStatement.setString(3, iccidNumberDbTableName);
 
 3407                 preparedStatement.setInt(4, 1);
 
 3408                 preparedStatement.setInt(5, 1);
 
 3409                 preparedStatement.execute();
 
 3412                 for (String tableName : instaceTablesToAdd) {
 
 3413                     statement.execute(String.format(addSsidTableTemplate, tableName, tableName));
 
 3414                     statement.execute(String.format(addCaseIdIndexTemplate, tableName, tableName));
 
 3415                     statement.execute(String.format(addDataSourceIdIndexTemplate, tableName, tableName));
 
 3416                     statement.execute(String.format(addValueIndexTemplate, tableName, tableName));
 
 3417                     statement.execute(String.format(addKnownStatusIndexTemplate, tableName, tableName));
 
 3421                 String instance_type_dbname;
 
 3422                 final String objectIdColumnName = 
"file_obj_id";
 
 3425                     if (!doesColumnExist(conn, instance_type_dbname, objectIdColumnName)) {
 
 3426                         statement.execute(String.format(addIntegerColumnTemplate, instance_type_dbname, objectIdColumnName)); 
 
 3428                     statement.execute(String.format(addObjectIdIndexTemplate, instance_type_dbname, instance_type_dbname));
 
 3434                 if (!doesColumnExist(conn, dataSourcesTableName, 
"md5")) {
 
 3435                     statement.execute(
"ALTER TABLE data_sources ADD COLUMN md5 TEXT DEFAULT NULL");
 
 3437                 if (!doesColumnExist(conn, dataSourcesTableName, 
"sha1")) {
 
 3438                     statement.execute(
"ALTER TABLE data_sources ADD COLUMN sha1 TEXT DEFAULT NULL");
 
 3440                 if (!doesColumnExist(conn, dataSourcesTableName, 
"sha256")) {
 
 3441                     statement.execute(
"ALTER TABLE data_sources ADD COLUMN sha256 TEXT DEFAULT NULL");
 
 3452                 String creationMajorVer;
 
 3453                 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name = '" + AbstractSqlEamDb.CREATION_SCHEMA_MAJOR_VERSION_KEY + 
"'");
 
 3454                 if (resultSet.next()) {
 
 3455                     creationMajorVer = resultSet.getString(
"value");
 
 3457                     creationMajorVer = 
"0";
 
 3459                 String creationMinorVer;
 
 3460                 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name = '" + AbstractSqlEamDb.CREATION_SCHEMA_MINOR_VERSION_KEY + 
"'");
 
 3461                 if (resultSet.next()) {
 
 3462                     creationMinorVer = resultSet.getString(
"value");
 
 3464                     creationMinorVer = 
"0";
 
 3466                 statement.execute(
"DROP TABLE db_info");
 
 3468                     statement.execute(
"CREATE TABLE db_info (id SERIAL, name TEXT UNIQUE NOT NULL, value TEXT NOT NULL)");
 
 3470                     statement.execute(
"CREATE TABLE db_info (id INTEGER PRIMARY KEY, name TEXT UNIQUE NOT NULL, value TEXT NOT NULL)");
 
 3472                 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + AbstractSqlEamDb.SCHEMA_MAJOR_VERSION_KEY + 
"','" + majorVersionStr + 
"')");
 
 3473                 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + AbstractSqlEamDb.SCHEMA_MINOR_VERSION_KEY + 
"','" + minorVersionStr + 
"')");
 
 3474                 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + AbstractSqlEamDb.CREATION_SCHEMA_MAJOR_VERSION_KEY + 
"','" + creationMajorVer + 
"')");
 
 3475                 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + AbstractSqlEamDb.CREATION_SCHEMA_MINOR_VERSION_KEY + 
"','" + creationMinorVer + 
"')");
 
 3480             if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 3)) < 0) {
 
 3481                 switch (selectedPlatform) {
 
 3483                         statement.execute(
"ALTER TABLE data_sources DROP CONSTRAINT datasource_unique");
 
 3485                         statement.execute(
"ALTER TABLE data_sources ADD CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name, datasource_obj_id)");
 
 3489                         statement.execute(
"DROP INDEX IF EXISTS data_sources_name");
 
 3490                         statement.execute(
"DROP INDEX IF EXISTS data_sources_object_id");
 
 3491                         statement.execute(
"ALTER TABLE data_sources RENAME TO old_data_sources");
 
 3493                         statement.execute(
"CREATE TABLE IF NOT EXISTS data_sources (id integer primary key autoincrement NOT NULL," 
 3494                                 + 
"case_id integer NOT NULL,device_id text NOT NULL,name text NOT NULL,datasource_obj_id integer," 
 3495                                 + 
"md5 text DEFAULT NULL,sha1 text DEFAULT NULL,sha256 text DEFAULT NULL," 
 3496                                 + 
"foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL," 
 3497                                 + 
"CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name, datasource_obj_id))");
 
 3500                         statement.execute(
"INSERT INTO data_sources SELECT * FROM old_data_sources");
 
 3501                         statement.execute(
"DROP TABLE old_data_sources");
 
 3504                         throw new EamDbException(Bundle.AbstractSqlEamDb_cannotUpgrage_message(selectedPlatform.name()));
 
 3507             updateSchemaVersion(conn);
 
 3509             logger.log(Level.INFO, String.format(
"Central Repository schema updated to version %s", SOFTWARE_CR_DB_SCHEMA_VERSION));
 
 3510         } 
catch (SQLException | EamDbException ex) {
 
 3515             } 
catch (SQLException ex2) {
 
 3516                 logger.log(Level.SEVERE, String.format(
"Central Repository rollback of failed schema update to %s failed", SOFTWARE_CR_DB_SCHEMA_VERSION), ex2);
 
TskData.FileKnown getKnownStatus()
String getExaminerPhone()
CorrelationAttributeInstance.Type getType()
static String correlationTypeToInstanceTableName(CorrelationAttributeInstance.Type type)
static final int ICCID_TYPE_ID
static void closeResultSet(ResultSet resultSet)
static void closeStatement(Statement statement)
static List< CorrelationAttributeInstance.Type > getDefaultCorrelationTypes()
String getCorrelationValue()
static final int IMEI_TYPE_ID
static TimingMetric getTimingMetric(String name)
TskData.FileKnown getKnownStatus()
void process(ResultSet resultSet)
Type getCorrelationType()
static String normalize(CorrelationAttributeInstance.Type attributeType, String data)
static EamDb getInstance()
static void closeConnection(Connection conn)
void setKnownStatus(TskData.FileKnown knownStatus)
CorrelationAttributeInstance.Type getCorrelationTypeById(int typeId)
TskData.FileKnown getFileKnownStatus()
CorrelationDataSource getCorrelationDataSource()
String getExaminerEmail()
LocalDate getImportDate()
String getExaminerPhone()
static final int MAC_TYPE_ID
Long getDataSourceObjectID()
static void submitTimingMetric(TimingMetric metric)
static final int IMSI_TYPE_ID
synchronized static Logger getLogger(String name)
CorrelationCase getCorrelationCase()
static String correlationTypeToReferenceTableName(CorrelationAttributeInstance.Type type)
static EamOrganization getDefault()
static final int SSID_TYPE_ID
static final int FILES_TYPE_ID
String getExaminerEmail()