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.HashMap;
 
   40 import java.util.concurrent.ExecutionException;
 
   41 import java.util.concurrent.TimeUnit;
 
   42 import java.util.logging.Level;
 
   48 import org.
sleuthkit.datamodel.CaseDbSchemaVersionNumber;
 
   56 abstract class AbstractSqlEamDb 
implements EamDb {
 
   62     private int bulkArtifactsCount;
 
   63     protected int bulkArtifactsThreshold;
 
   64     private final Map<String, Collection<CorrelationAttributeInstance>> bulkArtifacts;
 
   65     private static final int CASE_CACHE_TIMEOUT = 5;
 
   66     private static final int DATA_SOURCE_CACHE_TIMEOUT = 5;
 
   68     private static final Cache<String, CorrelationCase> caseCacheByUUID = CacheBuilder.newBuilder()
 
   69             .expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES).
 
   71     private static final Cache<Integer, CorrelationCase> caseCacheById = CacheBuilder.newBuilder()
 
   72             .expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES).
 
   74     private static final Cache<String, CorrelationDataSource> dataSourceCacheByDeviceId = CacheBuilder.newBuilder()
 
   75             .expireAfterWrite(DATA_SOURCE_CACHE_TIMEOUT, TimeUnit.MINUTES).
 
   77     private static final Cache<String, CorrelationDataSource> dataSourceCacheById = CacheBuilder.newBuilder()
 
   78             .expireAfterWrite(DATA_SOURCE_CACHE_TIMEOUT, TimeUnit.MINUTES).
 
   81     static final int MAX_VALUE_LENGTH = 256;
 
   85     static final int DEFAULT_BULK_THRESHHOLD = 1000;
 
   93         bulkArtifactsCount = 0;
 
   94         bulkArtifacts = 
