Autopsy  4.6.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
AbstractSqlEamDb.java
Go to the documentation of this file.
1 /*
2  * Central Repository
3  *
4  * Copyright 2015-2017 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.centralrepository.datamodel;
20 
21 import java.net.UnknownHostException;
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.Collection;
25 import java.util.LinkedHashSet;
26 import java.util.stream.Collectors;
27 import java.sql.Connection;
28 import java.sql.PreparedStatement;
29 import java.sql.ResultSet;
30 import java.sql.SQLException;
31 import java.sql.Statement;
32 import java.sql.Types;
33 import java.time.LocalDate;
34 import java.util.HashMap;
35 import java.util.Map;
36 import java.util.Set;
37 import java.util.logging.Level;
38 import org.openide.util.NbBundle.Messages;
40 import static org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil.updateSchemaVersion;
42 import org.sleuthkit.datamodel.CaseDbSchemaVersionNumber;
43 import org.sleuthkit.datamodel.TskData;
44 
50 public abstract class AbstractSqlEamDb implements EamDb {
51 
52  private final static Logger LOGGER = Logger.getLogger(AbstractSqlEamDb.class.getName());
53 
55 
56  private int bulkArtifactsCount;
57  protected int bulkArtifactsThreshold;
58  private final Map<String, Collection<CorrelationAttribute>> bulkArtifacts;
59 
65  protected AbstractSqlEamDb() throws EamDbException {
66  bulkArtifactsCount = 0;
67  bulkArtifacts = new HashMap<>();
68 
70  DEFAULT_CORRELATION_TYPES.forEach((type) -> {
71  bulkArtifacts.put(type.getDbTableName(), new ArrayList<>());
72  });
73  }
74 
78  protected abstract Connection connect() throws EamDbException;
79 
88  @Override
89  public void newDbInfo(String name, String value) throws EamDbException {
90  Connection conn = connect();
91 
92  PreparedStatement preparedStatement = null;
93  String sql = "INSERT INTO db_info (name, value) VALUES (?, ?) "
95  try {
96  preparedStatement = conn.prepareStatement(sql);
97  preparedStatement.setString(1, name);
98  preparedStatement.setString(2, value);
99  preparedStatement.executeUpdate();
100  } catch (SQLException ex) {
101  throw new EamDbException("Error adding new name/value pair to db_info.", ex);
102  } finally {
103  EamDbUtil.closePreparedStatement(preparedStatement);
105  }
106 
107  }
108 
118  @Override
119  public String getDbInfo(String name) throws EamDbException {
120  Connection conn = connect();
121 
122  PreparedStatement preparedStatement = null;
123  ResultSet resultSet = null;
124  String value = null;
125  String sql = "SELECT value FROM db_info WHERE name=?";
126  try {
127  preparedStatement = conn.prepareStatement(sql);
128  preparedStatement.setString(1, name);
129  resultSet = preparedStatement.executeQuery();
130  if (resultSet.next()) {
131  value = resultSet.getString("value");
132  }
133  } catch (SQLException ex) {
134  throw new EamDbException("Error getting value for name.", ex);
135  } finally {
136  EamDbUtil.closePreparedStatement(preparedStatement);
137  EamDbUtil.closeResultSet(resultSet);
139  }
140 
141  return value;
142  }
143 
152  @Override
153  public void updateDbInfo(String name, String value) throws EamDbException {
154  Connection conn = connect();
155 
156  PreparedStatement preparedStatement = null;
157  String sql = "UPDATE db_info SET value=? WHERE name=?";
158  try {
159  preparedStatement = conn.prepareStatement(sql);
160  preparedStatement.setString(1, value);
161  preparedStatement.setString(2, name);
162  preparedStatement.executeUpdate();
163  } catch (SQLException ex) {
164  throw new EamDbException("Error updating value for name.", ex);
165  } finally {
166  EamDbUtil.closePreparedStatement(preparedStatement);
168  }
169  }
170 
179  @Override
180  public synchronized CorrelationCase newCase(CorrelationCase eamCase) throws EamDbException {
181 
182  // check if there is already an existing CorrelationCase for this Case
183  CorrelationCase cRCase = getCaseByUUID(eamCase.getCaseUUID());
184  if (cRCase != null) {
185  return cRCase;
186  }
187 
188  Connection conn = connect();
189  PreparedStatement preparedStatement = null;
190 
191  String sql = "INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, "
192  + "examiner_name, examiner_email, examiner_phone, notes) "
193  + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) "
194  + getConflictClause();
195 
196  try {
197  preparedStatement = conn.prepareStatement(sql);
198 
199  preparedStatement.setString(1, eamCase.getCaseUUID());
200  if (null == eamCase.getOrg()) {
201  preparedStatement.setNull(2, Types.INTEGER);
202  } else {
203  preparedStatement.setInt(2, eamCase.getOrg().getOrgID());
204  }
205  preparedStatement.setString(3, eamCase.getDisplayName());
206  preparedStatement.setString(4, eamCase.getCreationDate());
207  if ("".equals(eamCase.getCaseNumber())) {
208  preparedStatement.setNull(5, Types.INTEGER);
209  } else {
210  preparedStatement.setString(5, eamCase.getCaseNumber());
211  }
212  if ("".equals(eamCase.getExaminerName())) {
213  preparedStatement.setNull(6, Types.INTEGER);
214  } else {
215  preparedStatement.setString(6, eamCase.getExaminerName());
216  }
217  if ("".equals(eamCase.getExaminerEmail())) {
218  preparedStatement.setNull(7, Types.INTEGER);
219  } else {
220  preparedStatement.setString(7, eamCase.getExaminerEmail());
221  }
222  if ("".equals(eamCase.getExaminerPhone())) {
223  preparedStatement.setNull(8, Types.INTEGER);
224  } else {
225  preparedStatement.setString(8, eamCase.getExaminerPhone());
226  }
227  if ("".equals(eamCase.getNotes())) {
228  preparedStatement.setNull(9, Types.INTEGER);
229  } else {
230  preparedStatement.setString(9, eamCase.getNotes());
231  }
232 
233  preparedStatement.executeUpdate();
234  } catch (SQLException ex) {
235  throw new EamDbException("Error inserting new case.", ex); // NON-NLS
236  } finally {
237  EamDbUtil.closePreparedStatement(preparedStatement);
239  }
240 
241  // get a new version with the updated ID
242  return getCaseByUUID(eamCase.getCaseUUID());
243  }
244 
250  @Override
251  public CorrelationCase newCase(Case autopsyCase) throws EamDbException {
252  if (autopsyCase == null) {
253  throw new EamDbException("Case is null");
254  }
255 
256  CorrelationCase curCeCase = new CorrelationCase(
257  -1,
258  autopsyCase.getName(), // unique case ID
260  autopsyCase.getDisplayName(),
261  autopsyCase.getCreatedDate(),
262  autopsyCase.getNumber(),
263  autopsyCase.getExaminer(),
264  autopsyCase.getExaminerEmail(),
265  autopsyCase.getExaminerPhone(),
266  autopsyCase.getCaseNotes());
267  return newCase(curCeCase);
268  }
269 
270  @Override
271  public CorrelationCase getCase(Case autopsyCase) throws EamDbException {
272  return getCaseByUUID(autopsyCase.getName());
273  }
274 
280  @Override
281  public void updateCase(CorrelationCase eamCase) throws EamDbException {
282  if(eamCase == null) {
283  throw new EamDbException("CorrelationCase argument is null");
284  }
285 
286  Connection conn = connect();
287 
288  PreparedStatement preparedStatement = null;
289  String sql = "UPDATE cases "
290  + "SET org_id=?, case_name=?, creation_date=?, case_number=?, examiner_name=?, examiner_email=?, examiner_phone=?, notes=? "
291  + "WHERE case_uid=?";
292 
293  try {
294  preparedStatement = conn.prepareStatement(sql);
295 
296  if (null == eamCase.getOrg()) {
297  preparedStatement.setNull(1, Types.INTEGER);
298  } else {
299  preparedStatement.setInt(1, eamCase.getOrg().getOrgID());
300  }
301  preparedStatement.setString(2, eamCase.getDisplayName());
302  preparedStatement.setString(3, eamCase.getCreationDate());
303 
304  if ("".equals(eamCase.getCaseNumber())) {
305  preparedStatement.setNull(4, Types.INTEGER);
306  } else {
307  preparedStatement.setString(4, eamCase.getCaseNumber());
308  }
309  if ("".equals(eamCase.getExaminerName())) {
310  preparedStatement.setNull(5, Types.INTEGER);
311  } else {
312  preparedStatement.setString(5, eamCase.getExaminerName());
313  }
314  if ("".equals(eamCase.getExaminerEmail())) {
315  preparedStatement.setNull(6, Types.INTEGER);
316  } else {
317  preparedStatement.setString(6, eamCase.getExaminerEmail());
318  }
319  if ("".equals(eamCase.getExaminerPhone())) {
320  preparedStatement.setNull(7, Types.INTEGER);
321  } else {
322  preparedStatement.setString(7, eamCase.getExaminerPhone());
323  }
324  if ("".equals(eamCase.getNotes())) {
325  preparedStatement.setNull(8, Types.INTEGER);
326  } else {
327  preparedStatement.setString(8, eamCase.getNotes());
328  }
329 
330  preparedStatement.setString(9, eamCase.getCaseUUID());
331 
332  preparedStatement.executeUpdate();
333  } catch (SQLException ex) {
334  throw new EamDbException("Error updating case.", ex); // NON-NLS
335  } finally {
336  EamDbUtil.closePreparedStatement(preparedStatement);
338  }
339  }
340 
348  @Override
349  public CorrelationCase getCaseByUUID(String caseUUID) throws EamDbException {
350  // @@@ We should have a cache here...
351 
352  Connection conn = connect();
353 
354  CorrelationCase eamCaseResult = null;
355  PreparedStatement preparedStatement = null;
356  ResultSet resultSet = null;
357 
358  String sql = "SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, "
359  + "examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone "
360  + "FROM cases "
361  + "LEFT JOIN organizations ON cases.org_id=organizations.id "
362  + "WHERE case_uid=?";
363 
364  try {
365  preparedStatement = conn.prepareStatement(sql);
366  preparedStatement.setString(1, caseUUID);
367  resultSet = preparedStatement.executeQuery();
368  if (resultSet.next()) {
369  eamCaseResult = getEamCaseFromResultSet(resultSet);
370  }
371  } catch (SQLException ex) {
372  throw new EamDbException("Error getting case details.", ex); // NON-NLS
373  } finally {
374  EamDbUtil.closePreparedStatement(preparedStatement);
375  EamDbUtil.closeResultSet(resultSet);
377  }
378 
379  return eamCaseResult;
380  }
381 
387  @Override
388  public List<CorrelationCase> getCases() throws EamDbException {
389  Connection conn = connect();
390 
391  List<CorrelationCase> cases = new ArrayList<>();
392  CorrelationCase eamCaseResult;
393  PreparedStatement preparedStatement = null;
394  ResultSet resultSet = null;
395 
396  String sql = "SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, "
397  + "examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone "
398  + "FROM cases "
399  + "LEFT JOIN organizations ON cases.org_id=organizations.id";
400 
401  try {
402  preparedStatement = conn.prepareStatement(sql);
403  resultSet = preparedStatement.executeQuery();
404  while (resultSet.next()) {
405  eamCaseResult = getEamCaseFromResultSet(resultSet);
406  cases.add(eamCaseResult);
407  }
408  } catch (SQLException ex) {
409  throw new EamDbException("Error getting all cases.", ex); // NON-NLS
410  } finally {
411  EamDbUtil.closePreparedStatement(preparedStatement);
412  EamDbUtil.closeResultSet(resultSet);
414  }
415 
416  return cases;
417  }
418 
424  @Override
425  public void newDataSource(CorrelationDataSource eamDataSource) throws EamDbException {
426  Connection conn = connect();
427 
428  PreparedStatement preparedStatement = null;
429 
430  String sql = "INSERT INTO data_sources(device_id, case_id, name) VALUES (?, ?, ?) "
431  + getConflictClause();
432 
433  try {
434  preparedStatement = conn.prepareStatement(sql);
435 
436  preparedStatement.setString(1, eamDataSource.getDeviceID());
437  preparedStatement.setInt(2, eamDataSource.getCaseID());
438  preparedStatement.setString(3, eamDataSource.getName());
439 
440  preparedStatement.executeUpdate();
441  } catch (SQLException ex) {
442  throw new EamDbException("Error inserting new data source.", ex); // NON-NLS
443  } finally {
444  EamDbUtil.closePreparedStatement(preparedStatement);
446  }
447  }
448 
458  @Override
459  public CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException {
460  if(correlationCase == null) {
461  throw new EamDbException("CorrelationCase argument is null");
462  }
463 
464  Connection conn = connect();
465 
466  CorrelationDataSource eamDataSourceResult = null;
467  PreparedStatement preparedStatement = null;
468  ResultSet resultSet = null;
469 
470  String sql = "SELECT * FROM data_sources WHERE device_id=? AND case_id=?"; // NON-NLS
471 
472  try {
473  preparedStatement = conn.prepareStatement(sql);
474  preparedStatement.setString(1, dataSourceDeviceId);
475  preparedStatement.setInt(2, correlationCase.getID());
476  resultSet = preparedStatement.executeQuery();
477  if (resultSet.next()) {
478  eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
479  }
480  } catch (SQLException ex) {
481  throw new EamDbException("Error getting data source.", ex); // NON-NLS
482  } finally {
483  EamDbUtil.closePreparedStatement(preparedStatement);
484  EamDbUtil.closeResultSet(resultSet);
486  }
487 
488  return eamDataSourceResult;
489  }
490 
496  @Override
497  public List<CorrelationDataSource> getDataSources() throws EamDbException {
498  Connection conn = connect();
499 
500  List<CorrelationDataSource> dataSources = new ArrayList<>();
501  CorrelationDataSource eamDataSourceResult;
502  PreparedStatement preparedStatement = null;
503  ResultSet resultSet = null;
504 
505  String sql = "SELECT * FROM data_sources";
506 
507  try {
508  preparedStatement = conn.prepareStatement(sql);
509  resultSet = preparedStatement.executeQuery();
510  while (resultSet.next()) {
511  eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
512  dataSources.add(eamDataSourceResult);
513  }
514  } catch (SQLException ex) {
515  throw new EamDbException("Error getting all data sources.", ex); // NON-NLS
516  } finally {
517  EamDbUtil.closePreparedStatement(preparedStatement);
518  EamDbUtil.closeResultSet(resultSet);
520  }
521 
522  return dataSources;
523  }
524 
531  @Override
532  public void addArtifact(CorrelationAttribute eamArtifact) throws EamDbException {
533  if(eamArtifact == null) {
534  throw new EamDbException("CorrelationAttribute is null");
535  }
536  if(eamArtifact.getCorrelationType() == null) {
537  throw new EamDbException("Correlation type is null");
538  }
539  if(eamArtifact.getCorrelationValue() == null) {
540  throw new EamDbException("Correlation value is null");
541  }
542 
543  Connection conn = connect();
544 
545  List<CorrelationAttributeInstance> eamInstances = eamArtifact.getInstances();
546  PreparedStatement preparedStatement = null;
547 
548  // @@@ We should cache the case and data source IDs in memory
549  String tableName = EamDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
550  StringBuilder sql = new StringBuilder();
551  sql.append("INSERT INTO ");
552  sql.append(tableName);
553  sql.append("(case_id, data_source_id, value, file_path, known_status, comment) ");
554  sql.append("VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), ");
555  sql.append("(SELECT id FROM data_sources WHERE device_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?) ");
556  sql.append(getConflictClause());
557 
558  try {
559  preparedStatement = conn.prepareStatement(sql.toString());
560  for (CorrelationAttributeInstance eamInstance : eamInstances) {
561  if (!eamArtifact.getCorrelationValue().isEmpty()) {
562  if(eamInstance.getCorrelationCase() == null) {
563  throw new EamDbException("CorrelationAttributeInstance has null case");
564  }
565  if(eamInstance.getCorrelationDataSource() == null) {
566  throw new EamDbException("CorrelationAttributeInstance has null data source");
567  }
568  if(eamInstance.getKnownStatus() == null) {
569  throw new EamDbException("CorrelationAttributeInstance has null known status");
570  }
571 
572  preparedStatement.setString(1, eamInstance.getCorrelationCase().getCaseUUID());
573  preparedStatement.setString(2, eamInstance.getCorrelationDataSource().getDeviceID());
574  preparedStatement.setInt(3, eamInstance.getCorrelationDataSource().getCaseID());
575  preparedStatement.setString(4, eamArtifact.getCorrelationValue());
576  preparedStatement.setString(5, eamInstance.getFilePath());
577  preparedStatement.setByte(6, eamInstance.getKnownStatus().getFileKnownValue());
578  if ("".equals(eamInstance.getComment())) {
579  preparedStatement.setNull(7, Types.INTEGER);
580  } else {
581  preparedStatement.setString(7, eamInstance.getComment());
582  }
583 
584  preparedStatement.executeUpdate();
585  }
586  }
587  } catch (SQLException ex) {
588  throw new EamDbException("Error inserting new artifact into artifacts table.", ex); // NON-NLS
589  } finally {
590  EamDbUtil.closePreparedStatement(preparedStatement);
592  }
593  }
594 
606  @Override
607  public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
608  if(aType == null) {
609  throw new EamDbException("Correlation type is null");
610  }
611  Connection conn = connect();
612 
613  List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>();
614 
615  CorrelationAttributeInstance artifactInstance;
616  PreparedStatement preparedStatement = null;
617  ResultSet resultSet = null;
618 
619  String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType);
620  StringBuilder sql = new StringBuilder();
621  sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id FROM ");
622  sql.append(tableName);
623  sql.append(" LEFT JOIN cases ON ");
624  sql.append(tableName);
625  sql.append(".case_id=cases.id");
626  sql.append(" LEFT JOIN data_sources ON ");
627  sql.append(tableName);
628  sql.append(".data_source_id=data_sources.id");
629  sql.append(" WHERE value=?");
630 
631  try {
632  preparedStatement = conn.prepareStatement(sql.toString());
633  preparedStatement.setString(1, value);
634  resultSet = preparedStatement.executeQuery();
635  while (resultSet.next()) {
636  artifactInstance = getEamArtifactInstanceFromResultSet(resultSet);
637  artifactInstances.add(artifactInstance);
638  }
639  } catch (SQLException ex) {
640  throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS
641  } finally {
642  EamDbUtil.closePreparedStatement(preparedStatement);
643  EamDbUtil.closeResultSet(resultSet);
645  }
646 
647  return artifactInstances;
648  }
649 
661  @Override
662  public List<CorrelationAttributeInstance> getArtifactInstancesByPath(CorrelationAttribute.Type aType, String filePath) throws EamDbException {
663  if(aType == null) {
664  throw new EamDbException("Correlation type is null");
665  }
666  if(filePath == null) {
667  throw new EamDbException("Correlation value is null");
668  }
669  Connection conn = connect();
670 
671  List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>();
672 
673  CorrelationAttributeInstance artifactInstance;
674  PreparedStatement preparedStatement = null;
675  ResultSet resultSet = null;
676 
677  String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType);
678  StringBuilder sql = new StringBuilder();
679  sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id FROM ");
680  sql.append(tableName);
681  sql.append(" LEFT JOIN cases ON ");
682  sql.append(tableName);
683  sql.append(".case_id=cases.id");
684  sql.append(" LEFT JOIN data_sources ON ");
685  sql.append(tableName);
686  sql.append(".data_source_id=data_sources.id");
687  sql.append(" WHERE file_path=?");
688 
689  try {
690  preparedStatement = conn.prepareStatement(sql.toString());
691  preparedStatement.setString(1, filePath.toLowerCase());
692  resultSet = preparedStatement.executeQuery();
693  while (resultSet.next()) {
694  artifactInstance = getEamArtifactInstanceFromResultSet(resultSet);
695  artifactInstances.add(artifactInstance);
696  }
697  } catch (SQLException ex) {
698  throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS
699  } finally {
700  EamDbUtil.closePreparedStatement(preparedStatement);
701  EamDbUtil.closeResultSet(resultSet);
703  }
704 
705  return artifactInstances;
706  }
707 
718  @Override
720  if(aType == null) {
721  throw new EamDbException("Correlation type is null");
722  }
723  if(value == null) {
724  throw new EamDbException("Correlation value is null");
725  }
726 
727  Connection conn = connect();
728 
729  Long instanceCount = 0L;
730  PreparedStatement preparedStatement = null;
731  ResultSet resultSet = null;
732 
733  String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType);
734  StringBuilder sql = new StringBuilder();
735  sql.append("SELECT count(*) FROM ");
736  sql.append(tableName);
737  sql.append(" WHERE value=?");
738 
739  try {
740  preparedStatement = conn.prepareStatement(sql.toString());
741  preparedStatement.setString(1, value.toLowerCase());
742  resultSet = preparedStatement.executeQuery();
743  resultSet.next();
744  instanceCount = resultSet.getLong(1);
745  } catch (SQLException ex) {
746  throw new EamDbException("Error getting count of artifact instances by artifactType and artifactValue.", ex); // NON-NLS
747  } finally {
748  EamDbUtil.closePreparedStatement(preparedStatement);
749  EamDbUtil.closeResultSet(resultSet);
751  }
752 
753  return instanceCount;
754  }
755 
756  @Override
758  if (corAttr == null) {
759  throw new EamDbException("Correlation attribute is null");
760  }
761  Double uniqueTypeValueTuples = getCountUniqueCaseDataSourceTuplesHavingTypeValue(corAttr.getCorrelationType(), corAttr.getCorrelationValue()).doubleValue();
762  Double uniqueCaseDataSourceTuples = getCountUniqueDataSources().doubleValue();
763  Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100;
764  return commonalityPercentage.intValue();
765  }
766 
777  @Override
779  if(aType == null) {
780  throw new EamDbException("Correlation type is null");
781  }
782 
783  Connection conn = connect();
784 
785  Long instanceCount = 0L;
786  PreparedStatement preparedStatement = null;
787  ResultSet resultSet = null;
788 
789  String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType);
790  StringBuilder sql = new StringBuilder();
791  sql.append("SELECT count(*) FROM (SELECT DISTINCT case_id, data_source_id FROM ");
792  sql.append(tableName);
793  sql.append(" WHERE value=?) AS ");
794  sql.append(tableName);
795  sql.append("_distinct_case_data_source_tuple");
796 
797  try {
798  preparedStatement = conn.prepareStatement(sql.toString());
799  preparedStatement.setString(1, value);
800  resultSet = preparedStatement.executeQuery();
801  resultSet.next();
802  instanceCount = resultSet.getLong(1);
803  } catch (SQLException ex) {
804  throw new EamDbException("Error counting unique caseDisplayName/dataSource tuples having artifactType and artifactValue.", ex); // NON-NLS
805  } finally {
806  EamDbUtil.closePreparedStatement(preparedStatement);
807  EamDbUtil.closeResultSet(resultSet);
809  }
810 
811  return instanceCount;
812  }
813 
814  @Override
816  Connection conn = connect();
817 
818  Long instanceCount = 0L;
819  PreparedStatement preparedStatement = null;
820  ResultSet resultSet = null;
821 
822  String stmt = "SELECT count(*) FROM data_sources";
823 
824  try {
825  preparedStatement = conn.prepareStatement(stmt);
826  resultSet = preparedStatement.executeQuery();
827  resultSet.next();
828  instanceCount = resultSet.getLong(1);
829  } catch (SQLException ex) {
830  throw new EamDbException("Error counting data sources.", ex); // NON-NLS
831  } finally {
832  EamDbUtil.closePreparedStatement(preparedStatement);
833  EamDbUtil.closeResultSet(resultSet);
835  }
836 
837  return instanceCount;
838  }
839 
851  @Override
852  public Long getCountArtifactInstancesByCaseDataSource(String caseUUID, String dataSourceID) throws EamDbException {
853  Connection conn = connect();
854 
855  Long instanceCount = 0L;
856  List<CorrelationAttribute.Type> artifactTypes = getDefinedCorrelationTypes();
857  PreparedStatement preparedStatement = null;
858  ResultSet resultSet = null;
859 
860  // Figure out sql variables or subqueries
861  StringBuilder sql = new StringBuilder();
862  sql.append("SELECT 0 ");
863 
864  for (CorrelationAttribute.Type type : artifactTypes) {
865  String table_name = EamDbUtil.correlationTypeToInstanceTableName(type);
866 
867  sql.append("+ (SELECT count(*) FROM ");
868  sql.append(table_name);
869  sql.append(" WHERE case_id=(SELECT id FROM cases WHERE case_uid=?) and data_source_id=(SELECT id FROM data_sources WHERE device_id=?))");
870  }
871 
872  try {
873  preparedStatement = conn.prepareStatement(sql.toString());
874 
875  for (int i = 0; i < artifactTypes.size(); ++i) {
876  preparedStatement.setString(2 * i + 1, caseUUID);
877  preparedStatement.setString(2 * i + 2, dataSourceID);
878  }
879 
880  resultSet = preparedStatement.executeQuery();
881  resultSet.next();
882  instanceCount = resultSet.getLong(1);
883  } catch (SQLException ex) {
884  throw new EamDbException("Error counting artifact instances by caseName/dataSource.", ex); // NON-NLS
885  } finally {
886  EamDbUtil.closePreparedStatement(preparedStatement);
887  EamDbUtil.closeResultSet(resultSet);
889  }
890 
891  return instanceCount;
892  }
893 
901  @Override
902  public void prepareBulkArtifact(CorrelationAttribute eamArtifact) throws EamDbException {
903 
904  if(eamArtifact.getCorrelationType() == null) {
905  throw new EamDbException("Correlation type is null");
906  }
907 
908  synchronized (bulkArtifacts) {
909  bulkArtifacts.get(eamArtifact.getCorrelationType().getDbTableName()).add(eamArtifact);
910  bulkArtifactsCount++;
911 
912  if (bulkArtifactsCount >= bulkArtifactsThreshold) {
914  }
915  }
916  }
917 
923  protected abstract String getConflictClause();
924 
929  @Override
930  public void bulkInsertArtifacts() throws EamDbException {
931  List<CorrelationAttribute.Type> artifactTypes = getDefinedCorrelationTypes();
932 
933  Connection conn = connect();
934  PreparedStatement bulkPs = null;
935 
936  try {
937  synchronized (bulkArtifacts) {
938  if (bulkArtifactsCount == 0) {
939  return;
940  }
941 
942  for (CorrelationAttribute.Type type : artifactTypes) {
943 
944  String tableName = EamDbUtil.correlationTypeToInstanceTableName(type);
945  StringBuilder sql = new StringBuilder();
946  sql.append("INSERT INTO ");
947  sql.append(tableName);
948  sql.append(" (case_id, data_source_id, value, file_path, known_status, comment) ");
949  sql.append("VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), ");
950  sql.append("(SELECT id FROM data_sources WHERE device_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?) ");
951  sql.append(getConflictClause());
952 
953  bulkPs = conn.prepareStatement(sql.toString());
954 
955  Collection<CorrelationAttribute> eamArtifacts = bulkArtifacts.get(type.getDbTableName());
956  for (CorrelationAttribute eamArtifact : eamArtifacts) {
957  List<CorrelationAttributeInstance> eamInstances = eamArtifact.getInstances();
958 
959  for (CorrelationAttributeInstance eamInstance : eamInstances) {
960  if (!eamArtifact.getCorrelationValue().isEmpty()) {
961 
962  if(eamInstance.getCorrelationCase() == null) {
963  throw new EamDbException("Correlation attribute instance has null case");
964  }
965  if(eamInstance.getCorrelationDataSource() == null) {
966  throw new EamDbException("Correlation attribute instance has null data source");
967  }
968  if(eamInstance.getKnownStatus()== null) {
969  throw new EamDbException("Correlation attribute instance has null known known status");
970  }
971 
972  bulkPs.setString(1, eamInstance.getCorrelationCase().getCaseUUID());
973  bulkPs.setString(2, eamInstance.getCorrelationDataSource().getDeviceID());
974  bulkPs.setInt(3, eamInstance.getCorrelationDataSource().getCaseID());
975  bulkPs.setString(4, eamArtifact.getCorrelationValue());
976  bulkPs.setString(5, eamInstance.getFilePath());
977  bulkPs.setByte(6, eamInstance.getKnownStatus().getFileKnownValue());
978  if ("".equals(eamInstance.getComment())) {
979  bulkPs.setNull(7, Types.INTEGER);
980  } else {
981  bulkPs.setString(7, eamInstance.getComment());
982  }
983  bulkPs.addBatch();
984  }
985  }
986  }
987 
988  bulkPs.executeBatch();
989  bulkArtifacts.get(type.getDbTableName()).clear();
990  }
991 
992  // Reset state
993  bulkArtifactsCount = 0;
994  }
995  } catch (SQLException ex) {
996  throw new EamDbException("Error inserting bulk artifacts.", ex); // NON-NLS
997  } finally {
1000  }
1001  }
1002 
1006  @Override
1007  public void bulkInsertCases(List<CorrelationCase> cases) throws EamDbException {
1008  if(cases == null) {
1009  throw new EamDbException("cases argument is null");
1010  }
1011 
1012  if (cases.isEmpty()) {
1013  return;
1014  }
1015 
1016  Connection conn = connect();
1017 
1018  int counter = 0;
1019  PreparedStatement bulkPs = null;
1020  try {
1021  String sql = "INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, "
1022  + "examiner_name, examiner_email, examiner_phone, notes) "
1023  + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) "
1024  + getConflictClause();
1025  bulkPs = conn.prepareStatement(sql);
1026 
1027  for (CorrelationCase eamCase : cases) {
1028  bulkPs.setString(1, eamCase.getCaseUUID());
1029  if (null == eamCase.getOrg()) {
1030  bulkPs.setNull(2, Types.INTEGER);
1031  } else {
1032  bulkPs.setInt(2, eamCase.getOrg().getOrgID());
1033  }
1034  bulkPs.setString(3, eamCase.getDisplayName());
1035  bulkPs.setString(4, eamCase.getCreationDate());
1036 
1037  if ("".equals(eamCase.getCaseNumber())) {
1038  bulkPs.setNull(5, Types.INTEGER);
1039  } else {
1040  bulkPs.setString(5, eamCase.getCaseNumber());
1041  }
1042  if ("".equals(eamCase.getExaminerName())) {
1043  bulkPs.setNull(6, Types.INTEGER);
1044  } else {
1045  bulkPs.setString(6, eamCase.getExaminerName());
1046  }
1047  if ("".equals(eamCase.getExaminerEmail())) {
1048  bulkPs.setNull(7, Types.INTEGER);
1049  } else {
1050  bulkPs.setString(7, eamCase.getExaminerEmail());
1051  }
1052  if ("".equals(eamCase.getExaminerPhone())) {
1053  bulkPs.setNull(8, Types.INTEGER);
1054  } else {
1055  bulkPs.setString(8, eamCase.getExaminerPhone());
1056  }
1057  if ("".equals(eamCase.getNotes())) {
1058  bulkPs.setNull(9, Types.INTEGER);
1059  } else {
1060  bulkPs.setString(9, eamCase.getNotes());
1061  }
1062 
1063  bulkPs.addBatch();
1064 
1065  counter++;
1066 
1067  // limit a batch's max size to bulkArtifactsThreshold
1068  if (counter >= bulkArtifactsThreshold) {
1069  bulkPs.executeBatch();
1070  counter = 0;
1071  }
1072  }
1073  // send the remaining batch records
1074  bulkPs.executeBatch();
1075  } catch (SQLException ex) {
1076  throw new EamDbException("Error inserting bulk cases.", ex); // NON-NLS
1077  } finally {
1079  EamDbUtil.closeConnection(conn);
1080  }
1081  }
1082 
1093  @Override
1094  public void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus) throws EamDbException {
1095  if(eamArtifact == null) {
1096  throw new EamDbException("Correlation attribute is null");
1097  }
1098  if(knownStatus == null) {
1099  throw new EamDbException("Known status is null");
1100  }
1101  if (1 != eamArtifact.getInstances().size()) {
1102  throw new EamDbException("Error: Artifact must have exactly one (1) Artifact Instance to set as notable."); // NON-NLS
1103  }
1104 
1105  List<CorrelationAttributeInstance> eamInstances = eamArtifact.getInstances();
1106  CorrelationAttributeInstance eamInstance = eamInstances.get(0);
1107 
1108  if(eamInstance.getCorrelationCase() == null) {
1109  throw new EamDbException("Correlation case is null");
1110  }
1111  if(eamInstance.getCorrelationDataSource() == null) {
1112  throw new EamDbException("Correlation data source is null");
1113  }
1114 
1115  Connection conn = connect();
1116 
1117  PreparedStatement preparedUpdate = null;
1118  PreparedStatement preparedQuery = null;
1119  ResultSet resultSet = null;
1120 
1121  String tableName = EamDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
1122 
1123  StringBuilder sqlQuery = new StringBuilder();
1124  sqlQuery.append("SELECT id FROM ");
1125  sqlQuery.append(tableName);
1126  sqlQuery.append(" WHERE case_id=(SELECT id FROM cases WHERE case_uid=?) ");
1127  sqlQuery.append("AND data_source_id=(SELECT id FROM data_sources WHERE device_id=?) ");
1128  sqlQuery.append("AND value=? ");
1129  sqlQuery.append("AND file_path=?");
1130 
1131  StringBuilder sqlUpdate = new StringBuilder();
1132  sqlUpdate.append("UPDATE ");
1133  sqlUpdate.append(tableName);
1134  sqlUpdate.append(" SET known_status=?, comment=? ");
1135  sqlUpdate.append("WHERE id=?");
1136 
1137  try {
1138  preparedQuery = conn.prepareStatement(sqlQuery.toString());
1139  preparedQuery.setString(1, eamInstance.getCorrelationCase().getCaseUUID());
1140  preparedQuery.setString(2, eamInstance.getCorrelationDataSource().getDeviceID());
1141  preparedQuery.setString(3, eamArtifact.getCorrelationValue());
1142  preparedQuery.setString(4, eamInstance.getFilePath());
1143  resultSet = preparedQuery.executeQuery();
1144  if (resultSet.next()) {
1145  int instance_id = resultSet.getInt("id");
1146  preparedUpdate = conn.prepareStatement(sqlUpdate.toString());
1147 
1148  preparedUpdate.setByte(1, knownStatus.getFileKnownValue());
1149  // NOTE: if the user tags the same instance as BAD multiple times,
1150  // the comment from the most recent tagging is the one that will
1151  // prevail in the DB.
1152  if ("".equals(eamInstance.getComment())) {
1153  preparedUpdate.setNull(2, Types.INTEGER);
1154  } else {
1155  preparedUpdate.setString(2, eamInstance.getComment());
1156  }
1157  preparedUpdate.setInt(3, instance_id);
1158 
1159  preparedUpdate.executeUpdate();
1160  } else {
1161  // In this case, the user is tagging something that isn't in the database,
1162  // which means the case and/or datasource may also not be in the database.
1163  // We could improve effiency by keeping a list of all datasources and cases
1164  // in the database, but we don't expect the user to be tagging large numbers
1165  // of items (that didn't have the CE ingest module run on them) at once.
1166  CorrelationCase correlationCaseWithId = getCaseByUUID(eamInstance.getCorrelationCase().getCaseUUID());
1167  if (null == correlationCaseWithId) {
1168  correlationCaseWithId = newCase(eamInstance.getCorrelationCase());
1169  }
1170 
1171  if (null == getDataSource(correlationCaseWithId, eamInstance.getCorrelationDataSource().getDeviceID())) {
1172  newDataSource(eamInstance.getCorrelationDataSource());
1173  }
1174  eamArtifact.getInstances().get(0).setKnownStatus(knownStatus);
1175  addArtifact(eamArtifact);
1176  }
1177 
1178  } catch (SQLException ex) {
1179  throw new EamDbException("Error getting/setting artifact instance knownStatus=" + knownStatus.getName(), ex); // NON-NLS
1180  } finally {
1181  EamDbUtil.closePreparedStatement(preparedUpdate);
1182  EamDbUtil.closePreparedStatement(preparedQuery);
1183  EamDbUtil.closeResultSet(resultSet);
1184  EamDbUtil.closeConnection(conn);
1185  }
1186  }
1187 
1197  @Override
1198  public List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
1199  if(aType == null) {
1200  throw new EamDbException("Correlation type is null");
1201  }
1202 
1203  Connection conn = connect();
1204 
1205  List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>();
1206 
1207  CorrelationAttributeInstance artifactInstance;
1208  PreparedStatement preparedStatement = null;
1209  ResultSet resultSet = null;
1210 
1211  String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType);
1212  StringBuilder sql = new StringBuilder();
1213  sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id FROM ");
1214  sql.append(tableName);
1215  sql.append(" LEFT JOIN cases ON ");
1216  sql.append(tableName);
1217  sql.append(".case_id=cases.id");
1218  sql.append(" LEFT JOIN data_sources ON ");
1219  sql.append(tableName);
1220  sql.append(".data_source_id=data_sources.id");
1221  sql.append(" WHERE value=? AND known_status=?");
1222 
1223  try {
1224  preparedStatement = conn.prepareStatement(sql.toString());
1225  preparedStatement.setString(1, value);
1226  preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
1227  resultSet = preparedStatement.executeQuery();
1228  while (resultSet.next()) {
1229  artifactInstance = getEamArtifactInstanceFromResultSet(resultSet);
1230  artifactInstances.add(artifactInstance);
1231  }
1232  } catch (SQLException ex) {
1233  throw new EamDbException("Error getting notable artifact instances.", ex); // NON-NLS
1234  } finally {
1235  EamDbUtil.closePreparedStatement(preparedStatement);
1236  EamDbUtil.closeResultSet(resultSet);
1237  EamDbUtil.closeConnection(conn);
1238  }
1239 
1240  return artifactInstances;
1241  }
1242 
1251  @Override
1253  if(aType == null) {
1254  throw new EamDbException("Correlation type is null");
1255  }
1256 
1257  Connection conn = connect();
1258 
1259  Long badInstances = 0L;
1260  PreparedStatement preparedStatement = null;
1261  ResultSet resultSet = null;
1262 
1263  String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType);
1264  StringBuilder sql = new StringBuilder();
1265  sql.append("SELECT count(*) FROM ");
1266  sql.append(tableName);
1267  sql.append(" WHERE value=? AND known_status=?");
1268 
1269  try {
1270  preparedStatement = conn.prepareStatement(sql.toString());
1271  preparedStatement.setString(1, value);
1272  preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
1273  resultSet = preparedStatement.executeQuery();
1274  resultSet.next();
1275  badInstances = resultSet.getLong(1);
1276  } catch (SQLException ex) {
1277  throw new EamDbException("Error getting count of notable artifact instances.", ex); // NON-NLS
1278  } finally {
1279  EamDbUtil.closePreparedStatement(preparedStatement);
1280  EamDbUtil.closeResultSet(resultSet);
1281  EamDbUtil.closeConnection(conn);
1282  }
1283 
1284  return badInstances;
1285  }
1286 
1299  @Override
1301  if(aType == null) {
1302  throw new EamDbException("Correlation type is null");
1303  }
1304 
1305  Connection conn = connect();
1306 
1307  Collection<String> caseNames = new LinkedHashSet<>();
1308 
1309  PreparedStatement preparedStatement = null;
1310  ResultSet resultSet = null;
1311 
1312  String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType);
1313  StringBuilder sql = new StringBuilder();
1314  sql.append("SELECT DISTINCT case_name FROM ");
1315  sql.append(tableName);
1316  sql.append(" INNER JOIN cases ON ");
1317  sql.append(tableName);
1318  sql.append(".case_id=cases.id WHERE ");
1319  sql.append(tableName);
1320  sql.append(".value=? AND ");
1321  sql.append(tableName);
1322  sql.append(".known_status=?");
1323 
1324  try {
1325  preparedStatement = conn.prepareStatement(sql.toString());
1326  preparedStatement.setString(1, value);
1327  preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
1328  resultSet = preparedStatement.executeQuery();
1329  while (resultSet.next()) {
1330  caseNames.add(resultSet.getString("case_name"));
1331  }
1332  } catch (SQLException ex) {
1333  throw new EamDbException("Error getting notable artifact instances.", ex); // NON-NLS
1334  } finally {
1335  EamDbUtil.closePreparedStatement(preparedStatement);
1336  EamDbUtil.closeResultSet(resultSet);
1337  EamDbUtil.closeConnection(conn);
1338  }
1339 
1340  return caseNames.stream().collect(Collectors.toList());
1341  }
1342 
1349  @Override
1350  public void deleteReferenceSet(int referenceSetID) throws EamDbException {
1351  deleteReferenceSetEntries(referenceSetID);
1352  deleteReferenceSetEntry(referenceSetID);
1353  }
1354 
1361  private void deleteReferenceSetEntry(int referenceSetID) throws EamDbException {
1362  Connection conn = connect();
1363 
1364  PreparedStatement preparedStatement = null;
1365  String sql = "DELETE FROM reference_sets WHERE id=?";
1366 
1367  try {
1368  preparedStatement = conn.prepareStatement(sql);
1369  preparedStatement.setInt(1, referenceSetID);
1370  preparedStatement.executeUpdate();
1371  } catch (SQLException ex) {
1372  throw new EamDbException("Error deleting reference set " + referenceSetID, ex); // NON-NLS
1373  } finally {
1374  EamDbUtil.closePreparedStatement(preparedStatement);
1375  EamDbUtil.closeConnection(conn);
1376  }
1377  }
1378 
1386  private void deleteReferenceSetEntries(int referenceSetID) throws EamDbException {
1387  Connection conn = connect();
1388 
1389  PreparedStatement preparedStatement = null;
1390  String sql = "DELETE FROM %s WHERE reference_set_id=?";
1391 
1392  // When other reference types are added, this will need to loop over all the tables
1394 
1395  try {
1396  preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
1397  preparedStatement.setInt(1, referenceSetID);
1398  preparedStatement.executeUpdate();
1399  } catch (SQLException ex) {
1400  throw new EamDbException("Error deleting files from reference set " + referenceSetID, ex); // NON-NLS
1401  } finally {
1402  EamDbUtil.closePreparedStatement(preparedStatement);
1403  EamDbUtil.closeConnection(conn);
1404  }
1405  }
1406 
1418  @Override
1419  public boolean referenceSetIsValid(int referenceSetID, String setName, String version) throws EamDbException {
1420  EamGlobalSet refSet = this.getReferenceSetByID(referenceSetID);
1421  if(refSet == null) {
1422  return false;
1423  }
1424 
1425  return (refSet.getSetName().equals(setName) && refSet.getVersion().equals(version));
1426  }
1427 
1437  @Override
1438  public boolean isFileHashInReferenceSet(String hash, int referenceSetID) throws EamDbException {
1439  return isValueInReferenceSet(hash, referenceSetID, CorrelationAttribute.FILES_TYPE_ID);
1440  }
1441 
1450  @Override
1451  public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException {
1452 
1453  Connection conn = connect();
1454 
1455  Long matchingInstances = 0L;
1456  PreparedStatement preparedStatement = null;
1457  ResultSet resultSet = null;
1458  String sql = "SELECT count(*) FROM %s WHERE value=? AND reference_set_id=?";
1459 
1460  String fileTableName = EamDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(correlationTypeID));
1461 
1462  try {
1463  preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
1464  preparedStatement.setString(1, value);
1465  preparedStatement.setInt(2, referenceSetID);
1466  resultSet = preparedStatement.executeQuery();
1467  resultSet.next();
1468  matchingInstances = resultSet.getLong(1);
1469  } catch (SQLException ex) {
1470  throw new EamDbException("Error determining if value (" + value + ") is in reference set " + referenceSetID, ex); // NON-NLS
1471  } finally {
1472  EamDbUtil.closePreparedStatement(preparedStatement);
1473  EamDbUtil.closeResultSet(resultSet);
1474  EamDbUtil.closeConnection(conn);
1475  }
1476 
1477  return 0 < matchingInstances;
1478  }
1479 
1488  @Override
1489  public boolean isArtifactKnownBadByReference(CorrelationAttribute.Type aType, String value) throws EamDbException {
1490  if(aType == null) {
1491  throw new EamDbException("null correlation type");
1492  }
1493 
1494  // TEMP: Only support file correlation type
1495  if (aType.getId() != CorrelationAttribute.FILES_TYPE_ID) {
1496  return false;
1497  }
1498 
1499  Connection conn = connect();
1500 
1501  Long badInstances = 0L;
1502  PreparedStatement preparedStatement = null;
1503  ResultSet resultSet = null;
1504  String sql = "SELECT count(*) FROM %s WHERE value=? AND known_status=?";
1505 
1506  try {
1507  preparedStatement = conn.prepareStatement(String.format(sql, EamDbUtil.correlationTypeToReferenceTableName(aType)));
1508  preparedStatement.setString(1, value);
1509  preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
1510  resultSet = preparedStatement.executeQuery();
1511  resultSet.next();
1512  badInstances = resultSet.getLong(1);
1513  } catch (SQLException ex) {
1514  throw new EamDbException("Error determining if artifact is notable by reference.", ex); // NON-NLS
1515  } finally {
1516  EamDbUtil.closePreparedStatement(preparedStatement);
1517  EamDbUtil.closeResultSet(resultSet);
1518  EamDbUtil.closeConnection(conn);
1519  }
1520 
1521  return 0 < badInstances;
1522  }
1523 
1533  @Override
1534  public long newOrganization(EamOrganization eamOrg) throws EamDbException {
1535  if(eamOrg == null) {
1536  throw new EamDbException("EamOrganization is null");
1537  }
1538 
1539  Connection conn = connect();
1540  ResultSet generatedKeys = null;
1541  PreparedStatement preparedStatement = null;
1542  String sql = "INSERT INTO organizations(org_name, poc_name, poc_email, poc_phone) VALUES (?, ?, ?, ?) "
1543  + getConflictClause();
1544 
1545  try {
1546  preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
1547  preparedStatement.setString(1, eamOrg.getName());
1548  preparedStatement.setString(2, eamOrg.getPocName());
1549  preparedStatement.setString(3, eamOrg.getPocEmail());
1550  preparedStatement.setString(4, eamOrg.getPocPhone());
1551 
1552  preparedStatement.executeUpdate();
1553  generatedKeys = preparedStatement.getGeneratedKeys();
1554  if (generatedKeys.next()) {
1555  return generatedKeys.getLong(1);
1556  } else {
1557  throw new SQLException("Creating user failed, no ID obtained.");
1558  }
1559  } catch (SQLException ex) {
1560  throw new EamDbException("Error inserting new organization.", ex); // NON-NLS
1561  } finally {
1562  EamDbUtil.closePreparedStatement(preparedStatement);
1563  EamDbUtil.closeResultSet(generatedKeys);
1564  EamDbUtil.closeConnection(conn);
1565  }
1566  }
1567 
1575  @Override
1576  public List<EamOrganization> getOrganizations() throws EamDbException {
1577  Connection conn = connect();
1578 
1579  List<EamOrganization> orgs = new ArrayList<>();
1580  PreparedStatement preparedStatement = null;
1581  ResultSet resultSet = null;
1582  String sql = "SELECT * FROM organizations";
1583 
1584  try {
1585  preparedStatement = conn.prepareStatement(sql);
1586  resultSet = preparedStatement.executeQuery();
1587  while (resultSet.next()) {
1588  orgs.add(getEamOrganizationFromResultSet(resultSet));
1589  }
1590  return orgs;
1591 
1592  } catch (SQLException ex) {
1593  throw new EamDbException("Error getting all organizations.", ex); // NON-NLS
1594  } finally {
1595  EamDbUtil.closePreparedStatement(preparedStatement);
1596  EamDbUtil.closeResultSet(resultSet);
1597  EamDbUtil.closeConnection(conn);
1598  }
1599  }
1600 
1610  @Override
1612  Connection conn = connect();
1613 
1614  PreparedStatement preparedStatement = null;
1615  ResultSet resultSet = null;
1616  String sql = "SELECT * FROM organizations WHERE id=?";
1617 
1618  try {
1619  preparedStatement = conn.prepareStatement(sql);
1620  preparedStatement.setInt(1, orgID);
1621  resultSet = preparedStatement.executeQuery();
1622  resultSet.next();
1623  return getEamOrganizationFromResultSet(resultSet);
1624 
1625  } catch (SQLException ex) {
1626  throw new EamDbException("Error getting organization by id.", ex); // NON-NLS
1627  } finally {
1628  EamDbUtil.closePreparedStatement(preparedStatement);
1629  EamDbUtil.closeResultSet(resultSet);
1630  EamDbUtil.closeConnection(conn);
1631  }
1632  }
1633 
1641  @Override
1642  public EamOrganization getReferenceSetOrganization(int referenceSetID) throws EamDbException {
1643 
1644  EamGlobalSet globalSet = getReferenceSetByID(referenceSetID);
1645  if(globalSet == null) {
1646  throw new EamDbException("Reference set with ID " + referenceSetID + " not found");
1647  }
1648  return (getOrganizationByID(globalSet.getOrgID()));
1649  }
1650 
1659  @Override
1660  public void updateOrganization(EamOrganization updatedOrganization) throws EamDbException {
1661  if(updatedOrganization == null) {
1662  throw new EamDbException("null updatedOrganization");
1663  }
1664 
1665  Connection conn = connect();
1666  PreparedStatement preparedStatement = null;
1667  String sql = "UPDATE organizations SET org_name = ?, poc_name = ?, poc_email = ?, poc_phone = ? WHERE id = ?";
1668  try {
1669  preparedStatement = conn.prepareStatement(sql);
1670  preparedStatement.setString(1, updatedOrganization.getName());
1671  preparedStatement.setString(2, updatedOrganization.getPocName());
1672  preparedStatement.setString(3, updatedOrganization.getPocEmail());
1673  preparedStatement.setString(4, updatedOrganization.getPocPhone());
1674  preparedStatement.setInt(5, updatedOrganization.getOrgID());
1675  preparedStatement.executeUpdate();
1676  } catch (SQLException ex) {
1677  throw new EamDbException("Error updating organization.", ex); // NON-NLS
1678  } finally {
1679  EamDbUtil.closePreparedStatement(preparedStatement);
1680  EamDbUtil.closeConnection(conn);
1681  }
1682  }
1683 
1684  @Messages({"AbstractSqlEamDb.deleteOrganization.inUseException.message=Can not delete organization "
1685  + "which is currently in use by a case or reference set in the central repository.",
1686  "AbstractSqlEamDb.deleteOrganization.errorDeleting.message=Error executing query when attempting to delete organization by id."})
1687  @Override
1688  public void deleteOrganization(EamOrganization organizationToDelete) throws EamDbException {
1689  if(organizationToDelete == null) {
1690  throw new EamDbException("Organization to delete is null");
1691  }
1692 
1693  Connection conn = connect();
1694  PreparedStatement checkIfUsedStatement = null;
1695  ResultSet resultSet = null;
1696  String checkIfUsedSql = "SELECT (select count(*) FROM cases WHERE org_id=?) + (select count(*) FROM reference_sets WHERE org_id=?)";
1697  PreparedStatement deleteOrgStatement = null;
1698  String deleteOrgSql = "DELETE FROM organizations WHERE id=?";
1699  try {
1700  checkIfUsedStatement = conn.prepareStatement(checkIfUsedSql);
1701  checkIfUsedStatement.setInt(1, organizationToDelete.getOrgID());
1702  checkIfUsedStatement.setInt(2, organizationToDelete.getOrgID());
1703  resultSet = checkIfUsedStatement.executeQuery();
1704  resultSet.next();
1705  if (resultSet.getLong(1) > 0) {
1706  throw new EamDbException(Bundle.AbstractSqlEamDb_deleteOrganization_inUseException_message());
1707  }
1708  deleteOrgStatement = conn.prepareStatement(deleteOrgSql);
1709  deleteOrgStatement.setInt(1, organizationToDelete.getOrgID());
1710  deleteOrgStatement.executeUpdate();
1711  } catch (SQLException ex) {
1712  throw new EamDbException(Bundle.AbstractSqlEamDb_deleteOrganization_errorDeleting_message(), ex); // NON-NLS
1713  } finally {
1714  EamDbUtil.closePreparedStatement(checkIfUsedStatement);
1715  EamDbUtil.closePreparedStatement(deleteOrgStatement);
1716  EamDbUtil.closeResultSet(resultSet);
1717  EamDbUtil.closeConnection(conn);
1718  }
1719  }
1720 
1730  @Override
1731  public int newReferenceSet(EamGlobalSet eamGlobalSet) throws EamDbException {
1732  if(eamGlobalSet == null){
1733  throw new EamDbException("EamGlobalSet argument is null");
1734  }
1735 
1736  if(eamGlobalSet.getFileKnownStatus() == null){
1737  throw new EamDbException("File known status on the EamGlobalSet is null");
1738  }
1739 
1740  if(eamGlobalSet.getType() == null){
1741  throw new EamDbException("Type on the EamGlobalSet is null");
1742  }
1743 
1744  Connection conn = connect();
1745 
1746  PreparedStatement preparedStatement1 = null;
1747  PreparedStatement preparedStatement2 = null;
1748  ResultSet resultSet = null;
1749  String sql1 = "INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, type, import_date) VALUES (?, ?, ?, ?, ?, ?, ?) "
1750  + getConflictClause();
1751  String sql2 = "SELECT id FROM reference_sets WHERE org_id=? AND set_name=? AND version=? AND import_date=? LIMIT 1";
1752 
1753  try {
1754  preparedStatement1 = conn.prepareStatement(sql1);
1755  preparedStatement1.setInt(1, eamGlobalSet.getOrgID());
1756  preparedStatement1.setString(2, eamGlobalSet.getSetName());
1757  preparedStatement1.setString(3, eamGlobalSet.getVersion());
1758  preparedStatement1.setInt(4, eamGlobalSet.getFileKnownStatus().getFileKnownValue());
1759  preparedStatement1.setBoolean(5, eamGlobalSet.isReadOnly());
1760  preparedStatement1.setInt(6, eamGlobalSet.getType().getId());
1761  preparedStatement1.setString(7, eamGlobalSet.getImportDate().toString());
1762 
1763  preparedStatement1.executeUpdate();
1764 
1765  preparedStatement2 = conn.prepareStatement(sql2);
1766  preparedStatement2.setInt(1, eamGlobalSet.getOrgID());
1767  preparedStatement2.setString(2, eamGlobalSet.getSetName());
1768  preparedStatement2.setString(3, eamGlobalSet.getVersion());
1769  preparedStatement2.setString(4, eamGlobalSet.getImportDate().toString());
1770 
1771  resultSet = preparedStatement2.executeQuery();
1772  resultSet.next();
1773  return resultSet.getInt("id");
1774 
1775  } catch (SQLException ex) {
1776  throw new EamDbException("Error inserting new global set.", ex); // NON-NLS
1777  } finally {
1778  EamDbUtil.closePreparedStatement(preparedStatement1);
1779  EamDbUtil.closePreparedStatement(preparedStatement2);
1780  EamDbUtil.closeResultSet(resultSet);
1781  EamDbUtil.closeConnection(conn);
1782  }
1783  }
1784 
1794  @Override
1795  public EamGlobalSet getReferenceSetByID(int referenceSetID) throws EamDbException {
1796  Connection conn = connect();
1797 
1798  PreparedStatement preparedStatement1 = null;
1799  ResultSet resultSet = null;
1800  String sql1 = "SELECT * FROM reference_sets WHERE id=?";
1801 
1802  try {
1803  preparedStatement1 = conn.prepareStatement(sql1);
1804  preparedStatement1.setInt(1, referenceSetID);
1805  resultSet = preparedStatement1.executeQuery();
1806  if(resultSet.next()) {
1807  return getEamGlobalSetFromResultSet(resultSet);
1808  } else {
1809  return null;
1810  }
1811 
1812  } catch (SQLException ex) {
1813  throw new EamDbException("Error getting reference set by id.", ex); // NON-NLS
1814  } finally {
1815  EamDbUtil.closePreparedStatement(preparedStatement1);
1816  EamDbUtil.closeResultSet(resultSet);
1817  EamDbUtil.closeConnection(conn);
1818  }
1819  }
1820 
1830  @Override
1831  public List<EamGlobalSet> getAllReferenceSets(CorrelationAttribute.Type correlationType) throws EamDbException {
1832 
1833  if(correlationType == null){
1834  throw new EamDbException("Correlation type is null");
1835  }
1836 
1837  List<EamGlobalSet> results = new ArrayList<>();
1838  Connection conn = connect();
1839 
1840  PreparedStatement preparedStatement1 = null;
1841  ResultSet resultSet = null;
1842  String sql1 = "SELECT * FROM reference_sets WHERE type=" + correlationType.getId();
1843 
1844  try {
1845  preparedStatement1 = conn.prepareStatement(sql1);
1846  resultSet = preparedStatement1.executeQuery();
1847  while (resultSet.next()) {
1848  results.add(getEamGlobalSetFromResultSet(resultSet));
1849  }
1850 
1851  } catch (SQLException ex) {
1852  throw new EamDbException("Error getting reference sets.", ex); // NON-NLS
1853  } finally {
1854  EamDbUtil.closePreparedStatement(preparedStatement1);
1855  EamDbUtil.closeResultSet(resultSet);
1856  EamDbUtil.closeConnection(conn);
1857  }
1858  return results;
1859  }
1860 
1869  @Override
1870  public void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, CorrelationAttribute.Type correlationType) throws EamDbException {
1871  if(eamGlobalFileInstance.getKnownStatus() == null){
1872  throw new EamDbException("known status of EamGlobalFileInstance is null");
1873  }
1874  if(correlationType == null){
1875  throw new EamDbException("Correlation type is null");
1876  }
1877 
1878  Connection conn = connect();
1879 
1880  PreparedStatement preparedStatement = null;
1881 
1882  String sql = "INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) "
1883  + getConflictClause();
1884 
1885  try {
1886  preparedStatement = conn.prepareStatement(String.format(sql, EamDbUtil.correlationTypeToReferenceTableName(correlationType)));
1887  preparedStatement.setInt(1, eamGlobalFileInstance.getGlobalSetID());
1888  preparedStatement.setString(2, eamGlobalFileInstance.getMD5Hash());
1889  preparedStatement.setByte(3, eamGlobalFileInstance.getKnownStatus().getFileKnownValue());
1890  preparedStatement.setString(4, eamGlobalFileInstance.getComment());
1891  preparedStatement.executeUpdate();
1892  } catch (SQLException ex) {
1893  throw new EamDbException("Error inserting new reference instance into reference_ table.", ex); // NON-NLS
1894  } finally {
1895  EamDbUtil.closePreparedStatement(preparedStatement);
1896  EamDbUtil.closeConnection(conn);
1897  }
1898  }
1899 
1910  @Override
1911  public boolean referenceSetExists(String referenceSetName, String version) throws EamDbException {
1912  Connection conn = connect();
1913 
1914  PreparedStatement preparedStatement1 = null;
1915  ResultSet resultSet = null;
1916  String sql1 = "SELECT * FROM reference_sets WHERE set_name=? AND version=?";
1917 
1918  try {
1919  preparedStatement1 = conn.prepareStatement(sql1);
1920  preparedStatement1.setString(1, referenceSetName);
1921  preparedStatement1.setString(2, version);
1922  resultSet = preparedStatement1.executeQuery();
1923  return (resultSet.next());
1924 
1925  } catch (SQLException ex) {
1926  throw new EamDbException("Error testing whether reference set exists (name: " + referenceSetName
1927  + " version: " + version, ex); // NON-NLS
1928  } finally {
1929  EamDbUtil.closePreparedStatement(preparedStatement1);
1930  EamDbUtil.closeResultSet(resultSet);
1931  EamDbUtil.closeConnection(conn);
1932  }
1933  }
1934 
1940  @Override
1941  public void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances, CorrelationAttribute.Type contentType) throws EamDbException {
1942  if(contentType == null) {
1943  throw new EamDbException("Null correlation type");
1944  }
1945  if(globalInstances == null) {
1946  throw new EamDbException("Null set of EamGlobalFileInstance");
1947  }
1948 
1949  Connection conn = connect();
1950 
1951  PreparedStatement bulkPs = null;
1952  try {
1953  conn.setAutoCommit(false);
1954 
1955  // FUTURE: have a separate global_files table for each Type.
1956  String sql = "INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) "
1957  + getConflictClause();
1958 
1959  bulkPs = conn.prepareStatement(String.format(sql, EamDbUtil.correlationTypeToReferenceTableName(contentType)));
1960 
1961  for (EamGlobalFileInstance globalInstance : globalInstances) {
1962  if(globalInstance.getKnownStatus() == null){
1963  throw new EamDbException("EamGlobalFileInstance with value " + globalInstance.getMD5Hash() + " has null known status");
1964  }
1965 
1966  bulkPs.setInt(1, globalInstance.getGlobalSetID());
1967  bulkPs.setString(2, globalInstance.getMD5Hash());
1968  bulkPs.setByte(3, globalInstance.getKnownStatus().getFileKnownValue());
1969  bulkPs.setString(4, globalInstance.getComment());
1970  bulkPs.addBatch();
1971  }
1972 
1973  bulkPs.executeBatch();
1974  conn.commit();
1975  } catch (SQLException | EamDbException ex) {
1976  try {
1977  conn.rollback();
1978  } catch (SQLException ex2) {
1979  // We're alredy in an error state
1980  }
1981  throw new EamDbException("Error inserting bulk artifacts.", ex); // NON-NLS
1982  } finally {
1984  EamDbUtil.closeConnection(conn);
1985  }
1986  }
1987 
1998  @Override
1999  public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(CorrelationAttribute.Type aType, String aValue) throws EamDbException {
2000  if(aType == null) {
2001  throw new EamDbException("correlation type is null");
2002  }
2003 
2004  Connection conn = connect();
2005 
2006  List<EamGlobalFileInstance> globalFileInstances = new ArrayList<>();
2007  PreparedStatement preparedStatement1 = null;
2008  ResultSet resultSet = null;
2009  String sql1 = "SELECT * FROM %s WHERE value=?";
2010 
2011  try {
2012  preparedStatement1 = conn.prepareStatement(String.format(sql1, EamDbUtil.correlationTypeToReferenceTableName(aType)));
2013  preparedStatement1.setString(1, aValue);
2014  resultSet = preparedStatement1.executeQuery();
2015  while (resultSet.next()) {
2016  globalFileInstances.add(getEamGlobalFileInstanceFromResultSet(resultSet));
2017  }
2018  return globalFileInstances;
2019 
2020  } catch (SQLException ex) {
2021  throw new EamDbException("Error getting reference instances by type and value.", ex); // NON-NLS
2022  } finally {
2023  EamDbUtil.closePreparedStatement(preparedStatement1);
2024  EamDbUtil.closeResultSet(resultSet);
2025  EamDbUtil.closeConnection(conn);
2026  }
2027  }
2028 
2038  @Override
2040  if (newType == null) {
2041  throw new EamDbException("null correlation type");
2042  }
2043 
2044  Connection conn = connect();
2045 
2046  PreparedStatement preparedStatement = null;
2047  PreparedStatement preparedStatementQuery = null;
2048  ResultSet resultSet = null;
2049  int typeId = 0;
2050  String insertSql;
2051  String querySql;
2052  // if we have a known ID, use it, if not (is -1) let the db assign it.
2053  if (-1 == newType.getId()) {
2054  insertSql = "INSERT INTO correlation_types(display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?) " + getConflictClause();
2055  } else {
2056  insertSql = "INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause();
2057  }
2058  querySql = "SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
2059 
2060  try {
2061  preparedStatement = conn.prepareStatement(insertSql);
2062 
2063  if (-1 == newType.getId()) {
2064  preparedStatement.setString(1, newType.getDisplayName());
2065  preparedStatement.setString(2, newType.getDbTableName());
2066  preparedStatement.setInt(3, newType.isSupported() ? 1 : 0);
2067  preparedStatement.setInt(4, newType.isEnabled() ? 1 : 0);
2068  } else {
2069  preparedStatement.setInt(1, newType.getId());
2070  preparedStatement.setString(2, newType.getDisplayName());
2071  preparedStatement.setString(3, newType.getDbTableName());
2072  preparedStatement.setInt(4, newType.isSupported() ? 1 : 0);
2073  preparedStatement.setInt(5, newType.isEnabled() ? 1 : 0);
2074  }
2075 
2076  preparedStatement.executeUpdate();
2077 
2078  preparedStatementQuery = conn.prepareStatement(querySql);
2079  preparedStatementQuery.setString(1, newType.getDisplayName());
2080  preparedStatementQuery.setString(2, newType.getDbTableName());
2081 
2082  resultSet = preparedStatementQuery.executeQuery();
2083  if (resultSet.next()) {
2084  CorrelationAttribute.Type correlationType = getCorrelationTypeFromResultSet(resultSet);
2085  typeId = correlationType.getId();
2086  }
2087  } catch (SQLException ex) {
2088  throw new EamDbException("Error inserting new correlation type.", ex); // NON-NLS
2089  } finally {
2090  EamDbUtil.closePreparedStatement(preparedStatement);
2091  EamDbUtil.closePreparedStatement(preparedStatementQuery);
2092  EamDbUtil.closeResultSet(resultSet);
2093  EamDbUtil.closeConnection(conn);
2094  }
2095  return typeId;
2096  }
2097 
2098  @Override
2100  Connection conn = connect();
2101 
2102  List<CorrelationAttribute.Type> aTypes = new ArrayList<>();
2103  PreparedStatement preparedStatement = null;
2104  ResultSet resultSet = null;
2105  String sql = "SELECT * FROM correlation_types";
2106 
2107  try {
2108  preparedStatement = conn.prepareStatement(sql);
2109  resultSet = preparedStatement.executeQuery();
2110  while (resultSet.next()) {
2111  aTypes.add(getCorrelationTypeFromResultSet(resultSet));
2112  }
2113  return aTypes;
2114 
2115  } catch (SQLException ex) {
2116  throw new EamDbException("Error getting all correlation types.", ex); // NON-NLS
2117  } finally {
2118  EamDbUtil.closePreparedStatement(preparedStatement);
2119  EamDbUtil.closeResultSet(resultSet);
2120  EamDbUtil.closeConnection(conn);
2121  }
2122  }
2123 
2133  @Override
2135  Connection conn = connect();
2136 
2137  List<CorrelationAttribute.Type> aTypes = new ArrayList<>();
2138  PreparedStatement preparedStatement = null;
2139  ResultSet resultSet = null;
2140  String sql = "SELECT * FROM correlation_types WHERE enabled=1";
2141 
2142  try {
2143  preparedStatement = conn.prepareStatement(sql);
2144  resultSet = preparedStatement.executeQuery();
2145  while (resultSet.next()) {
2146  aTypes.add(getCorrelationTypeFromResultSet(resultSet));
2147  }
2148  return aTypes;
2149 
2150  } catch (SQLException ex) {
2151  throw new EamDbException("Error getting enabled correlation types.", ex); // NON-NLS
2152  } finally {
2153  EamDbUtil.closePreparedStatement(preparedStatement);
2154  EamDbUtil.closeResultSet(resultSet);
2155  EamDbUtil.closeConnection(conn);
2156  }
2157  }
2158 
2168  @Override
2170  Connection conn = connect();
2171 
2172  List<CorrelationAttribute.Type> aTypes = new ArrayList<>();
2173  PreparedStatement preparedStatement = null;
2174  ResultSet resultSet = null;
2175  String sql = "SELECT * FROM correlation_types WHERE supported=1";
2176 
2177  try {
2178  preparedStatement = conn.prepareStatement(sql);
2179  resultSet = preparedStatement.executeQuery();
2180  while (resultSet.next()) {
2181  aTypes.add(getCorrelationTypeFromResultSet(resultSet));
2182  }
2183  return aTypes;
2184 
2185  } catch (SQLException ex) {
2186  throw new EamDbException("Error getting supported correlation types.", ex); // NON-NLS
2187  } finally {
2188  EamDbUtil.closePreparedStatement(preparedStatement);
2189  EamDbUtil.closeResultSet(resultSet);
2190  EamDbUtil.closeConnection(conn);
2191  }
2192  }
2193 
2201  @Override
2203  Connection conn = connect();
2204 
2205  PreparedStatement preparedStatement = null;
2206  String sql = "UPDATE correlation_types SET display_name=?, db_table_name=?, supported=?, enabled=? WHERE id=?";
2207 
2208  try {
2209  preparedStatement = conn.prepareStatement(sql);
2210  preparedStatement.setString(1, aType.getDisplayName());
2211  preparedStatement.setString(2, aType.getDbTableName());
2212  preparedStatement.setInt(3, aType.isSupported() ? 1 : 0);
2213  preparedStatement.setInt(4, aType.isEnabled() ? 1 : 0);
2214  preparedStatement.setInt(5, aType.getId());
2215  preparedStatement.executeUpdate();
2216 
2217  } catch (SQLException ex) {
2218  throw new EamDbException("Error updating correlation type.", ex); // NON-NLS
2219  } finally {
2220  EamDbUtil.closePreparedStatement(preparedStatement);
2221  EamDbUtil.closeConnection(conn);
2222  }
2223 
2224  }
2225 
2235  @Override
2237  Connection conn = connect();
2238 
2239  CorrelationAttribute.Type aType;
2240  PreparedStatement preparedStatement = null;
2241  ResultSet resultSet = null;
2242  String sql = "SELECT * FROM correlation_types WHERE id=?";
2243 
2244  try {
2245  preparedStatement = conn.prepareStatement(sql);
2246  preparedStatement.setInt(1, typeId);
2247  resultSet = preparedStatement.executeQuery();
2248  if(resultSet.next()) {
2249  aType = getCorrelationTypeFromResultSet(resultSet);
2250  return aType;
2251  } else {
2252  throw new EamDbException("Failed to find entry for correlation type ID = " + typeId);
2253  }
2254 
2255  } catch (SQLException ex) {
2256  throw new EamDbException("Error getting correlation type by id.", ex); // NON-NLS
2257  } finally {
2258  EamDbUtil.closePreparedStatement(preparedStatement);
2259  EamDbUtil.closeResultSet(resultSet);
2260  EamDbUtil.closeConnection(conn);
2261  }
2262  }
2263 
2274  private CorrelationCase getEamCaseFromResultSet(ResultSet resultSet) throws SQLException {
2275  if (null == resultSet) {
2276  return null;
2277  }
2278 
2279  EamOrganization eamOrg = null;
2280 
2281  resultSet.getInt("org_id");
2282  if (!resultSet.wasNull()) {
2283 
2284  eamOrg = new EamOrganization(resultSet.getInt("org_id"),
2285  resultSet.getString("org_name"),
2286  resultSet.getString("poc_name"),
2287  resultSet.getString("poc_email"),
2288  resultSet.getString("poc_phone"));
2289  }
2290 
2291  CorrelationCase eamCase = new CorrelationCase(resultSet.getInt("case_id"), resultSet.getString("case_uid"), resultSet.getString("case_name"));
2292  eamCase.setOrg(eamOrg);
2293  eamCase.setCreationDate(resultSet.getString("creation_date"));
2294  eamCase.setCaseNumber(resultSet.getString("case_number"));
2295  eamCase.setExaminerName(resultSet.getString("examiner_name"));
2296  eamCase.setExaminerEmail(resultSet.getString("examiner_email"));
2297  eamCase.setExaminerPhone(resultSet.getString("examiner_phone"));
2298  eamCase.setNotes(resultSet.getString("notes"));
2299 
2300  return eamCase;
2301  }
2302 
2303  private CorrelationDataSource getEamDataSourceFromResultSet(ResultSet resultSet) throws SQLException {
2304  if (null == resultSet) {
2305  return null;
2306  }
2307 
2308  CorrelationDataSource eamDataSource = new CorrelationDataSource(
2309  resultSet.getInt("case_id"),
2310  resultSet.getInt("id"),
2311  resultSet.getString("device_id"),
2312  resultSet.getString("name")
2313  );
2314 
2315  return eamDataSource;
2316  }
2317 
2318  private CorrelationAttribute.Type getCorrelationTypeFromResultSet(ResultSet resultSet) throws EamDbException, SQLException {
2319  if (null == resultSet) {
2320  return null;
2321  }
2322 
2323  CorrelationAttribute.Type eamArtifactType = new CorrelationAttribute.Type(
2324  resultSet.getInt("id"),
2325  resultSet.getString("display_name"),
2326  resultSet.getString("db_table_name"),
2327  resultSet.getBoolean("supported"),
2328  resultSet.getBoolean("enabled")
2329  );
2330 
2331  return eamArtifactType;
2332  }
2333 
2344  private CorrelationAttributeInstance getEamArtifactInstanceFromResultSet(ResultSet resultSet) throws SQLException, EamDbException {
2345  if (null == resultSet) {
2346  return null;
2347  }
2349  new CorrelationCase(resultSet.getInt("case_id"), resultSet.getString("case_uid"), resultSet.getString("case_name")),
2350  new CorrelationDataSource(-1, resultSet.getInt("case_id"), resultSet.getString("device_id"), resultSet.getString("name")),
2351  resultSet.getString("file_path"),
2352  resultSet.getString("comment"),
2353  TskData.FileKnown.valueOf(resultSet.getByte("known_status"))
2354  );
2355 
2356  return eamArtifactInstance;
2357  }
2358 
2359  private EamOrganization getEamOrganizationFromResultSet(ResultSet resultSet) throws SQLException {
2360  if (null == resultSet) {
2361  return null;
2362  }
2363 
2364  EamOrganization eamOrganization = new EamOrganization(
2365  resultSet.getInt("id"),
2366  resultSet.getString("org_name"),
2367  resultSet.getString("poc_name"),
2368  resultSet.getString("poc_email"),
2369  resultSet.getString("poc_phone")
2370  );
2371 
2372  return eamOrganization;
2373  }
2374 
2375  private EamGlobalSet getEamGlobalSetFromResultSet(ResultSet resultSet) throws SQLException, EamDbException {
2376  if (null == resultSet) {
2377  return null;
2378  }
2379 
2380  EamGlobalSet eamGlobalSet = new EamGlobalSet(
2381  resultSet.getInt("id"),
2382  resultSet.getInt("org_id"),
2383  resultSet.getString("set_name"),
2384  resultSet.getString("version"),
2385  TskData.FileKnown.valueOf(resultSet.getByte("known_status")),
2386  resultSet.getBoolean("read_only"),
2387  EamDb.getInstance().getCorrelationTypeById(resultSet.getInt("type")),
2388  LocalDate.parse(resultSet.getString("import_date"))
2389  );
2390 
2391  return eamGlobalSet;
2392  }
2393 
2394  private EamGlobalFileInstance getEamGlobalFileInstanceFromResultSet(ResultSet resultSet) throws SQLException, EamDbException {
2395  if (null == resultSet) {
2396  return null;
2397  }
2398 
2399  EamGlobalFileInstance eamGlobalFileInstance = new EamGlobalFileInstance(
2400  resultSet.getInt("id"),
2401  resultSet.getInt("reference_set_id"),
2402  resultSet.getString("value"),
2403  TskData.FileKnown.valueOf(resultSet.getByte("known_status")),
2404  resultSet.getString("comment")
2405  );
2406 
2407  return eamGlobalFileInstance;
2408  }
2409 
2415  @Override
2416  public void upgradeSchema() throws EamDbException, SQLException {
2417 
2418  ResultSet resultSet = null;
2419  Statement statement;
2420  Connection conn = null;
2421  try {
2422 
2423  conn = connect();
2424  conn.setAutoCommit(false);
2425  statement = conn.createStatement();
2426 
2427  int minorVersion = 0;
2428  int majorVersion = 0;
2429  resultSet = statement.executeQuery("SELECT value FROM db_info WHERE name='SCHEMA_MINOR_VERSION'");
2430  if (resultSet.next()) {
2431  String minorVersionStr = resultSet.getString("value");
2432  try {
2433  minorVersion = Integer.parseInt(minorVersionStr);
2434  } catch (NumberFormatException ex) {
2435  throw new EamDbException("Bad value for schema minor version (" + minorVersionStr + ") - database is corrupt");
2436  }
2437  }
2438 
2439  resultSet = statement.executeQuery("SELECT value FROM db_info WHERE name='SCHEMA_VERSION'");
2440  if (resultSet.next()) {
2441  String majorVersionStr = resultSet.getString("value");
2442  try {
2443  majorVersion = Integer.parseInt(majorVersionStr);
2444  } catch (NumberFormatException ex) {
2445  throw new EamDbException("Bad value for schema version (" + majorVersionStr + ") - database is corrupt");
2446  }
2447  }
2448 
2449  CaseDbSchemaVersionNumber dbSchemaVersion = new CaseDbSchemaVersionNumber(majorVersion, minorVersion);
2450  if (dbSchemaVersion.equals(CURRENT_DB_SCHEMA_VERSION)) {
2451  LOGGER.log(Level.INFO, "Central Repository is up to date");
2452  return;
2453  }
2454 
2455  // Update from 1.0 to 1.1
2456  if (dbSchemaVersion.compareTo(new CaseDbSchemaVersionNumber(1, 1)) < 0) {
2457  statement.execute("ALTER TABLE reference_sets ADD COLUMN known_status INTEGER;"); //NON-NLS
2458  statement.execute("ALTER TABLE reference_sets ADD COLUMN read_only BOOLEAN;"); //NON-NLS
2459  statement.execute("ALTER TABLE reference_sets ADD COLUMN type INTEGER;"); //NON-NLS
2460 
2461  // There's an outide chance that the user has already made an organization with the default name,
2462  // and the default org being missing will not impact any database operations, so continue on
2463  // regardless of whether this succeeds.
2464  EamDbUtil.insertDefaultOrganization(conn);
2465  }
2466 
2467  if (!updateSchemaVersion(conn)) {
2468  throw new EamDbException("Error updating schema version");
2469  }
2470 
2471  conn.commit();
2472  LOGGER.log(Level.INFO, "Central Repository upgraded to version " + CURRENT_DB_SCHEMA_VERSION);
2473  } catch (SQLException | EamDbException ex) {
2474  try {
2475  if (conn != null) {
2476  conn.rollback();
2477  }
2478  } catch (SQLException ex2) {
2479  LOGGER.log(Level.SEVERE, "Database rollback failed", ex2);
2480  }
2481  throw ex;
2482  } finally {
2483  EamDbUtil.closeResultSet(resultSet);
2484  EamDbUtil.closeConnection(conn);
2485  }
2486  }
2487 
2488 }
CorrelationAttribute.Type getCorrelationTypeById(int typeId)
List< CorrelationAttributeInstance > getArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value)
synchronized CorrelationCase newCase(CorrelationCase eamCase)
List< EamGlobalFileInstance > getReferenceInstancesByTypeValue(CorrelationAttribute.Type aType, String aValue)
Long getCountArtifactInstancesByCaseDataSource(String caseUUID, String dataSourceID)
Long getCountArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value)
List< String > getListCasesHavingArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value)
static String correlationTypeToReferenceTableName(CorrelationAttribute.Type type)
Definition: EamDbUtil.java:360
List< CorrelationAttributeInstance > getArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value)
List< CorrelationAttributeInstance > getArtifactInstancesByPath(CorrelationAttribute.Type aType, String filePath)
boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID)
void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, CorrelationAttribute.Type correlationType)
void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus)
boolean referenceSetExists(String referenceSetName, String version)
CorrelationAttribute.Type getCorrelationTypeFromResultSet(ResultSet resultSet)
boolean isArtifactKnownBadByReference(CorrelationAttribute.Type aType, String value)
CorrelationAttributeInstance getEamArtifactInstanceFromResultSet(ResultSet resultSet)
void bulkInsertReferenceTypeEntries(Set< EamGlobalFileInstance > globalInstances, CorrelationAttribute.Type contentType)
Long getCountArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value)
static String correlationTypeToInstanceTableName(CorrelationAttribute.Type type)
Definition: EamDbUtil.java:349
Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttribute.Type aType, String value)
CorrelationDataSource getEamDataSourceFromResultSet(ResultSet resultSet)
static final CaseDbSchemaVersionNumber CURRENT_DB_SCHEMA_VERSION
Definition: EamDb.java:36
CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
boolean referenceSetIsValid(int referenceSetID, String setName, String version)
EamGlobalFileInstance getEamGlobalFileInstanceFromResultSet(ResultSet resultSet)
List< EamGlobalSet > getAllReferenceSets(CorrelationAttribute.Type correlationType)
final Map< String, Collection< CorrelationAttribute > > bulkArtifacts
static void closePreparedStatement(PreparedStatement preparedStatement)
Definition: EamDbUtil.java:51

Copyright © 2012-2016 Basis Technology. Generated on: Mon May 7 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.