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());
1958 public List<String> getListCasesHavingArtifactInstances(
CorrelationAttributeInstance.
Type aType, String value)
throws EamDbException, CorrelationAttributeNormalizationException {
1962 Connection conn = connect();
1964 Collection<String> caseNames =
new LinkedHashSet<>();
1966 PreparedStatement preparedStatement = null;
1967 ResultSet resultSet = null;
1971 =
"SELECT DISTINCT case_name FROM "
1973 +
" INNER JOIN cases ON "
1975 +
".case_id=cases.id WHERE "
1980 preparedStatement = conn.prepareStatement(sql);
1981 preparedStatement.setString(1, normalizedValue);
1982 resultSet = preparedStatement.executeQuery();
1983 while (resultSet.next()) {
1984 caseNames.add(resultSet.getString(
"case_name"));
1986 }
catch (SQLException ex) {
1987 throw new EamDbException(
"Error getting notable artifact instances.", ex);
1994 return caseNames.stream().collect(Collectors.toList());
2005 public void deleteReferenceSet(
int referenceSetID)
throws EamDbException {
2006 deleteReferenceSetEntries(referenceSetID);
2007 deleteReferenceSetEntry(referenceSetID);
2017 private void deleteReferenceSetEntry(
int referenceSetID)
throws EamDbException {
2018 Connection conn = connect();
2020 PreparedStatement preparedStatement = null;
2021 String sql =
"DELETE FROM reference_sets WHERE id=?";
2024 preparedStatement = conn.prepareStatement(sql);
2025 preparedStatement.setInt(1, referenceSetID);
2026 preparedStatement.executeUpdate();
2027 }
catch (SQLException ex) {
2028 throw new EamDbException(
"Error deleting reference set " + referenceSetID, ex);
2043 private void deleteReferenceSetEntries(
int referenceSetID)
throws EamDbException {
2044 Connection conn = connect();
2046 PreparedStatement preparedStatement = null;
2047 String sql =
"DELETE FROM %s WHERE reference_set_id=?";
2053 preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
2054 preparedStatement.setInt(1, referenceSetID);
2055 preparedStatement.executeUpdate();
2056 }
catch (SQLException ex) {
2057 throw new EamDbException(
"Error deleting files from reference set " + referenceSetID, ex);
2078 public boolean referenceSetIsValid(
int referenceSetID, String setName, String version)
throws EamDbException {
2079 EamGlobalSet refSet = this.getReferenceSetByID(referenceSetID);
2080 if (refSet == null) {
2099 public boolean isFileHashInReferenceSet(String hash,
int referenceSetID)
throws EamDbException, CorrelationAttributeNormalizationException {
2113 public boolean isValueInReferenceSet(String value,
int referenceSetID,
int correlationTypeID)
throws EamDbException, CorrelationAttributeNormalizationException {
2117 Connection conn = connect();
2119 Long matchingInstances = 0L;
2120 PreparedStatement preparedStatement = null;
2121 ResultSet resultSet = null;
2122 String sql =
"SELECT count(*) FROM %s WHERE value=? AND reference_set_id=?";
2127 preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
2128 preparedStatement.setString(1, normalizeValued);
2129 preparedStatement.setInt(2, referenceSetID);
2130 resultSet = preparedStatement.executeQuery();
2132 matchingInstances = resultSet.getLong(1);
2133 }
catch (SQLException ex) {
2134 throw new EamDbException(
"Error determining if value (" + normalizeValued +
") is in reference set " + referenceSetID, ex);
2141 return 0 < matchingInstances;
2153 public boolean isArtifactKnownBadByReference(
CorrelationAttributeInstance.
Type aType, String value)
throws EamDbException, CorrelationAttributeNormalizationException {
2163 Connection conn = connect();
2165 Long badInstances = 0L;
2166 PreparedStatement preparedStatement = null;
2167 ResultSet resultSet = null;
2168 String sql =
"SELECT count(*) FROM %s WHERE value=? AND known_status=?";
2172 preparedStatement.setString(1, normalizeValued);
2173 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
2174 resultSet = preparedStatement.executeQuery();
2176 badInstances = resultSet.getLong(1);
2177 }
catch (SQLException ex) {
2178 throw new EamDbException(
"Error determining if artifact is notable by reference.", ex);
2185 return 0 < badInstances;
2199 throw new EamDbException(
"Correlation type is null");
2202 if (instanceTableCallback == null) {
2203 throw new EamDbException(
"Callback interface is null");
2206 Connection conn = connect();
2207 PreparedStatement preparedStatement = null;
2208 ResultSet resultSet = null;
2210 StringBuilder sql =
new StringBuilder();
2211 sql.append(
"select * from ");
2212 sql.append(tableName);
2215 preparedStatement = conn.prepareStatement(sql.toString());
2216 resultSet = preparedStatement.executeQuery();
2217 instanceTableCallback.
process(resultSet);
2218 }
catch (SQLException ex) {
2219 throw new EamDbException(
"Error getting all artifact instances from instances table", ex);
2239 throw new EamDbException(
"Correlation type is null");
2242 if (instanceTableCallback == null) {
2243 throw new EamDbException(
"Callback interface is null");
2246 if (whereClause == null) {
2247 throw new EamDbException(
"Where clause is null");
2250 Connection conn = connect();
2251 PreparedStatement preparedStatement = null;
2252 ResultSet resultSet = null;
2254 StringBuilder sql =
new StringBuilder(300);
2255 sql.append(
"select * from ")
2258 .append(whereClause);
2261 preparedStatement = conn.prepareStatement(sql.toString());
2262 resultSet = preparedStatement.executeQuery();
2263 instanceTableCallback.
process(resultSet);
2264 }
catch (SQLException ex) {
2265 throw new EamDbException(
"Error getting all artifact instances from instances table", ex);
2282 public void processSelectClause(String selectClause,
InstanceTableCallback instanceTableCallback)
throws EamDbException {
2284 if (instanceTableCallback == null) {
2285 throw new EamDbException(
"Callback interface is null");
2288 if (selectClause == null) {
2289 throw new EamDbException(
"Select clause is null");
2292 Connection conn = connect();
2293 PreparedStatement preparedStatement = null;
2294 ResultSet resultSet = null;
2295 StringBuilder sql =
new StringBuilder(300);
2296 sql.append(
"select ")
2297 .append(selectClause);
2300 preparedStatement = conn.prepareStatement(sql.toString());
2301 resultSet = preparedStatement.executeQuery();
2302 instanceTableCallback.
process(resultSet);
2303 }
catch (SQLException ex) {
2304 throw new EamDbException(
"Error running query", ex);
2314 if (eamOrg == null) {
2315 throw new EamDbException(
"EamOrganization is null");
2316 }
else if (eamOrg.
getOrgID() != -1) {
2317 throw new EamDbException(
"EamOrganization already has an ID");
2320 Connection conn = connect();
2321 ResultSet generatedKeys = null;
2322 PreparedStatement preparedStatement = null;
2323 String sql =
"INSERT INTO organizations(org_name, poc_name, poc_email, poc_phone) VALUES (?, ?, ?, ?) "
2324 + getConflictClause();
2327 preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
2328 preparedStatement.setString(1, eamOrg.
getName());
2329 preparedStatement.setString(2, eamOrg.
getPocName());
2330 preparedStatement.setString(3, eamOrg.
getPocEmail());
2331 preparedStatement.setString(4, eamOrg.
getPocPhone());
2333 preparedStatement.executeUpdate();
2334 generatedKeys = preparedStatement.getGeneratedKeys();
2335 if (generatedKeys.next()) {
2336 eamOrg.setOrgID((
int) generatedKeys.getLong(1));
2339 throw new SQLException(
"Creating user failed, no ID obtained.");
2341 }
catch (SQLException ex) {
2342 throw new EamDbException(
"Error inserting new organization.", ex);
2358 public List<EamOrganization> getOrganizations()
throws EamDbException {
2359 Connection conn = connect();
2361 List<EamOrganization> orgs =
new ArrayList<>();
2362 PreparedStatement preparedStatement = null;
2363 ResultSet resultSet = null;
2364 String sql =
"SELECT * FROM organizations";
2367 preparedStatement = conn.prepareStatement(sql);
2368 resultSet = preparedStatement.executeQuery();
2369 while (resultSet.next()) {
2370 orgs.add(getEamOrganizationFromResultSet(resultSet));
2374 }
catch (SQLException ex) {
2375 throw new EamDbException(
"Error getting all organizations.", ex);
2393 public EamOrganization getOrganizationByID(
int orgID)
throws EamDbException {
2394 Connection conn = connect();
2396 PreparedStatement preparedStatement = null;
2397 ResultSet resultSet = null;
2398 String sql =
"SELECT * FROM organizations WHERE id=?";
2401 preparedStatement = conn.prepareStatement(sql);
2402 preparedStatement.setInt(1, orgID);
2403 resultSet = preparedStatement.executeQuery();
2405 return getEamOrganizationFromResultSet(resultSet);
2407 }
catch (SQLException ex) {
2408 throw new EamDbException(
"Error getting organization by id.", ex);
2426 public EamOrganization getReferenceSetOrganization(
int referenceSetID)
throws EamDbException {
2428 EamGlobalSet globalSet = getReferenceSetByID(referenceSetID);
2429 if (globalSet == null) {
2430 throw new EamDbException(
"Reference set with ID " + referenceSetID +
" not found");
2432 return (getOrganizationByID(globalSet.
getOrgID()));
2444 throw new EamDbException(
"EamOrganization is null");
2446 throw new EamDbException(
"Organization has -1 row ID");
2459 public void updateOrganization(
EamOrganization updatedOrganization)
throws EamDbException {
2460 testArgument(updatedOrganization);
2462 Connection conn = connect();
2463 PreparedStatement preparedStatement = null;
2464 String sql =
"UPDATE organizations SET org_name = ?, poc_name = ?, poc_email = ?, poc_phone = ? WHERE id = ?";
2466 preparedStatement = conn.prepareStatement(sql);
2467 preparedStatement.setString(1, updatedOrganization.
getName());
2468 preparedStatement.setString(2, updatedOrganization.
getPocName());
2469 preparedStatement.setString(3, updatedOrganization.
getPocEmail());
2470 preparedStatement.setString(4, updatedOrganization.
getPocPhone());
2471 preparedStatement.setInt(5, updatedOrganization.
getOrgID());
2472 preparedStatement.executeUpdate();
2473 }
catch (SQLException ex) {
2474 throw new EamDbException(
"Error updating organization.", ex);
2482 public void deleteOrganization(
EamOrganization organizationToDelete)
throws EamDbException {
2483 testArgument(organizationToDelete);
2485 Connection conn = connect();
2486 PreparedStatement checkIfUsedStatement = null;
2487 ResultSet resultSet = null;
2488 String checkIfUsedSql =
"SELECT (select count(*) FROM cases WHERE org_id=?) + (select count(*) FROM reference_sets WHERE org_id=?)";
2489 PreparedStatement deleteOrgStatement = null;
2490 String deleteOrgSql =
"DELETE FROM organizations WHERE id=?";
2492 checkIfUsedStatement = conn.prepareStatement(checkIfUsedSql);
2493 checkIfUsedStatement.setInt(1, organizationToDelete.
getOrgID());
2494 checkIfUsedStatement.setInt(2, organizationToDelete.
getOrgID());
2495 resultSet = checkIfUsedStatement.executeQuery();
2497 if (resultSet.getLong(1) > 0) {
2498 throw new EamDbException(
"Can not delete organization which is currently in use by a case or reference set in the central repository.");
2500 deleteOrgStatement = conn.prepareStatement(deleteOrgSql);
2501 deleteOrgStatement.setInt(1, organizationToDelete.
getOrgID());
2502 deleteOrgStatement.executeUpdate();
2503 }
catch (SQLException ex) {
2504 throw new EamDbException(
"Error executing query when attempting to delete organization by id.", ex);
2523 public int newReferenceSet(
EamGlobalSet eamGlobalSet)
throws EamDbException {
2524 if (eamGlobalSet == null) {
2525 throw new EamDbException(
"EamGlobalSet is null");
2529 throw new EamDbException(
"File known status on the EamGlobalSet is null");
2532 if (eamGlobalSet.
getType() == null) {
2533 throw new EamDbException(
"Type on the EamGlobalSet is null");
2536 Connection conn = connect();
2538 PreparedStatement preparedStatement1 = null;
2539 PreparedStatement preparedStatement2 = null;
2540 ResultSet resultSet = null;
2541 String sql1 =
"INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, type, import_date) VALUES (?, ?, ?, ?, ?, ?, ?) "
2542 + getConflictClause();
2543 String sql2 =
"SELECT id FROM reference_sets WHERE org_id=? AND set_name=? AND version=? AND import_date=? LIMIT 1";
2546 preparedStatement1 = conn.prepareStatement(sql1);
2547 preparedStatement1.setInt(1, eamGlobalSet.
getOrgID());
2548 preparedStatement1.setString(2, eamGlobalSet.
getSetName());
2549 preparedStatement1.setString(3, eamGlobalSet.
getVersion());
2551 preparedStatement1.setBoolean(5, eamGlobalSet.
isReadOnly());
2552 preparedStatement1.setInt(6, eamGlobalSet.
getType().getId());
2553 preparedStatement1.setString(7, eamGlobalSet.
getImportDate().toString());
2555 preparedStatement1.executeUpdate();
2557 preparedStatement2 = conn.prepareStatement(sql2);
2558 preparedStatement2.setInt(1, eamGlobalSet.
getOrgID());
2559 preparedStatement2.setString(2, eamGlobalSet.
getSetName());
2560 preparedStatement2.setString(3, eamGlobalSet.
getVersion());
2561 preparedStatement2.setString(4, eamGlobalSet.
getImportDate().toString());
2563 resultSet = preparedStatement2.executeQuery();
2565 return resultSet.getInt(
"id");
2567 }
catch (SQLException ex) {
2568 throw new EamDbException(
"Error inserting new global set.", ex);
2587 public EamGlobalSet getReferenceSetByID(
int referenceSetID)
throws EamDbException {
2588 Connection conn = connect();
2590 PreparedStatement preparedStatement1 = null;
2591 ResultSet resultSet = null;
2592 String sql1 =
"SELECT * FROM reference_sets WHERE id=?";
2595 preparedStatement1 = conn.prepareStatement(sql1);
2596 preparedStatement1.setInt(1, referenceSetID);
2597 resultSet = preparedStatement1.executeQuery();
2598 if (resultSet.next()) {
2599 return getEamGlobalSetFromResultSet(resultSet);
2604 }
catch (SQLException ex) {
2605 throw new EamDbException(
"Error getting reference set by id.", ex);
2625 if (correlationType == null) {
2626 throw new EamDbException(
"Correlation type is null");
2629 List<EamGlobalSet> results =
new ArrayList<>();
2630 Connection conn = connect();
2632 PreparedStatement preparedStatement1 = null;
2633 ResultSet resultSet = null;
2634 String sql1 =
"SELECT * FROM reference_sets WHERE type=" + correlationType.getId();
2637 preparedStatement1 = conn.prepareStatement(sql1);
2638 resultSet = preparedStatement1.executeQuery();
2639 while (resultSet.next()) {
2640 results.add(getEamGlobalSetFromResultSet(resultSet));
2643 }
catch (SQLException ex) {
2644 throw new EamDbException(
"Error getting reference sets.", ex);
2665 throw new EamDbException(
"Known status of EamGlobalFileInstance is null");
2667 if (correlationType == null) {
2668 throw new EamDbException(
"Correlation type is null");
2671 Connection conn = connect();
2673 PreparedStatement preparedStatement = null;
2675 String sql =
"INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) "
2676 + getConflictClause();
2680 preparedStatement.setInt(1, eamGlobalFileInstance.
getGlobalSetID());
2681 preparedStatement.setString(2, eamGlobalFileInstance.
getMD5Hash());
2682 preparedStatement.setByte(3, eamGlobalFileInstance.
getKnownStatus().getFileKnownValue());
2683 preparedStatement.setString(4, eamGlobalFileInstance.
getComment());
2684 preparedStatement.executeUpdate();
2685 }
catch (SQLException ex) {
2686 throw new EamDbException(
"Error inserting new reference instance into reference_ table.", ex);
2706 public boolean referenceSetExists(String referenceSetName, String version)
throws EamDbException {
2707 Connection conn = connect();
2709 PreparedStatement preparedStatement1 = null;
2710 ResultSet resultSet = null;
2711 String sql1 =
"SELECT * FROM reference_sets WHERE set_name=? AND version=?";
2714 preparedStatement1 = conn.prepareStatement(sql1);
2715 preparedStatement1.setString(1, referenceSetName);
2716 preparedStatement1.setString(2, version);
2717 resultSet = preparedStatement1.executeQuery();
2718 return (resultSet.next());
2720 }
catch (SQLException ex) {
2721 throw new EamDbException(
"Error testing whether reference set exists (name: " + referenceSetName
2722 +
" version: " + version, ex);
2736 public void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances,
CorrelationAttributeInstance.
Type contentType)
throws EamDbException {
2737 if (contentType == null) {
2738 throw new EamDbException(
"Correlation type is null");
2740 if (globalInstances == null) {
2741 throw new EamDbException(
"Null set of EamGlobalFileInstance");
2744 Connection conn = connect();
2746 PreparedStatement bulkPs = null;
2748 conn.setAutoCommit(
false);
2751 String sql =
"INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) "
2752 + getConflictClause();
2757 if (globalInstance.getKnownStatus() == null) {
2758 throw new EamDbException(
"EamGlobalFileInstance with value " + globalInstance.getMD5Hash() +
" has null known status");
2761 bulkPs.setInt(1, globalInstance.getGlobalSetID());
2762 bulkPs.setString(2, globalInstance.getMD5Hash());
2763 bulkPs.setByte(3, globalInstance.getKnownStatus().getFileKnownValue());
2764 bulkPs.setString(4, globalInstance.getComment());
2768 bulkPs.executeBatch();
2770 }
catch (SQLException | EamDbException ex) {
2773 }
catch (SQLException ex2) {
2776 throw new EamDbException(
"Error inserting bulk artifacts.", ex);
2794 public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(
CorrelationAttributeInstance.
Type aType, String aValue)
throws EamDbException, CorrelationAttributeNormalizationException {
2797 Connection conn = connect();
2799 List<EamGlobalFileInstance> globalFileInstances =
new ArrayList<>();
2800 PreparedStatement preparedStatement1 = null;
2801 ResultSet resultSet = null;
2802 String sql1 =
"SELECT * FROM %s WHERE value=?";
2806 preparedStatement1.setString(1, normalizeValued);
2807 resultSet = preparedStatement1.executeQuery();
2808 while (resultSet.next()) {
2809 globalFileInstances.add(getEamGlobalFileInstanceFromResultSet(resultSet));
2812 }
catch (SQLException ex) {
2813 throw new EamDbException(
"Error getting reference instances by type and value.", ex);
2820 return globalFileInstances;
2834 if (newType == null) {
2835 throw new EamDbException(
"Correlation type is null");
2838 if (-1 == newType.getId()) {
2839 typeId = newCorrelationTypeNotKnownId(newType);
2841 typeId = newCorrelationTypeKnownId(newType);
2858 Connection conn = connect();
2860 PreparedStatement preparedStatement = null;
2861 PreparedStatement preparedStatementQuery = null;
2862 ResultSet resultSet = null;
2867 insertSql =
"INSERT INTO correlation_types(display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?) " + getConflictClause();
2869 querySql =
"SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
2872 preparedStatement = conn.prepareStatement(insertSql);
2874 preparedStatement.setString(1, newType.getDisplayName());
2875 preparedStatement.setString(2, newType.getDbTableName());
2876 preparedStatement.setInt(3, newType.isSupported() ? 1 : 0);
2877 preparedStatement.setInt(4, newType.isEnabled() ? 1 : 0);
2879 preparedStatement.executeUpdate();
2881 preparedStatementQuery = conn.prepareStatement(querySql);
2882 preparedStatementQuery.setString(1, newType.getDisplayName());
2883 preparedStatementQuery.setString(2, newType.getDbTableName());
2885 resultSet = preparedStatementQuery.executeQuery();
2886 if (resultSet.next()) {
2888 typeId = correlationType.getId();
2890 }
catch (SQLException ex) {
2891 throw new EamDbException(
"Error inserting new correlation type.", ex);
2911 Connection conn = connect();
2913 PreparedStatement preparedStatement = null;
2914 PreparedStatement preparedStatementQuery = null;
2915 ResultSet resultSet = null;
2920 insertSql =
"INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause();
2922 querySql =
"SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
2925 preparedStatement = conn.prepareStatement(insertSql);
2927 preparedStatement.setInt(1, newType.getId());
2928 preparedStatement.setString(2, newType.getDisplayName());
2929 preparedStatement.setString(3, newType.getDbTableName());
2930 preparedStatement.setInt(4, newType.isSupported() ? 1 : 0);
2931 preparedStatement.setInt(5, newType.isEnabled() ? 1 : 0);
2933 preparedStatement.executeUpdate();
2935 preparedStatementQuery = conn.prepareStatement(querySql);
2936 preparedStatementQuery.setString(1, newType.getDisplayName());
2937 preparedStatementQuery.setString(2, newType.getDbTableName());
2939 resultSet = preparedStatementQuery.executeQuery();
2940 if (resultSet.next()) {
2942 typeId = correlationType.getId();
2944 }
catch (SQLException ex) {
2945 throw new EamDbException(
"Error inserting new correlation type.", ex);
2957 Connection conn = connect();
2960 PreparedStatement preparedStatement = null;
2961 ResultSet resultSet = null;
2962 String sql =
"SELECT * FROM correlation_types";
2965 preparedStatement = conn.prepareStatement(sql);
2966 resultSet = preparedStatement.executeQuery();
2967 while (resultSet.next()) {
2968 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
2972 }
catch (SQLException ex) {
2973 throw new EamDbException(
"Error getting all correlation types.", ex);
2992 Connection conn = connect();
2995 PreparedStatement preparedStatement = null;
2996 ResultSet resultSet = null;
2997 String sql =
"SELECT * FROM correlation_types WHERE enabled=1";
3000 preparedStatement = conn.prepareStatement(sql);
3001 resultSet = preparedStatement.executeQuery();
3002 while (resultSet.next()) {
3003 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
3007 }
catch (SQLException ex) {
3008 throw new EamDbException(
"Error getting enabled correlation types.", ex);
3027 Connection conn = connect();
3030 PreparedStatement preparedStatement = null;
3031 ResultSet resultSet = null;
3032 String sql =
"SELECT * FROM correlation_types WHERE supported=1";
3035 preparedStatement = conn.prepareStatement(sql);
3036 resultSet = preparedStatement.executeQuery();
3037 while (resultSet.next()) {
3038 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
3042 }
catch (SQLException ex) {
3043 throw new EamDbException(
"Error getting supported correlation types.", ex);
3060 Connection conn = connect();
3062 PreparedStatement preparedStatement = null;
3063 String sql =
"UPDATE correlation_types SET display_name=?, db_table_name=?, supported=?, enabled=? WHERE id=?";
3066 preparedStatement = conn.prepareStatement(sql);
3067 preparedStatement.setString(1, aType.getDisplayName());
3068 preparedStatement.setString(2, aType.getDbTableName());
3069 preparedStatement.setInt(3, aType.isSupported() ? 1 : 0);
3070 preparedStatement.setInt(4, aType.isEnabled() ? 1 : 0);
3071 preparedStatement.setInt(5, aType.getId());
3072 preparedStatement.executeUpdate();
3073 typeCache.put(aType.getId(), aType);
3074 }
catch (SQLException ex) {
3075 throw new EamDbException(
"Error updating correlation type.", ex);
3095 return typeCache.get(typeId, () -> getCorrelationTypeByIdFromCr(typeId));
3096 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
3099 }
catch (ExecutionException ex) {
3100 throw new EamDbException(
"Error getting correlation type", ex);
3114 Connection conn = connect();
3117 PreparedStatement preparedStatement = null;
3118 ResultSet resultSet = null;
3119 String sql =
"SELECT * FROM correlation_types WHERE id=?";
3122 preparedStatement = conn.prepareStatement(sql);
3123 preparedStatement.setInt(1, typeId);
3124 resultSet = preparedStatement.executeQuery();
3125 if (resultSet.next()) {
3126 aType = getCorrelationTypeFromResultSet(resultSet);
3129 throw new EamDbException(
"Failed to find entry for correlation type ID = " + typeId);
3132 }
catch (SQLException ex) {
3133 throw new EamDbException(
"Error getting correlation type by id.", ex);
3151 private CorrelationCase getEamCaseFromResultSet(ResultSet resultSet)
throws SQLException {
3152 if (null == resultSet) {
3158 resultSet.getInt(
"org_id");
3159 if (!resultSet.wasNull()) {
3162 resultSet.getString(
"org_name"),
3163 resultSet.getString(
"poc_name"),
3164 resultSet.getString(
"poc_email"),
3165 resultSet.getString(
"poc_phone"));
3168 CorrelationCase eamCase =
new CorrelationCase(resultSet.getInt(
"case_id"), resultSet.getString(
"case_uid"), eamOrg, resultSet.getString(
"case_name"),
3169 resultSet.getString(
"creation_date"), resultSet.getString(
"case_number"), resultSet.getString(
"examiner_name"),
3170 resultSet.getString(
"examiner_email"), resultSet.getString(
"examiner_phone"), resultSet.getString(
"notes"));
3175 private CorrelationDataSource getEamDataSourceFromResultSet(ResultSet resultSet)
throws SQLException {
3176 if (null == resultSet) {
3181 resultSet.getInt(
"case_id"),
3182 resultSet.getInt(
"id"),
3183 resultSet.getString(
"device_id"),
3184 resultSet.getString(
"name"),
3185 resultSet.getLong(
"datasource_obj_id"),
3186 resultSet.getString(
"md5"),
3187 resultSet.getString(
"sha1"),
3188 resultSet.getString(
"sha256")
3191 return eamDataSource;
3195 if (null == resultSet) {
3200 resultSet.getInt(
"id"),
3201 resultSet.getString(
"display_name"),
3202 resultSet.getString(
"db_table_name"),
3203 resultSet.getBoolean(
"supported"),
3204 resultSet.getBoolean(
"enabled")
3207 return eamArtifactType;
3221 if (null == resultSet) {
3226 resultSet.getString(
"org_name"),
3227 resultSet.getString(
"poc_name"),
3228 resultSet.getString(
"poc_email"),
3229 resultSet.getString(
"poc_phone"));
3233 resultSet.getString(
"value"),
3234 resultSet.getInt(
"instance_id"),
3235 new CorrelationCase(resultSet.getInt(
"id"), resultSet.getString(
"case_uid"), eamOrg, resultSet.getString(
"case_name"),
3236 resultSet.getString(
"creation_date"), resultSet.getString(
"case_number"), resultSet.getString(
"examiner_name"),
3237 resultSet.getString(
"examiner_email"), resultSet.getString(
"examiner_phone"), resultSet.getString(
"notes")),
3239 resultSet.getInt(
"id"), resultSet.getInt(
"data_source_id"), resultSet.getString(
"device_id"), resultSet.getString(
"name"),
3240 resultSet.getLong(
"datasource_obj_id"), resultSet.getString(
"md5"), resultSet.getString(
"sha1"), resultSet.getString(
"sha256")),
3241 resultSet.getString(
"file_path"),
3242 resultSet.getString(
"comment"),
3243 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3244 resultSet.getLong(
"file_obj_id"));
3247 private EamOrganization getEamOrganizationFromResultSet(ResultSet resultSet)
throws SQLException {
3248 if (null == resultSet) {
3253 resultSet.getInt(
"id"),
3254 resultSet.getString(
"org_name"),
3255 resultSet.getString(
"poc_name"),
3256 resultSet.getString(
"poc_email"),
3257 resultSet.getString(
"poc_phone")
3261 private EamGlobalSet getEamGlobalSetFromResultSet(ResultSet resultSet)
throws SQLException, EamDbException {
3262 if (null == resultSet) {
3267 resultSet.getInt(
"id"),
3268 resultSet.getInt(
"org_id"),
3269 resultSet.getString(
"set_name"),
3270 resultSet.getString(
"version"),
3271 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3272 resultSet.getBoolean(
"read_only"),
3274 LocalDate.parse(resultSet.getString(
"import_date"))
3278 private EamGlobalFileInstance getEamGlobalFileInstanceFromResultSet(ResultSet resultSet)
throws SQLException, EamDbException, CorrelationAttributeNormalizationException {
3279 if (null == resultSet) {
3284 resultSet.getInt(
"id"),
3285 resultSet.getInt(
"reference_set_id"),
3286 resultSet.getString(
"value"),
3287 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3288 resultSet.getString(
"comment")
3302 abstract boolean doesColumnExist(Connection conn, String tableName, String columnName)
throws SQLException;
3309 @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.",
3310 "# {0} - minorVersion",
3311 "AbstractSqlEamDb.badMinorSchema.message=Bad value for schema minor version ({0}) - database is corrupt.",
3312 "AbstractSqlEamDb.failedToReadMinorVersion.message=Failed to read schema minor version for Central Repository.",
3313 "# {0} - majorVersion",
3314 "AbstractSqlEamDb.badMajorSchema.message=Bad value for schema version ({0}) - database is corrupt.",
3315 "AbstractSqlEamDb.failedToReadMajorVersion.message=Failed to read schema version for Central Repository.",
3316 "# {0} - platformName",
3317 "AbstractSqlEamDb.cannotUpgrage.message=Currently selected database platform \"{0}\" can not be upgraded."})
3321 ResultSet resultSet = null;
3322 Statement statement = null;
3323 PreparedStatement preparedStatement = null;
3324 Connection conn = null;
3328 conn = connect(
false);
3329 conn.setAutoCommit(
false);
3330 statement = conn.createStatement();
3332 int minorVersion = 0;
3333 String minorVersionStr = null;
3334 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name='" + AbstractSqlEamDb.SCHEMA_MINOR_VERSION_KEY +
"'");
3335 if (resultSet.next()) {
3336 minorVersionStr = resultSet.getString(
"value");
3338 minorVersion = Integer.parseInt(minorVersionStr);
3339 }
catch (NumberFormatException ex) {
3340 throw new EamDbException(
"Bad value for schema minor version (" + minorVersionStr +
") - database is corrupt", Bundle.AbstractSqlEamDb_badMinorSchema_message(minorVersionStr), ex);
3343 throw new EamDbException(
"Failed to read schema minor version from db_info table", Bundle.AbstractSqlEamDb_failedToReadMinorVersion_message());
3346 int majorVersion = 0;
3347 String majorVersionStr = null;
3348 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name='" + AbstractSqlEamDb.SCHEMA_MAJOR_VERSION_KEY +
"'");
3349 if (resultSet.next()) {
3350 majorVersionStr = resultSet.getString(
"value");
3352 majorVersion = Integer.parseInt(majorVersionStr);
3353 }
catch (NumberFormatException ex) {
3354 throw new EamDbException(
"Bad value for schema version (" + majorVersionStr +
") - database is corrupt", Bundle.AbstractSqlEamDb_badMajorSchema_message(majorVersionStr), ex);
3357 throw new EamDbException(
"Failed to read schema major version from db_info table", Bundle.AbstractSqlEamDb_failedToReadMajorVersion_message());
3368 CaseDbSchemaVersionNumber dbSchemaVersion =
new CaseDbSchemaVersionNumber(majorVersion, minorVersion);
3373 if (SOFTWARE_CR_DB_SCHEMA_VERSION.getMajor() < dbSchemaVersion.getMajor()) {
3376 if (dbSchemaVersion.equals(SOFTWARE_CR_DB_SCHEMA_VERSION)) {
3377 logger.log(Level.INFO,
"Central Repository is up to date");
3380 if (dbSchemaVersion.compareTo(SOFTWARE_CR_DB_SCHEMA_VERSION) > 0) {
3381 logger.log(Level.INFO,
"Central Repository is of newer version than software creates");
3388 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 1)) < 0) {
3389 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN known_status INTEGER;");
3390 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN read_only BOOLEAN;");
3391 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN type INTEGER;");
3396 EamDbUtil.insertDefaultOrganization(conn);
3402 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 2)) < 0) {
3403 final String addIntegerColumnTemplate =
"ALTER TABLE %s ADD COLUMN %s INTEGER;";
3404 final String addSsidTableTemplate;
3405 final String addCaseIdIndexTemplate;
3406 final String addDataSourceIdIndexTemplate;
3407 final String addValueIndexTemplate;
3408 final String addKnownStatusIndexTemplate;
3409 final String addObjectIdIndexTemplate;
3411 final String addAttributeSql;
3413 switch (selectedPlatform) {
3415 addAttributeSql =
"INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause();
3425 addAttributeSql =
"INSERT OR IGNORE INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?)";
3435 throw new EamDbException(
"Currently selected database platform \"" + selectedPlatform.name() +
"\" can not be upgraded.", Bundle.AbstractSqlEamDb_cannotUpgrage_message(selectedPlatform.name()));
3437 final String dataSourcesTableName =
"data_sources";
3438 final String dataSourceObjectIdColumnName =
"datasource_obj_id";
3439 if (!doesColumnExist(conn, dataSourcesTableName, dataSourceObjectIdColumnName)) {
3440 statement.execute(String.format(addIntegerColumnTemplate, dataSourcesTableName, dataSourceObjectIdColumnName));
3442 final String dataSourceObjectIdIndexTemplate =
"CREATE INDEX IF NOT EXISTS datasource_object_id ON data_sources (%s)";
3443 statement.execute(String.format(dataSourceObjectIdIndexTemplate, dataSourceObjectIdColumnName));
3444 List<String> instaceTablesToAdd =
new ArrayList<>();
3446 final String wirelessNetworksDbTableName =
"wireless_networks";
3447 instaceTablesToAdd.add(wirelessNetworksDbTableName +
"_instances");
3448 final String macAddressDbTableName =
"mac_address";
3449 instaceTablesToAdd.add(macAddressDbTableName +
"_instances");
3450 final String imeiNumberDbTableName =
"imei_number";
3451 instaceTablesToAdd.add(imeiNumberDbTableName +
"_instances");
3452 final String iccidNumberDbTableName =
"iccid_number";
3453 instaceTablesToAdd.add(iccidNumberDbTableName +
"_instances");
3454 final String imsiNumberDbTableName =
"imsi_number";
3455 instaceTablesToAdd.add(imsiNumberDbTableName +
"_instances");
3458 preparedStatement = conn.prepareStatement(addAttributeSql);
3460 preparedStatement.setString(2, Bundle.CorrelationType_SSID_displayName());
3461 preparedStatement.setString(3, wirelessNetworksDbTableName);
3462 preparedStatement.setInt(4, 1);
3463 preparedStatement.setInt(5, 1);
3464 preparedStatement.execute();
3467 preparedStatement = conn.prepareStatement(addAttributeSql);
3469 preparedStatement.setString(2, Bundle.CorrelationType_MAC_displayName());
3470 preparedStatement.setString(3, macAddressDbTableName);
3471 preparedStatement.setInt(4, 1);
3472 preparedStatement.setInt(5, 1);
3473 preparedStatement.execute();
3476 preparedStatement = conn.prepareStatement(addAttributeSql);
3478 preparedStatement.setString(2, Bundle.CorrelationType_IMEI_displayName());
3479 preparedStatement.setString(3, imeiNumberDbTableName);
3480 preparedStatement.setInt(4, 1);
3481 preparedStatement.setInt(5, 1);
3482 preparedStatement.execute();
3485 preparedStatement = conn.prepareStatement(addAttributeSql);
3487 preparedStatement.setString(2, Bundle.CorrelationType_IMSI_displayName());
3488 preparedStatement.setString(3, imsiNumberDbTableName);
3489 preparedStatement.setInt(4, 1);
3490 preparedStatement.setInt(5, 1);
3491 preparedStatement.execute();
3494 preparedStatement = conn.prepareStatement(addAttributeSql);
3496 preparedStatement.setString(2, Bundle.CorrelationType_ICCID_displayName());
3497 preparedStatement.setString(3, iccidNumberDbTableName);
3498 preparedStatement.setInt(4, 1);
3499 preparedStatement.setInt(5, 1);
3500 preparedStatement.execute();
3503 for (String tableName : instaceTablesToAdd) {
3504 statement.execute(String.format(addSsidTableTemplate, tableName, tableName));
3505 statement.execute(String.format(addCaseIdIndexTemplate, tableName, tableName));
3506 statement.execute(String.format(addDataSourceIdIndexTemplate, tableName, tableName));
3507 statement.execute(String.format(addValueIndexTemplate, tableName, tableName));
3508 statement.execute(String.format(addKnownStatusIndexTemplate, tableName, tableName));
3512 String instance_type_dbname;
3513 final String objectIdColumnName =
"file_obj_id";
3516 if (!doesColumnExist(conn, instance_type_dbname, objectIdColumnName)) {
3517 statement.execute(String.format(addIntegerColumnTemplate, instance_type_dbname, objectIdColumnName));
3519 statement.execute(String.format(addObjectIdIndexTemplate, instance_type_dbname, instance_type_dbname));
3525 if (!doesColumnExist(conn, dataSourcesTableName,
"md5")) {
3526 statement.execute(
"ALTER TABLE data_sources ADD COLUMN md5 TEXT DEFAULT NULL");
3528 if (!doesColumnExist(conn, dataSourcesTableName,
"sha1")) {
3529 statement.execute(
"ALTER TABLE data_sources ADD COLUMN sha1 TEXT DEFAULT NULL");
3531 if (!doesColumnExist(conn, dataSourcesTableName,
"sha256")) {
3532 statement.execute(
"ALTER TABLE data_sources ADD COLUMN sha256 TEXT DEFAULT NULL");
3543 String creationMajorVer;
3544 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name = '" + AbstractSqlEamDb.CREATION_SCHEMA_MAJOR_VERSION_KEY +
"'");
3545 if (resultSet.next()) {
3546 creationMajorVer = resultSet.getString(
"value");
3548 creationMajorVer =
"0";
3550 String creationMinorVer;
3551 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name = '" + AbstractSqlEamDb.CREATION_SCHEMA_MINOR_VERSION_KEY +
"'");
3552 if (resultSet.next()) {
3553 creationMinorVer = resultSet.getString(
"value");
3555 creationMinorVer =
"0";
3557 statement.execute(
"DROP TABLE db_info");
3559 statement.execute(
"CREATE TABLE db_info (id SERIAL, name TEXT UNIQUE NOT NULL, value TEXT NOT NULL)");
3561 statement.execute(
"CREATE TABLE db_info (id INTEGER PRIMARY KEY, name TEXT UNIQUE NOT NULL, value TEXT NOT NULL)");
3563 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + AbstractSqlEamDb.SCHEMA_MAJOR_VERSION_KEY +
"','" + majorVersionStr +
"')");
3564 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + AbstractSqlEamDb.SCHEMA_MINOR_VERSION_KEY +
"','" + minorVersionStr +
"')");
3565 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + AbstractSqlEamDb.CREATION_SCHEMA_MAJOR_VERSION_KEY +
"','" + creationMajorVer +
"')");
3566 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + AbstractSqlEamDb.CREATION_SCHEMA_MINOR_VERSION_KEY +
"','" + creationMinorVer +
"')");
3571 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 3)) < 0) {
3572 switch (selectedPlatform) {
3574 statement.execute(
"ALTER TABLE data_sources DROP CONSTRAINT datasource_unique");
3576 statement.execute(
"ALTER TABLE data_sources ADD CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name, datasource_obj_id)");
3580 statement.execute(
"DROP INDEX IF EXISTS data_sources_name");
3581 statement.execute(
"DROP INDEX IF EXISTS data_sources_object_id");
3582 statement.execute(
"ALTER TABLE data_sources RENAME TO old_data_sources");
3584 statement.execute(
"CREATE TABLE IF NOT EXISTS data_sources (id integer primary key autoincrement NOT NULL,"
3585 +
"case_id integer NOT NULL,device_id text NOT NULL,name text NOT NULL,datasource_obj_id integer,"
3586 +
"md5 text DEFAULT NULL,sha1 text DEFAULT NULL,sha256 text DEFAULT NULL,"
3587 +
"foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL,"
3588 +
"CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name, datasource_obj_id))");
3591 statement.execute(
"INSERT INTO data_sources SELECT * FROM old_data_sources");
3592 statement.execute(
"DROP TABLE old_data_sources");
3595 throw new EamDbException(
"Currently selected database platform \"" + selectedPlatform.name() +
"\" can not be upgraded.", Bundle.AbstractSqlEamDb_cannotUpgrage_message(selectedPlatform.name()));
3598 updateSchemaVersion(conn);
3600 logger.log(Level.INFO, String.format(
"Central Repository schema updated to version %s", SOFTWARE_CR_DB_SCHEMA_VERSION));
3601 }
catch (SQLException | EamDbException ex) {
3606 }
catch (SQLException ex2) {
3607 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()