new HashMap<>();
 
   97         defaultCorrelationTypes.forEach((type) -> {
 
   98             bulkArtifacts.put(type.getDbTableName(), 
new ArrayList<>());
 
  116     public void newDbInfo(String name, String value) 
throws EamDbException {
 
  117         Connection conn = connect();
 
  119         PreparedStatement preparedStatement = null;
 
  120         String sql = 
"INSERT INTO db_info (name, value) VALUES (?, ?) " 
  121                 + getConflictClause();
 
  123             preparedStatement = conn.prepareStatement(sql);
 
  124             preparedStatement.setString(1, name);
 
  125             preparedStatement.setString(2, value);
 
  126             preparedStatement.executeUpdate();
 
  127         } 
catch (SQLException ex) {
 
  128             throw new EamDbException(
"Error adding new name/value pair to db_info.", ex);
 
  146     public String getDbInfo(String name) 
throws EamDbException {
 
  147         Connection conn = connect();
 
  149         PreparedStatement preparedStatement = null;
 
  150         ResultSet resultSet = null;
 
  152         String sql = 
"SELECT value FROM db_info WHERE name=?";
 
  154             preparedStatement = conn.prepareStatement(sql);
 
  155             preparedStatement.setString(1, name);
 
  156             resultSet = preparedStatement.executeQuery();
 
  157             if (resultSet.next()) {
 
  158                 value = resultSet.getString(
"value");
 
  160         } 
catch (SQLException ex) {
 
  161             throw new EamDbException(
"Error getting value for name.", ex);
 
  174     protected final void clearCaches() {
 
  175         typeCache.invalidateAll();
 
  176         caseCacheByUUID.invalidateAll();
 
  177         caseCacheById.invalidateAll();
 
  178         dataSourceCacheByDeviceId.invalidateAll();
 
  179         dataSourceCacheById.invalidateAll();
 
  191     public void updateDbInfo(String name, String value) 
throws EamDbException {
 
  192         Connection conn = connect();
 
  194         PreparedStatement preparedStatement = null;
 
  195         String sql = 
"UPDATE db_info SET value=? WHERE name=?";
 
  197             preparedStatement = conn.prepareStatement(sql);
 
  198             preparedStatement.setString(1, value);
 
  199             preparedStatement.setString(2, name);
 
  200             preparedStatement.executeUpdate();
 
  201         } 
catch (SQLException ex) {
 
  202             throw new EamDbException(
"Error updating value for name.", ex);
 
  223         if (cRCase != null) {
 
  227         Connection conn = connect();
 
  228         PreparedStatement preparedStatement = null;
 
  230         String sql = 
"INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, " 
  231                 + 
"examiner_name, examiner_email, examiner_phone, notes) " 
  232                 + 
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) " 
  233                 + getConflictClause();
 
  234         ResultSet resultSet = null;
 
  236             preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
 
  238             preparedStatement.setString(1, eamCase.
getCaseUUID());
 
  239             if (null == eamCase.
getOrg()) {
 
  240                 preparedStatement.setNull(2, Types.INTEGER);
 
  247                 preparedStatement.setNull(5, Types.INTEGER);
 
  252                 preparedStatement.setNull(6, Types.INTEGER);
 
  257                 preparedStatement.setNull(7, Types.INTEGER);
 
  262                 preparedStatement.setNull(8, Types.INTEGER);
 
  266             if (
"".equals(eamCase.
getNotes())) {
 
  267                 preparedStatement.setNull(9, Types.INTEGER);
 
  269                 preparedStatement.setString(9, eamCase.
getNotes());
 
  272             preparedStatement.executeUpdate();
 
  274             resultSet = preparedStatement.getGeneratedKeys();
 
  275             if (!resultSet.next()) {
 
  276                 throw new EamDbException(String.format(
"Failed to INSERT case %s in central repo", eamCase.
getCaseUUID()));
 
  278             int caseID = resultSet.getInt(1); 
 
  282             caseCacheByUUID.put(eamCase.
getCaseUUID(), correlationCase);
 
  283             caseCacheById.put(caseID, correlationCase);
 
  284         } 
catch (SQLException ex) {
 
  285             throw new EamDbException(
"Error inserting new case.", ex); 
 
  303         if (autopsyCase == null) {
 
  304             throw new EamDbException(
"Case is null");
 
  318         return newCase(curCeCase);
 
  323         return getCaseByUUID(autopsyCase.
getName());
 
  332     public void updateCase(
CorrelationCase eamCase) 
throws EamDbException {
 
  333         if (eamCase == null) {
 
  334             throw new EamDbException(
"Correlation case is null");
 
  337         Connection conn = connect();
 
  339         PreparedStatement preparedStatement = null;
 
  340         String sql = 
"UPDATE cases " 
  341                 + 
"SET org_id=?, case_name=?, creation_date=?, case_number=?, examiner_name=?, examiner_email=?, examiner_phone=?, notes=? " 
  342                 + 
"WHERE case_uid=?";
 
  345             preparedStatement = conn.prepareStatement(sql);
 
  347             if (null == eamCase.
getOrg()) {
 
  348                 preparedStatement.setNull(1, Types.INTEGER);
 
  356                 preparedStatement.setNull(4, Types.INTEGER);
 
  361                 preparedStatement.setNull(5, Types.INTEGER);
 
  366                 preparedStatement.setNull(6, Types.INTEGER);
 
  371                 preparedStatement.setNull(7, Types.INTEGER);
 
  375             if (
"".equals(eamCase.
getNotes())) {
 
  376                 preparedStatement.setNull(8, Types.INTEGER);
 
  378                 preparedStatement.setString(8, eamCase.
getNotes());
 
  381             preparedStatement.setString(9, eamCase.
getCaseUUID());
 
  383             preparedStatement.executeUpdate();
 
  385             caseCacheById.put(eamCase.
getID(), eamCase);
 
  386             caseCacheByUUID.put(eamCase.
getCaseUUID(), eamCase);
 
  387         } 
catch (SQLException ex) {
 
  388             throw new EamDbException(
"Error updating case.", ex); 
 
  403     public CorrelationCase getCaseByUUID(String caseUUID) 
throws EamDbException {
 
  405             return caseCacheByUUID.get(caseUUID, () -> getCaseByUUIDFromCr(caseUUID));
 
  406         } 
catch (CacheLoader.InvalidCacheLoadException ignored) {
 
  409         } 
catch (ExecutionException ex) {
 
  410             throw new EamDbException(
"Error getting autopsy case from Central repo", ex);
 
  421     private CorrelationCase getCaseByUUIDFromCr(String caseUUID) 
throws EamDbException {
 
  422         Connection conn = connect();
 
  425         PreparedStatement preparedStatement = null;
 
  426         ResultSet resultSet = null;
 
  428         String sql = 
"SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, " 
  429                 + 
"examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone " 
  431                 + 
"LEFT JOIN organizations ON cases.org_id=organizations.id " 
  432                 + 
"WHERE case_uid=?";
 
  435             preparedStatement = conn.prepareStatement(sql);
 
  436             preparedStatement.setString(1, caseUUID);
 
  437             resultSet = preparedStatement.executeQuery();
 
  438             if (resultSet.next()) {
 
  439                 eamCaseResult = getEamCaseFromResultSet(resultSet);
 
  441             if (eamCaseResult != null) {
 
  443                 caseCacheById.put(eamCaseResult.
getID(), eamCaseResult);
 
  445         } 
catch (SQLException ex) {
 
  446             throw new EamDbException(
"Error getting case details.", ex); 
 
  453         return eamCaseResult;
 
  466             return caseCacheById.get(caseId, () -> getCaseByIdFromCr(caseId));
 
  467         } 
catch (CacheLoader.InvalidCacheLoadException ignored) {
 
  470         } 
catch (ExecutionException ex) {
 
  471             throw new EamDbException(
"Error getting autopsy case from Central repo", ex);
 
  482     private CorrelationCase getCaseByIdFromCr(
int caseId) 
throws EamDbException {
 
  483         Connection conn = connect();
 
  486         PreparedStatement preparedStatement = null;
 
  487         ResultSet resultSet = null;
 
  489         String sql = 
"SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, " 
  490                 + 
"examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone " 
  492                 + 
"LEFT JOIN organizations ON cases.org_id=organizations.id " 
  493                 + 
"WHERE cases.id=?";
 
  495             preparedStatement = conn.prepareStatement(sql);
 
  496             preparedStatement.setInt(1, caseId);
 
  497             resultSet = preparedStatement.executeQuery();
 
  498             if (resultSet.next()) {
 
  499                 eamCaseResult = getEamCaseFromResultSet(resultSet);
 
  501             if (eamCaseResult != null) {
 
  503                 caseCacheByUUID.put(eamCaseResult.
getCaseUUID(), eamCaseResult);
 
  505         } 
catch (SQLException ex) {
 
  506             throw new EamDbException(
"Error getting case details.", ex); 
 
  513         return eamCaseResult;
 
  522     public List<CorrelationCase> getCases() 
throws EamDbException {
 
  523         Connection conn = connect();
 
  525         List<CorrelationCase> cases = 
new ArrayList<>();
 
  527         PreparedStatement preparedStatement = null;
 
  528         ResultSet resultSet = null;
 
  530         String sql = 
"SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, " 
  531                 + 
"examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone " 
  533                 + 
"LEFT JOIN organizations ON cases.org_id=organizations.id";
 
  536             preparedStatement = conn.prepareStatement(sql);
 
  537             resultSet = preparedStatement.executeQuery();
 
  538             while (resultSet.next()) {
 
  539                 eamCaseResult = getEamCaseFromResultSet(resultSet);
 
  540                 cases.add(eamCaseResult);
 
  542         } 
catch (SQLException ex) {
 
  543             throw new EamDbException(
"Error getting all cases.", ex); 
 
  562     private static String getDataSourceByDeviceIdCacheKey(
int caseId, String dataSourceDeviceId) {
 
  563         return "Case" + caseId + 
"DeviceId" + dataSourceDeviceId; 
 
  575     private static String getDataSourceByIdCacheKey(
int caseId, 
int dataSourceId) {
 
  576         return "Case" + caseId + 
"Id" + dataSourceId; 
 
  587             throw new EamDbException(
"Case ID is -1");
 
  588         } 
else if (eamDataSource.getID() != -1) {
 
  592         Connection conn = connect();
 
  594         PreparedStatement preparedStatement = null;
 
  596         String sql = 
"INSERT INTO data_sources(device_id, case_id, name) VALUES (?, ?, ?) " 
  597                 + getConflictClause();
 
  598         ResultSet resultSet = null;
 
  600             preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
 
  602             preparedStatement.setString(1, eamDataSource.
getDeviceID());
 
  603             preparedStatement.setInt(2, eamDataSource.
getCaseID());
 
  604             preparedStatement.setString(3, eamDataSource.
getName());
 
  606             preparedStatement.executeUpdate();
 
  607             resultSet = preparedStatement.getGeneratedKeys();
 
  608             if (!resultSet.next()) {
 
  609                 throw new EamDbException(String.format(
"Failed to INSERT data source %s in central repo", eamDataSource.
getName()));
 
  611             int dataSourceId = resultSet.getInt(1); 
 
  613             dataSourceCacheByDeviceId.put(getDataSourceByDeviceIdCacheKey(dataSource.
getCaseID(), dataSource.
getDeviceID()), dataSource);
 
  614             dataSourceCacheById.put(getDataSourceByIdCacheKey(dataSource.
getCaseID(), dataSource.getID()), dataSource);
 
  615         } 
catch (SQLException ex) {
 
  616             throw new EamDbException(
"Error inserting new data source.", ex); 
 
  638         if (correlationCase == null) {
 
  639             throw new EamDbException(
"Correlation case is null");
 
  642             return dataSourceCacheByDeviceId.get(getDataSourceByDeviceIdCacheKey(correlationCase.
getID(), dataSourceDeviceId), () -> getDataSourceFromCr(correlationCase, dataSourceDeviceId));
 
  643         } 
catch (CacheLoader.InvalidCacheLoadException ignored) {
 
  646         } 
catch (ExecutionException ex) {
 
  647             throw new EamDbException(
"Error getting data source from central repository", ex);
 
  664         Connection conn = connect();
 
  667         PreparedStatement preparedStatement = null;
 
  668         ResultSet resultSet = null;
 
  670         String sql = 
"SELECT * FROM data_sources WHERE device_id=? AND case_id=?"; 
 
  673             preparedStatement = conn.prepareStatement(sql);
 
  674             preparedStatement.setString(1, dataSourceDeviceId);
 
  675             preparedStatement.setInt(2, correlationCase.
getID());
 
  676             resultSet = preparedStatement.executeQuery();
 
  677             if (resultSet.next()) {
 
  678                 eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
 
  680             if (eamDataSourceResult != null) {
 
  681                 dataSourceCacheById.put(getDataSourceByIdCacheKey(correlationCase.
getID(), eamDataSourceResult.getID()), eamDataSourceResult);
 
  683         } 
catch (SQLException ex) {
 
  684             throw new EamDbException(
"Error getting data source.", ex); 
 
  691         return eamDataSourceResult;
 
  705         if (correlationCase == null) {
 
  706             throw new EamDbException(
"Correlation case is null");
 
  709             return dataSourceCacheById.get(getDataSourceByIdCacheKey(correlationCase.
getID(), dataSourceId), () -> getDataSourceByIdFromCr(correlationCase, dataSourceId));
 
  710         } 
catch (CacheLoader.InvalidCacheLoadException ignored) {
 
  713         } 
catch (ExecutionException ex) {
 
  714             throw new EamDbException(
"Error getting data source from central repository", ex);
 
  728         Connection conn = connect();
 
  731         PreparedStatement preparedStatement = null;
 
  732         ResultSet resultSet = null;
 
  734         String sql = 
"SELECT * FROM data_sources WHERE id=? AND case_id=?"; 
 
  737             preparedStatement = conn.prepareStatement(sql);
 
  738             preparedStatement.setInt(1, dataSourceId);
 
  739             preparedStatement.setInt(2, correlationCase.
getID());
 
  740             resultSet = preparedStatement.executeQuery();
 
  741             if (resultSet.next()) {
 
  742                 eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
 
  744             if (eamDataSourceResult != null) {
 
  745                 dataSourceCacheByDeviceId.put(getDataSourceByDeviceIdCacheKey(correlationCase.
getID(), eamDataSourceResult.
getDeviceID()), eamDataSourceResult);
 
  747         } 
catch (SQLException ex) {
 
  748             throw new EamDbException(
"Error getting data source.", ex); 
 
  755         return eamDataSourceResult;
 
  764     public List<CorrelationDataSource> getDataSources() 
throws EamDbException {
 
  765         Connection conn = connect();
 
  767         List<CorrelationDataSource> dataSources = 
new ArrayList<>();
 
  769         PreparedStatement preparedStatement = null;
 
  770         ResultSet resultSet = null;
 
  772         String sql = 
"SELECT * FROM data_sources";
 
  775             preparedStatement = conn.prepareStatement(sql);
 
  776             resultSet = preparedStatement.executeQuery();
 
  777             while (resultSet.next()) {
 
  778                 eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
 
  779                 dataSources.add(eamDataSourceResult);
 
  781         } 
catch (SQLException ex) {
 
  782             throw new EamDbException(
"Error getting all data sources.", ex); 
 
  800         checkAddArtifactInstanceNulls(eamArtifact);
 
  802         Connection conn = connect();
 
  804         PreparedStatement preparedStatement = null;
 
  811                 + 
"(case_id, data_source_id, value, file_path, known_status, comment) " 
  812                 + 
"VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), " 
  813                 + 
"(SELECT id FROM data_sources WHERE device_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?) " 
  814                 + getConflictClause();
 
  817             preparedStatement = conn.prepareStatement(sql);
 
  825                 preparedStatement.setString(5, eamArtifact.
getFilePath().toLowerCase());
 
  826                 preparedStatement.setByte(6, eamArtifact.
getKnownStatus().getFileKnownValue());
 
  828                     preparedStatement.setNull(7, Types.INTEGER);
 
  830                     preparedStatement.setString(7, eamArtifact.
getComment());
 
  833                 preparedStatement.executeUpdate();
 
  836         } 
catch (SQLException ex) {
 
  837             throw new EamDbException(
"Error inserting new artifact into artifacts table.", ex); 
 
  845         if (eamArtifact == null) {
 
  846             throw new EamDbException(
"CorrelationAttribute is null");
 
  849             throw new EamDbException(
"Correlation type is null");
 
  852             throw new EamDbException(
"Correlation value is null");
 
  855             throw new EamDbException(
"Artifact value too long for central repository." 
  856                     + 
"\nCorrelationArtifact ID: " + eamArtifact.
getID()
 
  862             throw new EamDbException(
"CorrelationAttributeInstance case is null");
 
  865             throw new EamDbException(
"CorrelationAttributeInstance data source is null");
 
  868             throw new EamDbException(
"CorrelationAttributeInstance known status is null");
 
  888         Connection conn = connect();
 
  890         List<CorrelationAttributeInstance> artifactInstances = 
new ArrayList<>();
 
  893         PreparedStatement preparedStatement = null;
 
  894         ResultSet resultSet = null;
 
  903                 + 
" cases.case_name, cases.case_uid, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id FROM " 
  905                 + 
" LEFT JOIN cases ON " 
  907                 + 
".case_id=cases.id" 
  908                 + 
" LEFT JOIN data_sources ON " 
  910                 + 
".data_source_id=data_sources.id" 
  914             preparedStatement = conn.prepareStatement(sql);
 
  915             preparedStatement.setString(1, normalizedValue);
 
  916             resultSet = preparedStatement.executeQuery();
 
  917             while (resultSet.next()) {
 
  918                 artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
 
  919                 artifactInstances.add(artifactInstance);
 
  921         } 
catch (SQLException ex) {
 
  922             throw new EamDbException(
"Error getting artifact instances by artifactType and artifactValue.", ex); 
 
  929         return artifactInstances;
 
  946             throw new EamDbException(
"Correlation type is null");
 
  948         if (filePath == null) {
 
  949             throw new EamDbException(
"Correlation value is null");
 
  951         Connection conn = connect();
 
  953         List<CorrelationAttributeInstance> artifactInstances = 
new ArrayList<>();
 
  956         PreparedStatement preparedStatement = null;
 
  957         ResultSet resultSet = null;
 
  966                 + 
" cases.case_name, cases.case_uid, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id FROM " 
  968                 + 
" LEFT JOIN cases ON " 
  970                 + 
".case_id=cases.id" 
  971                 + 
" LEFT JOIN data_sources ON " 
  973                 + 
".data_source_id=data_sources.id" 
  974                 + 
" WHERE file_path=?";
 
  977             preparedStatement = conn.prepareStatement(sql);
 
  978             preparedStatement.setString(1, filePath.toLowerCase());
 
  979             resultSet = preparedStatement.executeQuery();
 
  980             while (resultSet.next()) {
 
  982                     artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
 
  983                     artifactInstances.add(artifactInstance);
 
  985                     logger.log(Level.INFO, 
"Unable to get artifact instance from resultset.", ex);
 
  988         } 
catch (SQLException ex) {
 
  989             throw new EamDbException(
"Error getting artifact instances by artifactType and artifactValue.", ex); 
 
  996         return artifactInstances;
 
 1013         Connection conn = connect();
 
 1015         Long instanceCount = 0L;
 
 1016         PreparedStatement preparedStatement = null;
 
 1017         ResultSet resultSet = null;
 
 1021                 = 
"SELECT count(*) FROM " 
 1026             preparedStatement = conn.prepareStatement(sql);
 
 1027             preparedStatement.setString(1, normalizedValue);
 
 1028             resultSet = preparedStatement.executeQuery();
 
 1030             instanceCount = resultSet.getLong(1);
 
 1031         } 
catch (SQLException ex) {
 
 1032             throw new EamDbException(
"Error getting count of artifact instances by artifactType and artifactValue.", ex); 
 
 1039         return instanceCount;
 
 1044         if (corAttr == null) {
 
 1045             throw new EamDbException(
"CorrelationAttribute is null");
 
 1048         Double uniqueCaseDataSourceTuples = getCountUniqueDataSources().doubleValue();
 
 1049         Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100;
 
 1050         return commonalityPercentage.intValue();
 
 1067         Connection conn = connect();
 
 1069         Long instanceCount = 0L;
 
 1070         PreparedStatement preparedStatement = null;
 
 1071         ResultSet resultSet = null;
 
 1075                 = 
"SELECT count(*) FROM (SELECT DISTINCT case_id, data_source_id FROM " 
 1077                 + 
" WHERE value=?) AS " 
 1079                 + 
"_distinct_case_data_source_tuple";
 
 1082             preparedStatement = conn.prepareStatement(sql);
 
 1083             preparedStatement.setString(1, normalizedValue);
 
 1084             resultSet = preparedStatement.executeQuery();
 
 1086             instanceCount = resultSet.getLong(1);
 
 1087         } 
catch (SQLException ex) {
 
 1088             throw new EamDbException(
"Error counting unique caseDisplayName/dataSource tuples having artifactType and artifactValue.", ex); 
 
 1095         return instanceCount;
 
 1099     public Long getCountUniqueDataSources() 
throws EamDbException {
 
 1100         Connection conn = connect();
 
 1102         Long instanceCount = 0L;
 
 1103         PreparedStatement preparedStatement = null;
 
 1104         ResultSet resultSet = null;
 
 1106         String stmt = 
"SELECT count(*) FROM data_sources";
 
 1109             preparedStatement = conn.prepareStatement(stmt);
 
 1110             resultSet = preparedStatement.executeQuery();
 
 1112             instanceCount = resultSet.getLong(1);
 
 1113         } 
catch (SQLException ex) {
 
 1114             throw new EamDbException(
"Error counting data sources.", ex); 
 
 1121         return instanceCount;
 
 1136     public Long getCountArtifactInstancesByCaseDataSource(String caseUUID, String dataSourceID) 
throws EamDbException {
 
 1137         Connection conn = connect();
 
 1139         Long instanceCount = 0L;
 
 1141         PreparedStatement preparedStatement = null;
 
 1142         ResultSet resultSet = null;
 
 1145         String sql = 
"SELECT 0 ";
 
 1151                     += 
"+ (SELECT count(*) FROM " 
 1153                     + 
" WHERE data_source_id=(SELECT data_sources.id FROM cases INNER JOIN data_sources ON cases.id = data_sources.case_id WHERE case_uid=? and device_id=?))";
 
 1157             preparedStatement = conn.prepareStatement(sql);
 
 1159             for (
int i = 0; i < artifactTypes.size(); ++i) {
 
 1160                 preparedStatement.setString(2 * i + 1, caseUUID);
 
 1161                 preparedStatement.setString(2 * i + 2, dataSourceID);
 
 1164             resultSet = preparedStatement.executeQuery();
 
 1166             instanceCount = resultSet.getLong(1);
 
 1167         } 
catch (SQLException ex) {
 
 1168             throw new EamDbException(
"Error counting artifact instances by caseName/dataSource.", ex); 
 
 1175         return instanceCount;
 
 1189             throw new EamDbException(
"Correlation type is null");
 
 1192         synchronized (bulkArtifacts) {
 
 1194             bulkArtifactsCount++;
 
 1196             if (bulkArtifactsCount >= bulkArtifactsThreshold) {
 
 1197                 commitAttributeInstancesBulk();
 
 1207     protected abstract String getConflictClause();
 
 1214     public void commitAttributeInstancesBulk() 
throws EamDbException {
 
 1217         Connection conn = connect();
 
 1218         PreparedStatement bulkPs = null;
 
 1221             synchronized (bulkArtifacts) {
 
 1222                 if (bulkArtifactsCount == 0) {
 
 1232                             + 
" (case_id, data_source_id, value, file_path, known_status, comment) " 
 1233                             + 
"VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), " 
 1234                             + 
"(SELECT id FROM data_sources WHERE device_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?) " 
 1235                             + getConflictClause();
 
 1237                     bulkPs = conn.prepareStatement(sql);
 
 1239                     Collection<CorrelationAttributeInstance> eamArtifacts = bulkArtifacts.get(type.getDbTableName());
 
 1245                                 throw new EamDbException(
"CorrelationAttributeInstance case is null for: " 
 1246                                         + 
"\n\tCorrelationArtifact ID: " + eamArtifact.
getID()
 
 1251                                 throw new EamDbException(
"CorrelationAttributeInstance data source is null for: " 
 1252                                         + 
"\n\tCorrelationArtifact ID: " + eamArtifact.
getID()
 
 1257                                 throw new EamDbException(
"CorrelationAttributeInstance known status is null for: " 
 1258                                         + 
"\n\tCorrelationArtifact ID: " + eamArtifact.
getID()
 
 1261                                         + 
"\n\tEam Instance: " 
 1272                                 bulkPs.setByte(6, eamArtifact.
getKnownStatus().getFileKnownValue());
 
 1274                                     bulkPs.setNull(7, Types.INTEGER);
 
 1276                                     bulkPs.setString(7, eamArtifact.
getComment());
 
 1280                                 logger.log(Level.WARNING, (
"Artifact value too long for central repository." 
 1281                                         + 
"\n\tCorrelationArtifact ID: " + eamArtifact.
getID()
 
 1284                                         + 
"\n\tEam Instance: " 
 1287                                         + 
"\n\t\tFilePath: " + eamArtifact.
getFilePath());
 
 1293                     bulkPs.executeBatch();
 
 1294                     bulkArtifacts.get(type.getDbTableName()).clear();
 
 1301                 bulkArtifactsCount = 0;
 
 1303         } 
catch (SQLException ex) {
 
 1304             throw new EamDbException(
"Error inserting bulk artifacts.", ex); 
 
 1315     public void bulkInsertCases(List<CorrelationCase> cases) 
throws EamDbException {
 
 1316         if (cases == null) {
 
 1317             throw new EamDbException(
"cases argument is null");
 
 1320         if (cases.isEmpty()) {
 
 1324         Connection conn = connect();
 
 1327         PreparedStatement bulkPs = null;
 
 1329             String sql = 
"INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, " 
 1330                     + 
"examiner_name, examiner_email, examiner_phone, notes) " 
 1331                     + 
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) " 
 1332                     + getConflictClause();
 
 1333             bulkPs = conn.prepareStatement(sql);
 
 1337                 if (null == eamCase.
getOrg()) {
 
 1338                     bulkPs.setNull(2, Types.INTEGER);
 
 1346                     bulkPs.setNull(5, Types.INTEGER);
 
 1351                     bulkPs.setNull(6, Types.INTEGER);
 
 1356                     bulkPs.setNull(7, Types.INTEGER);
 
 1361                     bulkPs.setNull(8, Types.INTEGER);
 
 1365                 if (
"".equals(eamCase.
getNotes())) {
 
 1366                     bulkPs.setNull(9, Types.INTEGER);
 
 1368                     bulkPs.setString(9, eamCase.
getNotes());
 
 1376                 if (counter >= bulkArtifactsThreshold) {
 
 1377                     bulkPs.executeBatch();
 
 1382             bulkPs.executeBatch();
 
 1383         } 
catch (SQLException ex) {
 
 1384             throw new EamDbException(
"Error inserting bulk cases.", ex); 
 
 1403         if (eamArtifact == null) {
 
 1404             throw new EamDbException(
"CorrelationAttributeInstance is null");
 
 1407             throw new EamDbException(
"Correlation case is null");
 
 1410             throw new EamDbException(
"Correlation data source is null");
 
 1413         Connection conn = connect();
 
 1414         PreparedStatement preparedQuery = null;
 
 1421                 + 
"WHERE case_id=(SELECT id FROM cases WHERE case_uid=?) " 
 1422                 + 
"AND data_source_id=(SELECT id FROM data_sources WHERE device_id=?) " 
 1424                 + 
"AND file_path=?";
 
 1427             preparedQuery = conn.prepareStatement(sqlUpdate);
 
 1428             preparedQuery.setString(1, eamArtifact.
getComment());
 
 1432             preparedQuery.setString(5, eamArtifact.
getFilePath().toLowerCase());
 
 1433             preparedQuery.executeUpdate();
 
 1434         } 
catch (SQLException ex) {
 
 1435             throw new EamDbException(
"Error getting/setting artifact instance comment=" + eamArtifact.
getComment(), ex); 
 
 1460         if (correlationCase == null) {
 
 1461             throw new EamDbException(
"Correlation case is null");
 
 1463         if (correlationDataSource == null) {
 
 1464             throw new EamDbException(
"Correlation data source is null");
 
 1466         if (filePath == null) {
 
 1467             throw new EamDbException(
"Correlation file path is null");
 
 1470         Connection conn = connect();
 
 1472         PreparedStatement preparedStatement = null;
 
 1473         ResultSet resultSet = null;
 
 1481                     = 
"SELECT id, known_status, comment FROM " 
 1483                     + 
" WHERE case_id=?" 
 1484                     + 
" AND data_source_id=?" 
 1486                     + 
" AND file_path=?";
 
 1488             preparedStatement = conn.prepareStatement(sql);
 
 1489             preparedStatement.setInt(1, correlationCase.
getID());
 
 1490             preparedStatement.setInt(2, correlationDataSource.getID());
 
 1491             preparedStatement.setString(3, normalizedValue);
 
 1492             preparedStatement.setString(4, filePath.toLowerCase());
 
 1493             resultSet = preparedStatement.executeQuery();
 
 1494             if (resultSet.next()) {
 
 1495                 int instanceId = resultSet.getInt(1);
 
 1496                 int knownStatus = resultSet.getInt(2);
 
 1497                 String comment = resultSet.getString(3);
 
 1500                         instanceId, correlationCase, correlationDataSource, filePath, comment, TskData.FileKnown.valueOf((byte) knownStatus));
 
 1502         } 
catch (SQLException ex) {
 
 1503             throw new EamDbException(
"Error getting notable artifact instances.", ex); 
 
 1510         return correlationAttributeInstance;
 
 1524     public void setAttributeInstanceKnownStatus(
CorrelationAttributeInstance eamArtifact, TskData.FileKnown knownStatus) 
throws EamDbException {
 
 1525         if (eamArtifact == null) {
 
 1526             throw new EamDbException(
"CorrelationAttribute is null");
 
 1528         if (knownStatus == null) {
 
 1529             throw new EamDbException(
"Known status is null");
 
 1533             throw new EamDbException(
"Correlation case is null");
 
 1536             throw new EamDbException(
"Correlation data source is null");
 
 1539         Connection conn = connect();
 
 1541         PreparedStatement preparedUpdate = null;
 
 1542         PreparedStatement preparedQuery = null;
 
 1543         ResultSet resultSet = null;
 
 1550                 + 
" WHERE case_id=(SELECT id FROM cases WHERE case_uid=?) " 
 1551                 + 
"AND data_source_id=(SELECT id FROM data_sources WHERE device_id=?) " 
 1553                 + 
"AND file_path=?";
 
 1558                 + 
" SET known_status=?, comment=? " 
 1562             preparedQuery = conn.prepareStatement(sqlQuery);
 
 1566             preparedQuery.setString(4, eamArtifact.
getFilePath());
 
 1567             resultSet = preparedQuery.executeQuery();
 
 1568             if (resultSet.next()) {
 
 1569                 int instance_id = resultSet.getInt(
"id");
 
 1570                 preparedUpdate = conn.prepareStatement(sqlUpdate);
 
 1572                 preparedUpdate.setByte(1, knownStatus.getFileKnownValue());
 
 1577                     preparedUpdate.setNull(2, Types.INTEGER);
 
 1579                     preparedUpdate.setString(2, eamArtifact.
getComment());
 
 1581                 preparedUpdate.setInt(3, instance_id);
 
 1583                 preparedUpdate.executeUpdate();
 
 1591                 if (null == correlationCaseWithId) {
 
 1599                 addArtifactInstance(eamArtifact);
 
 1602         } 
catch (SQLException ex) {
 
 1603             throw new EamDbException(
"Error getting/setting artifact instance knownStatus=" + knownStatus.getName(), ex); 
 
 1625         Connection conn = connect();
 
 1627         List<CorrelationAttributeInstance> artifactInstances = 
new ArrayList<>();
 
 1630         PreparedStatement preparedStatement = null;
 
 1631         ResultSet resultSet = null;
 
 1640                 + 
"cases.case_name, cases.case_uid, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id FROM " 
 1642                 + 
" LEFT JOIN cases ON " 
 1644                 + 
".case_id=cases.id" 
 1645                 + 
" LEFT JOIN data_sources ON " 
 1647                 + 
".data_source_id=data_sources.id" 
 1648                 + 
" WHERE value=? AND known_status=?";
 
 1651             preparedStatement = conn.prepareStatement(sql);
 
 1652             preparedStatement.setString(1, normalizedValue);
 
 1653             preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
 
 1654             resultSet = preparedStatement.executeQuery();
 
 1655             while (resultSet.next()) {
 
 1656                 artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
 
 1657                 artifactInstances.add(artifactInstance);
 
 1659         } 
catch (SQLException ex) {
 
 1660             throw new EamDbException(
"Error getting notable artifact instances.", ex); 
 
 1667         return artifactInstances;
 
 1683         if (aType == null) {
 
 1684             throw new EamDbException(
"Correlation type is null");
 
 1687         Connection conn = connect();
 
 1689         List<CorrelationAttributeInstance> artifactInstances = 
new ArrayList<>();
 
 1692         PreparedStatement preparedStatement = null;
 
 1693         ResultSet resultSet = null;
 
 1697                 = 
"SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, id, value FROM " 
 1699                 + 
" LEFT JOIN cases ON " 
 1701                 + 
".case_id=cases.id" 
 1702                 + 
" LEFT JOIN data_sources ON " 
 1704                 + 
".data_source_id=data_sources.id" 
 1705                 + 
" WHERE known_status=?" 
 1711             preparedStatement = conn.prepareStatement(sql);
 
 1712             preparedStatement.setByte(1, TskData.FileKnown.BAD.getFileKnownValue());
 
 1713             resultSet = preparedStatement.executeQuery();
 
 1714             while (resultSet.next()) {
 
 1716                     artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
 
 1717                     artifactInstances.add(artifactInstance);
 
 1719                     logger.log(Level.INFO, 
"Unable to get artifact instance from resultset.", ex);
 
 1722         } 
catch (SQLException ex) {
 
 1723             throw new EamDbException(
"Error getting notable artifact instances.", ex); 
 
 1730         return artifactInstances;
 
 1746         Connection conn = connect();
 
 1748         Long badInstances = 0L;
 
 1749         PreparedStatement preparedStatement = null;
 
 1750         ResultSet resultSet = null;
 
 1754                 = 
"SELECT count(*) FROM " 
 1756                 + 
" WHERE value=? AND known_status=?";
 
 1759             preparedStatement = conn.prepareStatement(sql);
 
 1760             preparedStatement.setString(1, normalizedValue);
 
 1761             preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
 
 1762             resultSet = preparedStatement.executeQuery();
 
 1764             badInstances = resultSet.getLong(1);
 
 1765         } 
catch (SQLException ex) {
 
 1766             throw new EamDbException(
"Error getting count of notable artifact instances.", ex); 
 
 1773         return badInstances;
 
 1793         Connection conn = connect();
 
 1795         Collection<String> caseNames = 
new LinkedHashSet<>();
 
 1797         PreparedStatement preparedStatement = null;
 
 1798         ResultSet resultSet = null;
 
 1802                 = 
"SELECT DISTINCT case_name FROM " 
 1804                 + 
" INNER JOIN cases ON " 
 1806                 + 
".case_id=cases.id WHERE " 
 1810                 + 
".known_status=?";
 
 1813             preparedStatement = conn.prepareStatement(sql);
 
 1814             preparedStatement.setString(1, normalizedValue);
 
 1815             preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
 
 1816             resultSet = preparedStatement.executeQuery();
 
 1817             while (resultSet.next()) {
 
 1818                 caseNames.add(resultSet.getString(
"case_name"));
 
 1820         } 
catch (SQLException ex) {
 
 1821             throw new EamDbException(
"Error getting notable artifact instances.", ex); 
 
 1828         return caseNames.stream().collect(Collectors.toList());
 
 1839     public void deleteReferenceSet(
int referenceSetID) 
throws EamDbException {
 
 1840         deleteReferenceSetEntries(referenceSetID);
 
 1841         deleteReferenceSetEntry(referenceSetID);
 
 1851     private void deleteReferenceSetEntry(
int referenceSetID) 
throws EamDbException {
 
 1852         Connection conn = connect();
 
 1854         PreparedStatement preparedStatement = null;
 
 1855         String sql = 
"DELETE FROM reference_sets WHERE id=?";
 
 1858             preparedStatement = conn.prepareStatement(sql);
 
 1859             preparedStatement.setInt(1, referenceSetID);
 
 1860             preparedStatement.executeUpdate();
 
 1861         } 
catch (SQLException ex) {
 
 1862             throw new EamDbException(
"Error deleting reference set " + referenceSetID, ex); 
 
 1877     private void deleteReferenceSetEntries(
int referenceSetID) 
throws EamDbException {
 
 1878         Connection conn = connect();
 
 1880         PreparedStatement preparedStatement = null;
 
 1881         String sql = 
"DELETE FROM %s WHERE reference_set_id=?";
 
 1887             preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
 
 1888             preparedStatement.setInt(1, referenceSetID);
 
 1889             preparedStatement.executeUpdate();
 
 1890         } 
catch (SQLException ex) {
 
 1891             throw new EamDbException(
"Error deleting files from reference set " + referenceSetID, ex); 
 
 1912     public boolean referenceSetIsValid(
int referenceSetID, String setName, String version) 
throws EamDbException {
 
 1913         EamGlobalSet refSet = this.getReferenceSetByID(referenceSetID);
 
 1914         if (refSet == null) {
 
 1951         Connection conn = connect();
 
 1953         Long matchingInstances = 0L;
 
 1954         PreparedStatement preparedStatement = null;
 
 1955         ResultSet resultSet = null;
 
 1956         String sql = 
"SELECT count(*) FROM %s WHERE value=? AND reference_set_id=?";
 
 1961             preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
 
 1962             preparedStatement.setString(1, normalizeValued);
 
 1963             preparedStatement.setInt(2, referenceSetID);
 
 1964             resultSet = preparedStatement.executeQuery();
 
 1966             matchingInstances = resultSet.getLong(1);
 
 1967         } 
catch (SQLException ex) {
 
 1968             throw new EamDbException(
"Error determining if value (" + normalizeValued + 
") is in reference set " + referenceSetID, ex); 
 
 1975         return 0 < matchingInstances;
 
 1997         Connection conn = connect();
 
 1999         Long badInstances = 0L;
 
 2000         PreparedStatement preparedStatement = null;
 
 2001         ResultSet resultSet = null;
 
 2002         String sql = 
"SELECT count(*) FROM %s WHERE value=? AND known_status=?";
 
 2006             preparedStatement.setString(1, normalizeValued);
 
 2007             preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
 
 2008             resultSet = preparedStatement.executeQuery();
 
 2010             badInstances = resultSet.getLong(1);
 
 2011         } 
catch (SQLException ex) {
 
 2012             throw new EamDbException(
"Error determining if artifact is notable by reference.", ex); 
 
 2019         return 0 < badInstances;
 
 2033             throw new EamDbException(
"Correlation type is null");
 
 2036         if (instanceTableCallback == null) {
 
 2037             throw new EamDbException(
"Callback interface is null");
 
 2040         Connection conn = connect();
 
 2041         PreparedStatement preparedStatement = null;
 
 2042         ResultSet resultSet = null;
 
 2044         StringBuilder sql = 
new StringBuilder();
 
 2045         sql.append(
"select * from ");
 
 2046         sql.append(tableName);
 
 2049             preparedStatement = conn.prepareStatement(sql.toString());
 
 2050             resultSet = preparedStatement.executeQuery();
 
 2051             instanceTableCallback.
process(resultSet);
 
 2052         } 
catch (SQLException ex) {
 
 2053             throw new EamDbException(
"Error getting all artifact instances from instances table", ex);
 
 2073             throw new EamDbException(
"Correlation type is null");
 
 2076         if (instanceTableCallback == null) {
 
 2077             throw new EamDbException(
"Callback interface is null");
 
 2080         if (whereClause == null) {
 
 2081             throw new EamDbException(
"Where clause is null");
 
 2084         Connection conn = connect();
 
 2085         PreparedStatement preparedStatement = null;
 
 2086         ResultSet resultSet = null;
 
 2088         StringBuilder sql = 
new StringBuilder(300);
 
 2089         sql.append(
"select * from ")
 
 2092                 .append(whereClause);
 
 2095             preparedStatement = conn.prepareStatement(sql.toString());
 
 2096             resultSet = preparedStatement.executeQuery();
 
 2097             instanceTableCallback.
process(resultSet);
 
 2098         } 
catch (SQLException ex) {
 
 2099             throw new EamDbException(
"Error getting all artifact instances from instances table", ex);
 
 2109         if (eamOrg == null) {
 
 2110             throw new EamDbException(
"EamOrganization is null");
 
 2111         } 
else if (eamOrg.
getOrgID() != -1) {
 
 2112             throw new EamDbException(
"EamOrganization already has an ID");
 
 2115         Connection conn = connect();
 
 2116         ResultSet generatedKeys = null;
 
 2117         PreparedStatement preparedStatement = null;
 
 2118         String sql = 
"INSERT INTO organizations(org_name, poc_name, poc_email, poc_phone) VALUES (?, ?, ?, ?) " 
 2119                 + getConflictClause();
 
 2122             preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
 
 2123             preparedStatement.setString(1, eamOrg.
getName());
 
 2124             preparedStatement.setString(2, eamOrg.
getPocName());
 
 2125             preparedStatement.setString(3, eamOrg.
getPocEmail());
 
 2126             preparedStatement.setString(4, eamOrg.
getPocPhone());
 
 2128             preparedStatement.executeUpdate();
 
 2129             generatedKeys = preparedStatement.getGeneratedKeys();
 
 2130             if (generatedKeys.next()) {
 
 2131                 eamOrg.setOrgID((
int) generatedKeys.getLong(1));
 
 2134                 throw new SQLException(
"Creating user failed, no ID obtained.");
 
 2136         } 
catch (SQLException ex) {
 
 2137             throw new EamDbException(
"Error inserting new organization.", ex); 
 
 2153     public List<EamOrganization> getOrganizations() 
throws EamDbException {
 
 2154         Connection conn = connect();
 
 2156         List<EamOrganization> orgs = 
new ArrayList<>();
 
 2157         PreparedStatement preparedStatement = null;
 
 2158         ResultSet resultSet = null;
 
 2159         String sql = 
"SELECT * FROM organizations";
 
 2162             preparedStatement = conn.prepareStatement(sql);
 
 2163             resultSet = preparedStatement.executeQuery();
 
 2164             while (resultSet.next()) {
 
 2165                 orgs.add(getEamOrganizationFromResultSet(resultSet));
 
 2169         } 
catch (SQLException ex) {
 
 2170             throw new EamDbException(
"Error getting all organizations.", ex); 
 
 2188     public EamOrganization getOrganizationByID(
int orgID) 
throws EamDbException {
 
 2189         Connection conn = connect();
 
 2191         PreparedStatement preparedStatement = null;
 
 2192         ResultSet resultSet = null;
 
 2193         String sql = 
"SELECT * FROM organizations WHERE id=?";
 
 2196             preparedStatement = conn.prepareStatement(sql);
 
 2197             preparedStatement.setInt(1, orgID);
 
 2198             resultSet = preparedStatement.executeQuery();
 
 2200             return getEamOrganizationFromResultSet(resultSet);
 
 2202         } 
catch (SQLException ex) {
 
 2203             throw new EamDbException(
"Error getting organization by id.", ex); 
 
 2221     public EamOrganization getReferenceSetOrganization(
int referenceSetID) 
throws EamDbException {
 
 2223         EamGlobalSet globalSet = getReferenceSetByID(referenceSetID);
 
 2224         if (globalSet == null) {
 
 2225             throw new EamDbException(
"Reference set with ID " + referenceSetID + 
" not found");
 
 2227         return (getOrganizationByID(globalSet.
getOrgID()));
 
 2239             throw new EamDbException(
"EamOrganization is null");
 
 2241             throw new EamDbException(
"Organization  has -1 row ID");
 
 2254     public void updateOrganization(
EamOrganization updatedOrganization) 
throws EamDbException {
 
 2255         testArgument(updatedOrganization);
 
 2257         Connection conn = connect();
 
 2258         PreparedStatement preparedStatement = null;
 
 2259         String sql = 
"UPDATE organizations SET org_name = ?, poc_name = ?, poc_email = ?, poc_phone = ? WHERE id = ?";
 
 2261             preparedStatement = conn.prepareStatement(sql);
 
 2262             preparedStatement.setString(1, updatedOrganization.
getName());
 
 2263             preparedStatement.setString(2, updatedOrganization.
getPocName());
 
 2264             preparedStatement.setString(3, updatedOrganization.
getPocEmail());
 
 2265             preparedStatement.setString(4, updatedOrganization.
getPocPhone());
 
 2266             preparedStatement.setInt(5, updatedOrganization.
getOrgID());
 
 2267             preparedStatement.executeUpdate();
 
 2268         } 
catch (SQLException ex) {
 
 2269             throw new EamDbException(
"Error updating organization.", ex); 
 
 2277     public void deleteOrganization(
EamOrganization organizationToDelete) 
throws EamDbException {
 
 2278         testArgument(organizationToDelete);
 
 2280         Connection conn = connect();
 
 2281         PreparedStatement checkIfUsedStatement = null;
 
 2282         ResultSet resultSet = null;
 
 2283         String checkIfUsedSql = 
"SELECT (select count(*) FROM cases WHERE org_id=?) + (select count(*) FROM reference_sets WHERE org_id=?)";
 
 2284         PreparedStatement deleteOrgStatement = null;
 
 2285         String deleteOrgSql = 
"DELETE FROM organizations WHERE id=?";
 
 2287             checkIfUsedStatement = conn.prepareStatement(checkIfUsedSql);
 
 2288             checkIfUsedStatement.setInt(1, organizationToDelete.
getOrgID());
 
 2289             checkIfUsedStatement.setInt(2, organizationToDelete.
getOrgID());
 
 2290             resultSet = checkIfUsedStatement.executeQuery();
 
 2292             if (resultSet.getLong(1) > 0) {
 
 2293                 throw new EamDbException(
"Can not delete organization which is currently in use by a case or reference set in the central repository.");
 
 2295             deleteOrgStatement = conn.prepareStatement(deleteOrgSql);
 
 2296             deleteOrgStatement.setInt(1, organizationToDelete.
getOrgID());
 
 2297             deleteOrgStatement.executeUpdate();
 
 2298         } 
catch (SQLException ex) {
 
 2299             throw new EamDbException(
"Error executing query when attempting to delete organization by id.", ex); 
 
 2318     public int newReferenceSet(
EamGlobalSet eamGlobalSet) 
throws EamDbException {
 
 2319         if (eamGlobalSet == null) {
 
 2320             throw new EamDbException(
"EamGlobalSet is null");
 
 2324             throw new EamDbException(
"File known status on the EamGlobalSet is null");
 
 2327         if (eamGlobalSet.
getType() == null) {
 
 2328             throw new EamDbException(
"Type on the EamGlobalSet is null");
 
 2331         Connection conn = connect();
 
 2333         PreparedStatement preparedStatement1 = null;
 
 2334         PreparedStatement preparedStatement2 = null;
 
 2335         ResultSet resultSet = null;
 
 2336         String sql1 = 
"INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, type, import_date) VALUES (?, ?, ?, ?, ?, ?, ?) " 
 2337                 + getConflictClause();
 
 2338         String sql2 = 
"SELECT id FROM reference_sets WHERE org_id=? AND set_name=? AND version=? AND import_date=? LIMIT 1";
 
 2341             preparedStatement1 = conn.prepareStatement(sql1);
 
 2342             preparedStatement1.setInt(1, eamGlobalSet.
getOrgID());
 
 2343             preparedStatement1.setString(2, eamGlobalSet.
getSetName());
 
 2344             preparedStatement1.setString(3, eamGlobalSet.
getVersion());
 
 2346             preparedStatement1.setBoolean(5, eamGlobalSet.
isReadOnly());
 
 2347             preparedStatement1.setInt(6, eamGlobalSet.
getType().getId());
 
 2348             preparedStatement1.setString(7, eamGlobalSet.
getImportDate().toString());
 
 2350             preparedStatement1.executeUpdate();
 
 2352             preparedStatement2 = conn.prepareStatement(sql2);
 
 2353             preparedStatement2.setInt(1, eamGlobalSet.
getOrgID());
 
 2354             preparedStatement2.setString(2, eamGlobalSet.
getSetName());
 
 2355             preparedStatement2.setString(3, eamGlobalSet.
getVersion());
 
 2356             preparedStatement2.setString(4, eamGlobalSet.
getImportDate().toString());
 
 2358             resultSet = preparedStatement2.executeQuery();
 
 2360             return resultSet.getInt(
"id");
 
 2362         } 
catch (SQLException ex) {
 
 2363             throw new EamDbException(
"Error inserting new global set.", ex); 
 
 2382     public EamGlobalSet getReferenceSetByID(
int referenceSetID) 
throws EamDbException {
 
 2383         Connection conn = connect();
 
 2385         PreparedStatement preparedStatement1 = null;
 
 2386         ResultSet resultSet = null;
 
 2387         String sql1 = 
"SELECT * FROM reference_sets WHERE id=?";
 
 2390             preparedStatement1 = conn.prepareStatement(sql1);
 
 2391             preparedStatement1.setInt(1, referenceSetID);
 
 2392             resultSet = preparedStatement1.executeQuery();
 
 2393             if (resultSet.next()) {
 
 2394                 return getEamGlobalSetFromResultSet(resultSet);
 
 2399         } 
catch (SQLException ex) {
 
 2400             throw new EamDbException(
"Error getting reference set by id.", ex); 
 
 2420         if (correlationType == null) {
 
 2421             throw new EamDbException(
"Correlation type is null");
 
 2424         List<EamGlobalSet> results = 
new ArrayList<>();
 
 2425         Connection conn = connect();
 
 2427         PreparedStatement preparedStatement1 = null;
 
 2428         ResultSet resultSet = null;
 
 2429         String sql1 = 
"SELECT * FROM reference_sets WHERE type=" + correlationType.getId();
 
 2432             preparedStatement1 = conn.prepareStatement(sql1);
 
 2433             resultSet = preparedStatement1.executeQuery();
 
 2434             while (resultSet.next()) {
 
 2435                 results.add(getEamGlobalSetFromResultSet(resultSet));
 
 2438         } 
catch (SQLException ex) {
 
 2439             throw new EamDbException(
"Error getting reference sets.", ex); 
 
 2460             throw new EamDbException(
"Known status of EamGlobalFileInstance is null");
 
 2462         if (correlationType == null) {
 
 2463             throw new EamDbException(
"Correlation type is null");
 
 2466         Connection conn = connect();
 
 2468         PreparedStatement preparedStatement = null;
 
 2470         String sql = 
"INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) " 
 2471                 + getConflictClause();
 
 2475             preparedStatement.setInt(1, eamGlobalFileInstance.
getGlobalSetID());
 
 2476             preparedStatement.setString(2, eamGlobalFileInstance.
getMD5Hash());
 
 2477             preparedStatement.setByte(3, eamGlobalFileInstance.
getKnownStatus().getFileKnownValue());
 
 2478             preparedStatement.setString(4, eamGlobalFileInstance.
getComment());
 
 2479             preparedStatement.executeUpdate();
 
 2480         } 
catch (SQLException ex) {
 
 2481             throw new EamDbException(
"Error inserting new reference instance into reference_ table.", ex); 
 
 2501     public boolean referenceSetExists(String referenceSetName, String version) 
throws EamDbException {
 
 2502         Connection conn = connect();
 
 2504         PreparedStatement preparedStatement1 = null;
 
 2505         ResultSet resultSet = null;
 
 2506         String sql1 = 
"SELECT * FROM reference_sets WHERE set_name=? AND version=?";
 
 2509             preparedStatement1 = conn.prepareStatement(sql1);
 
 2510             preparedStatement1.setString(1, referenceSetName);
 
 2511             preparedStatement1.setString(2, version);
 
 2512             resultSet = preparedStatement1.executeQuery();
 
 2513             return (resultSet.next());
 
 2515         } 
catch (SQLException ex) {
 
 2516             throw new EamDbException(
"Error testing whether reference set exists (name: " + referenceSetName
 
 2517                     + 
" version: " + version, ex); 
 
 2531     public void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances, 
CorrelationAttributeInstance.
Type contentType) 
throws EamDbException {
 
 2532         if (contentType == null) {
 
 2533             throw new EamDbException(
"Correlation type is null");
 
 2535         if (globalInstances == null) {
 
 2536             throw new EamDbException(
"Null set of EamGlobalFileInstance");
 
 2539         Connection conn = connect();
 
 2541         PreparedStatement bulkPs = null;
 
 2543             conn.setAutoCommit(
false);
 
 2546             String sql = 
"INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) " 
 2547                     + getConflictClause();
 
 2552                 if (globalInstance.getKnownStatus() == null) {
 
 2553                     throw new EamDbException(
"EamGlobalFileInstance with value " + globalInstance.getMD5Hash() + 
" has null known status");
 
 2556                 bulkPs.setInt(1, globalInstance.getGlobalSetID());
 
 2557                 bulkPs.setString(2, globalInstance.getMD5Hash());
 
 2558                 bulkPs.setByte(3, globalInstance.getKnownStatus().getFileKnownValue());
 
 2559                 bulkPs.setString(4, globalInstance.getComment());
 
 2563             bulkPs.executeBatch();
 
 2565         } 
catch (SQLException | EamDbException ex) {
 
 2568             } 
catch (SQLException ex2) {
 
 2571             throw new EamDbException(
"Error inserting bulk artifacts.", ex); 
 
 2592         Connection conn = connect();
 
 2594         List<EamGlobalFileInstance> globalFileInstances = 
new ArrayList<>();
 
 2595         PreparedStatement preparedStatement1 = null;
 
 2596         ResultSet resultSet = null;
 
 2597         String sql1 = 
"SELECT * FROM %s WHERE value=?";
 
 2601             preparedStatement1.setString(1, normalizeValued);
 
 2602             resultSet = preparedStatement1.executeQuery();
 
 2603             while (resultSet.next()) {
 
 2604                 globalFileInstances.add(getEamGlobalFileInstanceFromResultSet(resultSet));
 
 2607         } 
catch (SQLException ex) {
 
 2608             throw new EamDbException(
"Error getting reference instances by type and value.", ex); 
 
 2615         return globalFileInstances;
 
 2629         if (newType == null) {
 
 2630             throw new EamDbException(
"Correlation type is null");
 
 2633         if (-1 == newType.getId()) {
 
 2634             typeId = newCorrelationTypeNotKnownId(newType);
 
 2636             typeId = newCorrelationTypeKnownId(newType);
 
 2653         Connection conn = connect();
 
 2655         PreparedStatement preparedStatement = null;
 
 2656         PreparedStatement preparedStatementQuery = null;
 
 2657         ResultSet resultSet = null;
 
 2662         insertSql = 
"INSERT INTO correlation_types(display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?) " + getConflictClause();
 
 2664         querySql = 
"SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
 
 2667             preparedStatement = conn.prepareStatement(insertSql);
 
 2669             preparedStatement.setString(1, newType.getDisplayName());
 
 2670             preparedStatement.setString(2, newType.getDbTableName());
 
 2671             preparedStatement.setInt(3, newType.isSupported() ? 1 : 0);
 
 2672             preparedStatement.setInt(4, newType.isEnabled() ? 1 : 0);
 
 2674             preparedStatement.executeUpdate();
 
 2676             preparedStatementQuery = conn.prepareStatement(querySql);
 
 2677             preparedStatementQuery.setString(1, newType.getDisplayName());
 
 2678             preparedStatementQuery.setString(2, newType.getDbTableName());
 
 2680             resultSet = preparedStatementQuery.executeQuery();
 
 2681             if (resultSet.next()) {
 
 2683                 typeId = correlationType.getId();
 
 2685         } 
catch (SQLException ex) {
 
 2686             throw new EamDbException(
"Error inserting new correlation type.", ex); 
 
 2706         Connection conn = connect();
 
 2708         PreparedStatement preparedStatement = null;
 
 2709         PreparedStatement preparedStatementQuery = null;
 
 2710         ResultSet resultSet = null;
 
 2715         insertSql = 
"INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause();
 
 2717         querySql = 
"SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
 
 2720             preparedStatement = conn.prepareStatement(insertSql);
 
 2722             preparedStatement.setInt(1, newType.getId());
 
 2723             preparedStatement.setString(2, newType.getDisplayName());
 
 2724             preparedStatement.setString(3, newType.getDbTableName());
 
 2725             preparedStatement.setInt(4, newType.isSupported() ? 1 : 0);
 
 2726             preparedStatement.setInt(5, newType.isEnabled() ? 1 : 0);
 
 2728             preparedStatement.executeUpdate();
 
 2730             preparedStatementQuery = conn.prepareStatement(querySql);
 
 2731             preparedStatementQuery.setString(1, newType.getDisplayName());
 
 2732             preparedStatementQuery.setString(2, newType.getDbTableName());
 
 2734             resultSet = preparedStatementQuery.executeQuery();
 
 2735             if (resultSet.next()) {
 
 2737                 typeId = correlationType.getId();
 
 2739         } 
catch (SQLException ex) {
 
 2740             throw new EamDbException(
"Error inserting new correlation type.", ex); 
 
 2752         Connection conn = connect();
 
 2755         PreparedStatement preparedStatement = null;
 
 2756         ResultSet resultSet = null;
 
 2757         String sql = 
"SELECT * FROM correlation_types";
 
 2760             preparedStatement = conn.prepareStatement(sql);
 
 2761             resultSet = preparedStatement.executeQuery();
 
 2762             while (resultSet.next()) {
 
 2763                 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
 
 2767         } 
catch (SQLException ex) {
 
 2768             throw new EamDbException(
"Error getting all correlation types.", ex); 
 
 2787         Connection conn = connect();
 
 2790         PreparedStatement preparedStatement = null;
 
 2791         ResultSet resultSet = null;
 
 2792         String sql = 
"SELECT * FROM correlation_types WHERE enabled=1";
 
 2795             preparedStatement = conn.prepareStatement(sql);
 
 2796             resultSet = preparedStatement.executeQuery();
 
 2797             while (resultSet.next()) {
 
 2798                 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
 
 2802         } 
catch (SQLException ex) {
 
 2803             throw new EamDbException(
"Error getting enabled correlation types.", ex); 
 
 2822         Connection conn = connect();
 
 2825         PreparedStatement preparedStatement = null;
 
 2826         ResultSet resultSet = null;
 
 2827         String sql = 
"SELECT * FROM correlation_types WHERE supported=1";
 
 2830             preparedStatement = conn.prepareStatement(sql);
 
 2831             resultSet = preparedStatement.executeQuery();
 
 2832             while (resultSet.next()) {
 
 2833                 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
 
 2837         } 
catch (SQLException ex) {
 
 2838             throw new EamDbException(
"Error getting supported correlation types.", ex); 
 
 2855         Connection conn = connect();
 
 2857         PreparedStatement preparedStatement = null;
 
 2858         String sql = 
"UPDATE correlation_types SET display_name=?, db_table_name=?, supported=?, enabled=? WHERE id=?";
 
 2861             preparedStatement = conn.prepareStatement(sql);
 
 2862             preparedStatement.setString(1, aType.getDisplayName());
 
 2863             preparedStatement.setString(2, aType.getDbTableName());
 
 2864             preparedStatement.setInt(3, aType.isSupported() ? 1 : 0);
 
 2865             preparedStatement.setInt(4, aType.isEnabled() ? 1 : 0);
 
 2866             preparedStatement.setInt(5, aType.getId());
 
 2867             preparedStatement.executeUpdate();
 
 2868             typeCache.put(aType.getId(), aType);
 
 2869         } 
catch (SQLException ex) {
 
 2870             throw new EamDbException(
"Error updating correlation type.", ex); 
 
 2890             return typeCache.get(typeId, () -> getCorrelationTypeByIdFromCr(typeId));
 
 2891         } 
catch (CacheLoader.InvalidCacheLoadException ignored) {
 
 2894         } 
catch (ExecutionException ex) {
 
 2895             throw new EamDbException(
"Error getting correlation type", ex);
 
 2909         Connection conn = connect();
 
 2912         PreparedStatement preparedStatement = null;
 
 2913         ResultSet resultSet = null;
 
 2914         String sql = 
"SELECT * FROM correlation_types WHERE id=?";
 
 2917             preparedStatement = conn.prepareStatement(sql);
 
 2918             preparedStatement.setInt(1, typeId);
 
 2919             resultSet = preparedStatement.executeQuery();
 
 2920             if (resultSet.next()) {
 
 2921                 aType = getCorrelationTypeFromResultSet(resultSet);
 
 2924                 throw new EamDbException(
"Failed to find entry for correlation type ID = " + typeId);
 
 2927         } 
catch (SQLException ex) {
 
 2928             throw new EamDbException(
"Error getting correlation type by id.", ex); 
 
 2946     private CorrelationCase getEamCaseFromResultSet(ResultSet resultSet) 
throws SQLException {
 
 2947         if (null == resultSet) {
 
 2953         resultSet.getInt(
"org_id");
 
 2954         if (!resultSet.wasNull()) {
 
 2957                     resultSet.getString(
"org_name"),
 
 2958                     resultSet.getString(
"poc_name"),
 
 2959                     resultSet.getString(
"poc_email"),
 
 2960                     resultSet.getString(
"poc_phone"));
 
 2970         eamCase.
setNotes(resultSet.getString(
"notes"));
 
 2975     private CorrelationDataSource getEamDataSourceFromResultSet(ResultSet resultSet) 
throws SQLException {
 
 2976         if (null == resultSet) {
 
 2981                 resultSet.getInt(
"case_id"),
 
 2982                 resultSet.getInt(
"id"),
 
 2983                 resultSet.getString(
"device_id"),
 
 2984                 resultSet.getString(
"name")
 
 2987         return eamDataSource;
 
 2991         if (null == resultSet) {
 
 2996                 resultSet.getInt(
"id"),
 
 2997                 resultSet.getString(
"display_name"),
 
 2998                 resultSet.getString(
"db_table_name"),
 
 2999                 resultSet.getBoolean(
"supported"),
 
 3000                 resultSet.getBoolean(
"enabled")
 
 3003         return eamArtifactType;
 
 3017         if (null == resultSet) {
 
 3023                 resultSet.getString(
"value"),
 
 3024                 resultSet.getInt(
"id"),
 
 3025                 new CorrelationCase(resultSet.getInt(
"case_id"), resultSet.getString(
"case_uid"), resultSet.getString(
"case_name")),
 
 3026                 new CorrelationDataSource(resultSet.getInt(
"case_id"), resultSet.getInt(
"data_source_id"), resultSet.getString(
"device_id"), resultSet.getString(
"name")),
 
 3027                 resultSet.getString(
"file_path"),
 
 3028                 resultSet.getString(
"comment"),
 
 3029                 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status"))
 
 3033     private EamOrganization getEamOrganizationFromResultSet(ResultSet resultSet) 
throws SQLException {
 
 3034         if (null == resultSet) {
 
 3039                 resultSet.getInt(
"id"),
 
 3040                 resultSet.getString(
"org_name"),
 
 3041                 resultSet.getString(
"poc_name"),
 
 3042                 resultSet.getString(
"poc_email"),
 
 3043                 resultSet.getString(
"poc_phone")
 
 3047     private EamGlobalSet getEamGlobalSetFromResultSet(ResultSet resultSet) 
throws SQLException, EamDbException {
 
 3048         if (null == resultSet) {
 
 3053                 resultSet.getInt(
"id"),
 
 3054                 resultSet.getInt(
"org_id"),
 
 3055                 resultSet.getString(
"set_name"),
 
 3056                 resultSet.getString(
"version"),
 
 3057                 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
 
 3058                 resultSet.getBoolean(
"read_only"),
 
 3060                 LocalDate.parse(resultSet.getString(
"import_date"))
 
 3065         if (null == resultSet) {
 
 3070                 resultSet.getInt(
"id"),
 
 3071                 resultSet.getInt(
"reference_set_id"),
 
 3072                 resultSet.getString(
"value"),
 
 3073                 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
 
 3074                 resultSet.getString(
"comment")
 
 3084     public void upgradeSchema() 
throws EamDbException, SQLException {
 
 3086         ResultSet resultSet = null;
 
 3087         Statement statement = null;
 
 3088         Connection conn = null;
 
 3092             conn.setAutoCommit(
false);
 
 3093             statement = conn.createStatement();
 
 3095             int minorVersion = 0;
 
 3096             resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name='SCHEMA_MINOR_VERSION'");
 
 3097             if (resultSet.next()) {
 
 3098                 String minorVersionStr = resultSet.getString(
"value");
 
 3100                     minorVersion = Integer.parseInt(minorVersionStr);
 
 3101                 } 
catch (NumberFormatException ex) {
 
 3102                     throw new EamDbException(
"Bad value for schema minor version (" + minorVersionStr + 
") - database is corrupt", ex);
 
 3106             int majorVersion = 0;
 
 3107             resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name='SCHEMA_VERSION'");
 
 3108             if (resultSet.next()) {
 
 3109                 String majorVersionStr = resultSet.getString(
"value");
 
 3111                     majorVersion = Integer.parseInt(majorVersionStr);
 
 3112                 } 
catch (NumberFormatException ex) {
 
 3113                     throw new EamDbException(
"Bad value for schema version (" + majorVersionStr + 
") - database is corrupt", ex);
 
 3117             CaseDbSchemaVersionNumber dbSchemaVersion = 
new CaseDbSchemaVersionNumber(majorVersion, minorVersion);
 
 3118             if (dbSchemaVersion.equals(CURRENT_DB_SCHEMA_VERSION)) {
 
 3119                 logger.log(Level.INFO, 
"Central Repository is up to date");
 
 3124             if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 1)) < 0) {
 
 3125                 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN known_status INTEGER;"); 
 
 3126                 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN read_only BOOLEAN;"); 
 
 3127                 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN type INTEGER;"); 
 
 3132                 EamDbUtil.insertDefaultOrganization(conn);
 
 3135             if (!updateSchemaVersion(conn)) {
 
 3136                 throw new EamDbException(
"Error updating schema version");
 
 3140             logger.log(Level.INFO, 
"Central Repository upgraded to version " + CURRENT_DB_SCHEMA_VERSION);
 
 3141         } 
catch (SQLException | EamDbException ex) {
 
 3146             } 
catch (SQLException ex2) {
 
 3147                 logger.log(Level.SEVERE, 
"Database rollback failed", ex2);
 
TskData.FileKnown getKnownStatus()
 
String getExaminerPhone()
 
CorrelationAttributeInstance.Type getType()
 
static String correlationTypeToInstanceTableName(CorrelationAttributeInstance.Type type)
 
void setCreationDate(String creationDate)
 
static void closeResultSet(ResultSet resultSet)
 
static void closeStatement(Statement statement)
 
static List< CorrelationAttributeInstance.Type > getDefaultCorrelationTypes()
 
String getCorrelationValue()
 
void setExaminerPhone(String examinerPhone)
 
void setExaminerName(String examinerName)
 
void setCaseNumber(String caseNumber)
 
static TimingMetric getTimingMetric(String name)
 
TskData.FileKnown getKnownStatus()
 
void process(ResultSet resultSet)
 
Type getCorrelationType()
 
void setOrg(EamOrganization org)
 
static String normalize(CorrelationAttributeInstance.Type attributeType, String data)
 
static EamDb getInstance()
 
void setNotes(String notes)
 
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 void submitTimingMetric(TimingMetric metric)
 
synchronized static Logger getLogger(String name)
 
CorrelationCase getCorrelationCase()
 
static String correlationTypeToReferenceTableName(CorrelationAttributeInstance.Type type)
 
static EamOrganization getDefault()
 
void setExaminerEmail(String examinerEmail)
 
static final int FILES_TYPE_ID
 
String getExaminerEmail()