Autopsy  4.5.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 (?, ?)";
94  try {
95  preparedStatement = conn.prepareStatement(sql);
96  preparedStatement.setString(1, name);
97  preparedStatement.setString(2, value);
98  preparedStatement.executeUpdate();
99  } catch (SQLException ex) {
100  throw new EamDbException("Error adding new name/value pair to db_info.", ex);
101  } finally {
102  EamDbUtil.closePreparedStatement(preparedStatement);
104  }
105 
106  }
107 
117  @Override
118  public String getDbInfo(String name) throws EamDbException {
119  Connection conn = connect();
120 
121  PreparedStatement preparedStatement = null;
122  ResultSet resultSet = null;
123  String value = null;
124  String sql = "SELECT value FROM db_info WHERE name=?";
125  try {
126  preparedStatement = conn.prepareStatement(sql);
127  preparedStatement.setString(1, name);
128  resultSet = preparedStatement.executeQuery();
129  if (resultSet.next()) {
130  value = resultSet.getString("value");
131  }
132  } catch (SQLException ex) {
133  throw new EamDbException("Error getting value for name.", ex);
134  } finally {
135  EamDbUtil.closePreparedStatement(preparedStatement);
136  EamDbUtil.closeResultSet(resultSet);
138  }
139 
140  return value;
141  }
142 
151  @Override
152  public void updateDbInfo(String name, String value) throws EamDbException {
153  Connection conn = connect();
154 
155  PreparedStatement preparedStatement = null;
156  String sql = "UPDATE db_info SET value=? WHERE name=?";
157  try {
158  preparedStatement = conn.prepareStatement(sql);
159  preparedStatement.setString(1, value);
160  preparedStatement.setString(2, name);
161  preparedStatement.executeUpdate();
162  } catch (SQLException ex) {
163  throw new EamDbException("Error updating value for name.", ex);
164  } finally {
165  EamDbUtil.closePreparedStatement(preparedStatement);
167  }
168  }
169 
178  @Override
180  Connection conn = connect();
181 
182  PreparedStatement preparedStatement = null;
183 
184  String sql = "INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, "
185  + "examiner_name, examiner_email, examiner_phone, notes) "
186  + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
187 
188  try {
189  preparedStatement = conn.prepareStatement(sql);
190 
191  preparedStatement.setString(1, eamCase.getCaseUUID());
192  if (null == eamCase.getOrg()) {
193  preparedStatement.setNull(2, Types.INTEGER);
194  } else {
195  preparedStatement.setInt(2, eamCase.getOrg().getOrgID());
196  }
197  preparedStatement.setString(3, eamCase.getDisplayName());
198  preparedStatement.setString(4, eamCase.getCreationDate());
199  if ("".equals(eamCase.getCaseNumber())) {
200  preparedStatement.setNull(5, Types.INTEGER);
201  } else {
202  preparedStatement.setString(5, eamCase.getCaseNumber());
203  }
204  if ("".equals(eamCase.getExaminerName())) {
205  preparedStatement.setNull(6, Types.INTEGER);
206  } else {
207  preparedStatement.setString(6, eamCase.getExaminerName());
208  }
209  if ("".equals(eamCase.getExaminerEmail())) {
210  preparedStatement.setNull(7, Types.INTEGER);
211  } else {
212  preparedStatement.setString(7, eamCase.getExaminerEmail());
213  }
214  if ("".equals(eamCase.getExaminerPhone())) {
215  preparedStatement.setNull(8, Types.INTEGER);
216  } else {
217  preparedStatement.setString(8, eamCase.getExaminerPhone());
218  }
219  if ("".equals(eamCase.getNotes())) {
220  preparedStatement.setNull(9, Types.INTEGER);
221  } else {
222  preparedStatement.setString(9, eamCase.getNotes());
223  }
224 
225  preparedStatement.executeUpdate();
226  } catch (SQLException ex) {
227  throw new EamDbException("Error inserting new case.", ex); // NON-NLS
228  } finally {
229  EamDbUtil.closePreparedStatement(preparedStatement);
231  }
232 
233  // get a new version with the updated ID
234  return getCaseByUUID(eamCase.getCaseUUID());
235  }
236 
242  @Override
243  public CorrelationCase newCase(Case autopsyCase) throws EamDbException {
244  if (autopsyCase == null) {
245  throw new EamDbException("Case is null");
246  }
247 
248  CorrelationCase curCeCase = new CorrelationCase(
249  -1,
250  autopsyCase.getName(), // unique case ID
252  autopsyCase.getDisplayName(),
253  autopsyCase.getCreatedDate(),
254  autopsyCase.getNumber(),
255  autopsyCase.getExaminer(),
256  autopsyCase.getExaminerEmail(),
257  autopsyCase.getExaminerPhone(),
258  autopsyCase.getCaseNotes());
259  return newCase(curCeCase);
260  }
261 
262  @Override
263  public CorrelationCase getCase(Case autopsyCase) throws EamDbException {
264  return getCaseByUUID(autopsyCase.getName());
265  }
266 
272  @Override
273  public void updateCase(CorrelationCase eamCase) throws EamDbException {
274  if(eamCase == null) {
275  throw new EamDbException("CorrelationCase argument is null");
276  }
277 
278  Connection conn = connect();
279 
280  PreparedStatement preparedStatement = null;
281  String sql = "UPDATE cases "
282  + "SET org_id=?, case_name=?, creation_date=?, case_number=?, examiner_name=?, examiner_email=?, examiner_phone=?, notes=? "
283  + "WHERE case_uid=?";
284 
285  try {
286  preparedStatement = conn.prepareStatement(sql);
287 
288  if (null == eamCase.getOrg()) {
289  preparedStatement.setNull(1, Types.INTEGER);
290  } else {
291  preparedStatement.setInt(1, eamCase.getOrg().getOrgID());
292  }
293  preparedStatement.setString(2, eamCase.getDisplayName());
294  preparedStatement.setString(3, eamCase.getCreationDate());
295 
296  if ("".equals(eamCase.getCaseNumber())) {
297  preparedStatement.setNull(4, Types.INTEGER);
298  } else {
299  preparedStatement.setString(4, eamCase.getCaseNumber());
300  }
301  if ("".equals(eamCase.getExaminerName())) {
302  preparedStatement.setNull(5, Types.INTEGER);
303  } else {
304  preparedStatement.setString(5, eamCase.getExaminerName());
305  }
306  if ("".equals(eamCase.getExaminerEmail())) {
307  preparedStatement.setNull(6, Types.INTEGER);
308  } else {
309  preparedStatement.setString(6, eamCase.getExaminerEmail());
310  }
311  if ("".equals(eamCase.getExaminerPhone())) {
312  preparedStatement.setNull(7, Types.INTEGER);
313  } else {
314  preparedStatement.setString(7, eamCase.getExaminerPhone());
315  }
316  if ("".equals(eamCase.getNotes())) {
317  preparedStatement.setNull(8, Types.INTEGER);
318  } else {
319  preparedStatement.setString(8, eamCase.getNotes());
320  }
321 
322  preparedStatement.setString(9, eamCase.getCaseUUID());
323 
324  preparedStatement.executeUpdate();
325  } catch (SQLException ex) {
326  throw new EamDbException("Error updating case.", ex); // NON-NLS
327  } finally {
328  EamDbUtil.closePreparedStatement(preparedStatement);
330  }
331  }
332 
340  @Override
341  public CorrelationCase getCaseByUUID(String caseUUID) throws EamDbException {
342  // @@@ We should have a cache here...
343 
344  Connection conn = connect();
345 
346  CorrelationCase eamCaseResult = null;
347  PreparedStatement preparedStatement = null;
348  ResultSet resultSet = null;
349 
350  String sql = "SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, "
351  + "examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone "
352  + "FROM cases "
353  + "LEFT JOIN organizations ON cases.org_id=organizations.id "
354  + "WHERE case_uid=?";
355 
356  try {
357  preparedStatement = conn.prepareStatement(sql);
358  preparedStatement.setString(1, caseUUID);
359  resultSet = preparedStatement.executeQuery();
360  if (resultSet.next()) {
361  eamCaseResult = getEamCaseFromResultSet(resultSet);
362  }
363  } catch (SQLException ex) {
364  throw new EamDbException("Error getting case details.", ex); // NON-NLS
365  } finally {
366  EamDbUtil.closePreparedStatement(preparedStatement);
367  EamDbUtil.closeResultSet(resultSet);
369  }
370 
371  return eamCaseResult;
372  }
373 
379  @Override
380  public List<CorrelationCase> getCases() throws EamDbException {
381  Connection conn = connect();
382 
383  List<CorrelationCase> cases = new ArrayList<>();
384  CorrelationCase eamCaseResult;
385  PreparedStatement preparedStatement = null;
386  ResultSet resultSet = null;
387 
388  String sql = "SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, "
389  + "examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone "
390  + "FROM cases "
391  + "LEFT JOIN organizations ON cases.org_id=organizations.id";
392 
393  try {
394  preparedStatement = conn.prepareStatement(sql);
395  resultSet = preparedStatement.executeQuery();
396  while (resultSet.next()) {
397  eamCaseResult = getEamCaseFromResultSet(resultSet);
398  cases.add(eamCaseResult);
399  }
400  } catch (SQLException ex) {
401  throw new EamDbException("Error getting all cases.", ex); // NON-NLS
402  } finally {
403  EamDbUtil.closePreparedStatement(preparedStatement);
404  EamDbUtil.closeResultSet(resultSet);
406  }
407 
408  return cases;
409  }
410 
416  @Override
417  public void newDataSource(CorrelationDataSource eamDataSource) throws EamDbException {
418  Connection conn = connect();
419 
420  PreparedStatement preparedStatement = null;
421 
422  String sql = "INSERT INTO data_sources(device_id, case_id, name) VALUES (?, ?, ?)";
423 
424  try {
425  preparedStatement = conn.prepareStatement(sql);
426 
427  preparedStatement.setString(1, eamDataSource.getDeviceID());
428  preparedStatement.setInt(2, eamDataSource.getCaseID());
429  preparedStatement.setString(3, eamDataSource.getName());
430 
431  preparedStatement.executeUpdate();
432  } catch (SQLException ex) {
433  throw new EamDbException("Error inserting new data source.", ex); // NON-NLS
434  } finally {
435  EamDbUtil.closePreparedStatement(preparedStatement);
437  }
438  }
439 
449  @Override
450  public CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException {
451  if(correlationCase == null) {
452  throw new EamDbException("CorrelationCase argument is null");
453  }
454 
455  Connection conn = connect();
456 
457  CorrelationDataSource eamDataSourceResult = null;
458  PreparedStatement preparedStatement = null;
459  ResultSet resultSet = null;
460 
461  String sql = "SELECT * FROM data_sources WHERE device_id=? AND case_id=?"; // NON-NLS
462 
463  try {
464  preparedStatement = conn.prepareStatement(sql);
465  preparedStatement.setString(1, dataSourceDeviceId);
466  preparedStatement.setInt(2, correlationCase.getID());
467  resultSet = preparedStatement.executeQuery();
468  if (resultSet.next()) {
469  eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
470  }
471  } catch (SQLException ex) {
472  throw new EamDbException("Error getting data source.", ex); // NON-NLS
473  } finally {
474  EamDbUtil.closePreparedStatement(preparedStatement);
475  EamDbUtil.closeResultSet(resultSet);
477  }
478 
479  return eamDataSourceResult;
480  }
481 
487  @Override
488  public List<CorrelationDataSource> getDataSources() throws EamDbException {
489  Connection conn = connect();
490 
491  List<CorrelationDataSource> dataSources = new ArrayList<>();
492  CorrelationDataSource eamDataSourceResult;
493  PreparedStatement preparedStatement = null;
494  ResultSet resultSet = null;
495 
496  String sql = "SELECT * FROM data_sources";
497 
498  try {
499  preparedStatement = conn.prepareStatement(sql);
500  resultSet = preparedStatement.executeQuery();
501  while (resultSet.next()) {
502  eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
503  dataSources.add(eamDataSourceResult);
504  }
505  } catch (SQLException ex) {
506  throw new EamDbException("Error getting all data sources.", ex); // NON-NLS
507  } finally {
508  EamDbUtil.closePreparedStatement(preparedStatement);
509  EamDbUtil.closeResultSet(resultSet);
511  }
512 
513  return dataSources;
514  }
515 
522  @Override
523  public void addArtifact(CorrelationAttribute eamArtifact) throws EamDbException {
524  if(eamArtifact == null) {
525  throw new EamDbException("CorrelationAttribute is null");
526  }
527  if(eamArtifact.getCorrelationType() == null) {
528  throw new EamDbException("Correlation type is null");
529  }
530  if(eamArtifact.getCorrelationValue() == null) {
531  throw new EamDbException("Correlation value is null");
532  }
533 
534  Connection conn = connect();
535 
536  List<CorrelationAttributeInstance> eamInstances = eamArtifact.getInstances();
537  PreparedStatement preparedStatement = null;
538 
539  // @@@ We should cache the case and data source IDs in memory
540  String tableName = EamDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
541  StringBuilder sql = new StringBuilder();
542  sql.append("INSERT INTO ");
543  sql.append(tableName);
544  sql.append("(case_id, data_source_id, value, file_path, known_status, comment) ");
545  sql.append("VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), ");
546  sql.append("(SELECT id FROM data_sources WHERE device_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?)");
547 
548  try {
549  preparedStatement = conn.prepareStatement(sql.toString());
550  for (CorrelationAttributeInstance eamInstance : eamInstances) {
551  if (!eamArtifact.getCorrelationValue().isEmpty()) {
552  if(eamInstance.getCorrelationCase() == null) {
553  throw new EamDbException("CorrelationAttributeInstance has null case");
554  }
555  if(eamInstance.getCorrelationDataSource() == null) {
556  throw new EamDbException("CorrelationAttributeInstance has null data source");
557  }
558  if(eamInstance.getKnownStatus() == null) {
559  throw new EamDbException("CorrelationAttributeInstance has null known status");
560  }
561 
562  preparedStatement.setString(1, eamInstance.getCorrelationCase().getCaseUUID());
563  preparedStatement.setString(2, eamInstance.getCorrelationDataSource().getDeviceID());
564  preparedStatement.setInt(3, eamInstance.getCorrelationDataSource().getCaseID());
565  preparedStatement.setString(4, eamArtifact.getCorrelationValue());
566  preparedStatement.setString(5, eamInstance.getFilePath());
567  preparedStatement.setByte(6, eamInstance.getKnownStatus().getFileKnownValue());
568  if ("".equals(eamInstance.getComment())) {
569  preparedStatement.setNull(7, Types.INTEGER);
570  } else {
571  preparedStatement.setString(7, eamInstance.getComment());
572  }
573 
574  preparedStatement.executeUpdate();
575  }
576  }
577  } catch (SQLException ex) {
578  throw new EamDbException("Error inserting new artifact into artifacts table.", ex); // NON-NLS
579  } finally {
580  EamDbUtil.closePreparedStatement(preparedStatement);
582  }
583  }
584 
596  @Override
597  public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
598  if(aType == null) {
599  throw new EamDbException("Correlation type is null");
600  }
601  Connection conn = connect();
602 
603  List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>();
604 
605  CorrelationAttributeInstance artifactInstance;
606  PreparedStatement preparedStatement = null;
607  ResultSet resultSet = null;
608 
609  String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType);
610  StringBuilder sql = new StringBuilder();
611  sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id FROM ");
612  sql.append(tableName);
613  sql.append(" LEFT JOIN cases ON ");
614  sql.append(tableName);
615  sql.append(".case_id=cases.id");
616  sql.append(" LEFT JOIN data_sources ON ");
617  sql.append(tableName);
618  sql.append(".data_source_id=data_sources.id");
619  sql.append(" WHERE value=?");
620 
621  try {
622  preparedStatement = conn.prepareStatement(sql.toString());
623  preparedStatement.setString(1, value);
624  resultSet = preparedStatement.executeQuery();
625  while (resultSet.next()) {
626  artifactInstance = getEamArtifactInstanceFromResultSet(resultSet);
627  artifactInstances.add(artifactInstance);
628  }
629  } catch (SQLException ex) {
630  throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS
631  } finally {
632  EamDbUtil.closePreparedStatement(preparedStatement);
633  EamDbUtil.closeResultSet(resultSet);
635  }
636 
637  return artifactInstances;
638  }
639 
651  @Override
652  public List<CorrelationAttributeInstance> getArtifactInstancesByPath(CorrelationAttribute.Type aType, String filePath) throws EamDbException {
653  if(aType == null) {
654  throw new EamDbException("Correlation type is null");
655  }
656  if(filePath == null) {
657  throw new EamDbException("Correlation value is null");
658  }
659  Connection conn = connect();
660 
661  List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>();
662 
663  CorrelationAttributeInstance artifactInstance;
664  PreparedStatement preparedStatement = null;
665  ResultSet resultSet = null;
666 
667  String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType);
668  StringBuilder sql = new StringBuilder();
669  sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id FROM ");
670  sql.append(tableName);
671  sql.append(" LEFT JOIN cases ON ");
672  sql.append(tableName);
673  sql.append(".case_id=cases.id");
674  sql.append(" LEFT JOIN data_sources ON ");
675  sql.append(tableName);
676  sql.append(".data_source_id=data_sources.id");
677  sql.append(" WHERE file_path=?");
678 
679  try {
680  preparedStatement = conn.prepareStatement(sql.toString());
681  preparedStatement.setString(1, filePath.toLowerCase());
682  resultSet = preparedStatement.executeQuery();
683  while (resultSet.next()) {
684  artifactInstance = getEamArtifactInstanceFromResultSet(resultSet);
685  artifactInstances.add(artifactInstance);
686  }
687  } catch (SQLException ex) {
688  throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS
689  } finally {
690  EamDbUtil.closePreparedStatement(preparedStatement);
691  EamDbUtil.closeResultSet(resultSet);
693  }
694 
695  return artifactInstances;
696  }
697 
708  @Override
710  if(aType == null) {
711  throw new EamDbException("Correlation type is null");
712  }
713  if(value == null) {
714  throw new EamDbException("Correlation value is null");
715  }
716 
717  Connection conn = connect();
718 
719  Long instanceCount = 0L;
720  PreparedStatement preparedStatement = null;
721  ResultSet resultSet = null;
722 
723  String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType);
724  StringBuilder sql = new StringBuilder();
725  sql.append("SELECT count(*) FROM ");
726  sql.append(tableName);
727  sql.append(" WHERE value=?");
728 
729  try {
730  preparedStatement = conn.prepareStatement(sql.toString());
731  preparedStatement.setString(1, value.toLowerCase());
732  resultSet = preparedStatement.executeQuery();
733  resultSet.next();
734  instanceCount = resultSet.getLong(1);
735  } catch (SQLException ex) {
736  throw new EamDbException("Error getting count of artifact instances by artifactType and artifactValue.", ex); // NON-NLS
737  } finally {
738  EamDbUtil.closePreparedStatement(preparedStatement);
739  EamDbUtil.closeResultSet(resultSet);
741  }
742 
743  return instanceCount;
744  }
745 
746  @Override
748  if (corAttr == null) {
749  throw new EamDbException("Correlation attribute is null");
750  }
751  Double uniqueTypeValueTuples = getCountUniqueCaseDataSourceTuplesHavingTypeValue(corAttr.getCorrelationType(), corAttr.getCorrelationValue()).doubleValue();
752  Double uniqueCaseDataSourceTuples = getCountUniqueDataSources().doubleValue();
753  Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100;
754  return commonalityPercentage.intValue();
755  }
756 
767  @Override
769  if(aType == null) {
770  throw new EamDbException("Correlation type is null");
771  }
772 
773  Connection conn = connect();
774 
775  Long instanceCount = 0L;
776  PreparedStatement preparedStatement = null;
777  ResultSet resultSet = null;
778 
779  String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType);
780  StringBuilder sql = new StringBuilder();
781  sql.append("SELECT count(*) FROM (SELECT DISTINCT case_id, data_source_id FROM ");
782  sql.append(tableName);
783  sql.append(" WHERE value=?) AS ");
784  sql.append(tableName);
785  sql.append("_distinct_case_data_source_tuple");
786 
787  try {
788  preparedStatement = conn.prepareStatement(sql.toString());
789  preparedStatement.setString(1, value);
790  resultSet = preparedStatement.executeQuery();
791  resultSet.next();
792  instanceCount = resultSet.getLong(1);
793  } catch (SQLException ex) {
794  throw new EamDbException("Error counting unique caseDisplayName/dataSource tuples having artifactType and artifactValue.", ex); // NON-NLS
795  } finally {
796  EamDbUtil.closePreparedStatement(preparedStatement);
797  EamDbUtil.closeResultSet(resultSet);
799  }
800 
801  return instanceCount;
802  }
803 
804  @Override
806  Connection conn = connect();
807 
808  Long instanceCount = 0L;
809  PreparedStatement preparedStatement = null;
810  ResultSet resultSet = null;
811 
812  String stmt = "SELECT count(*) FROM data_sources";
813 
814  try {
815  preparedStatement = conn.prepareStatement(stmt);
816  resultSet = preparedStatement.executeQuery();
817  resultSet.next();
818  instanceCount = resultSet.getLong(1);
819  } catch (SQLException ex) {
820  throw new EamDbException("Error counting data sources.", ex); // NON-NLS
821  } finally {
822  EamDbUtil.closePreparedStatement(preparedStatement);
823  EamDbUtil.closeResultSet(resultSet);
825  }
826 
827  return instanceCount;
828  }
829 
841  @Override
842  public Long getCountArtifactInstancesByCaseDataSource(String caseUUID, String dataSourceID) throws EamDbException {
843  Connection conn = connect();
844 
845  Long instanceCount = 0L;
846  List<CorrelationAttribute.Type> artifactTypes = getDefinedCorrelationTypes();
847  PreparedStatement preparedStatement = null;
848  ResultSet resultSet = null;
849 
850  // Figure out sql variables or subqueries
851  StringBuilder sql = new StringBuilder();
852  sql.append("SELECT 0 ");
853 
854  for (CorrelationAttribute.Type type : artifactTypes) {
855  String table_name = EamDbUtil.correlationTypeToInstanceTableName(type);
856 
857  sql.append("+ (SELECT count(*) FROM ");
858  sql.append(table_name);
859  sql.append(" WHERE case_id=(SELECT id FROM cases WHERE case_uid=?) and data_source_id=(SELECT id FROM data_sources WHERE device_id=?))");
860  }
861 
862  try {
863  preparedStatement = conn.prepareStatement(sql.toString());
864 
865  for (int i = 0; i < artifactTypes.size(); ++i) {
866  preparedStatement.setString(2 * i + 1, caseUUID);
867  preparedStatement.setString(2 * i + 2, dataSourceID);
868  }
869 
870  resultSet = preparedStatement.executeQuery();
871  resultSet.next();
872  instanceCount = resultSet.getLong(1);
873  } catch (SQLException ex) {
874  throw new EamDbException("Error counting artifact instances by caseName/dataSource.", ex); // NON-NLS
875  } finally {
876  EamDbUtil.closePreparedStatement(preparedStatement);
877  EamDbUtil.closeResultSet(resultSet);
879  }
880 
881  return instanceCount;
882  }
883 
891  @Override
892  public void prepareBulkArtifact(CorrelationAttribute eamArtifact) throws EamDbException {
893 
894  if(eamArtifact.getCorrelationType() == null) {
895  throw new EamDbException("Correlation type is null");
896  }
897 
898  synchronized (bulkArtifacts) {
899  bulkArtifacts.get(eamArtifact.getCorrelationType().getDbTableName()).add(eamArtifact);
900  bulkArtifactsCount++;
901 
902  if (bulkArtifactsCount >= bulkArtifactsThreshold) {
904  }
905  }
906  }
907 
913  protected abstract String getConflictClause();
914 
919  @Override
920  public void bulkInsertArtifacts() throws EamDbException {
921  List<CorrelationAttribute.Type> artifactTypes = getDefinedCorrelationTypes();
922 
923  Connection conn = connect();
924  PreparedStatement bulkPs = null;
925 
926  try {
927  synchronized (bulkArtifacts) {
928  if (bulkArtifactsCount == 0) {
929  return;
930  }
931 
932  for (CorrelationAttribute.Type type : artifactTypes) {
933 
934  String tableName = EamDbUtil.correlationTypeToInstanceTableName(type);
935  StringBuilder sql = new StringBuilder();
936  sql.append("INSERT INTO ");
937  sql.append(tableName);
938  sql.append(" (case_id, data_source_id, value, file_path, known_status, comment) ");
939  sql.append("VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), ");
940  sql.append("(SELECT id FROM data_sources WHERE device_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?) ");
941  sql.append(getConflictClause());
942 
943  bulkPs = conn.prepareStatement(sql.toString());
944 
945  Collection<CorrelationAttribute> eamArtifacts = bulkArtifacts.get(type.getDbTableName());
946  for (CorrelationAttribute eamArtifact : eamArtifacts) {
947  List<CorrelationAttributeInstance> eamInstances = eamArtifact.getInstances();
948 
949  for (CorrelationAttributeInstance eamInstance : eamInstances) {
950  if (!eamArtifact.getCorrelationValue().isEmpty()) {
951 
952  if(eamInstance.getCorrelationCase() == null) {
953  throw new EamDbException("Correlation attribute instance has null case");
954  }
955  if(eamInstance.getCorrelationDataSource() == null) {
956  throw new EamDbException("Correlation attribute instance has null data source");
957  }
958  if(eamInstance.getKnownStatus()== null) {
959  throw new EamDbException("Correlation attribute instance has null known known status");
960  }
961 
962  bulkPs.setString(1, eamInstance.getCorrelationCase().getCaseUUID());
963  bulkPs.setString(2, eamInstance.getCorrelationDataSource().getDeviceID());
964  bulkPs.setInt(3, eamInstance.getCorrelationDataSource().getCaseID());
965  bulkPs.setString(4, eamArtifact.getCorrelationValue());
966  bulkPs.setString(5, eamInstance.getFilePath());
967  bulkPs.setByte(6, eamInstance.getKnownStatus().getFileKnownValue());
968  if ("".equals(eamInstance.getComment())) {
969  bulkPs.setNull(7, Types.INTEGER);
970  } else {
971  bulkPs.setString(7, eamInstance.getComment());
972  }
973  bulkPs.addBatch();
974  }
975  }
976  }
977 
978  bulkPs.executeBatch();
979  bulkArtifacts.get(type.getDbTableName()).clear();
980  }
981 
982  // Reset state
983  bulkArtifactsCount = 0;
984  }
985  } catch (SQLException ex) {
986  throw new EamDbException("Error inserting bulk artifacts.", ex); // NON-NLS
987  } finally {
990  }
991  }
992 
996  @Override
997  public void bulkInsertCases(List<CorrelationCase> cases) throws EamDbException {
998  if(cases == null) {
999  throw new EamDbException("cases argument is null");
1000  }
1001 
1002  if (cases.isEmpty()) {
1003  return;
1004  }
1005 
1006  Connection conn = connect();
1007 
1008  int counter = 0;
1009  PreparedStatement bulkPs = null;
1010  try {
1011  String sql = "INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, "
1012  + "examiner_name, examiner_email, examiner_phone, notes) "
1013  + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) "
1014  + getConflictClause();
1015  bulkPs = conn.prepareStatement(sql);
1016 
1017  for (CorrelationCase eamCase : cases) {
1018  bulkPs.setString(1, eamCase.getCaseUUID());
1019  if (null == eamCase.getOrg()) {
1020  bulkPs.setNull(2, Types.INTEGER);
1021  } else {
1022  bulkPs.setInt(2, eamCase.getOrg().getOrgID());
1023  }
1024  bulkPs.setString(3, eamCase.getDisplayName());
1025  bulkPs.setString(4, eamCase.getCreationDate());
1026 
1027  if ("".equals(eamCase.getCaseNumber())) {
1028  bulkPs.setNull(5, Types.INTEGER);
1029  } else {
1030  bulkPs.setString(5, eamCase.getCaseNumber());
1031  }
1032  if ("".equals(eamCase.getExaminerName())) {
1033  bulkPs.setNull(6, Types.INTEGER);
1034  } else {
1035  bulkPs.setString(6, eamCase.getExaminerName());
1036  }
1037  if ("".equals(eamCase.getExaminerEmail())) {
1038  bulkPs.setNull(7, Types.INTEGER);
1039  } else {
1040  bulkPs.setString(7, eamCase.getExaminerEmail());
1041  }
1042  if ("".equals(eamCase.getExaminerPhone())) {
1043  bulkPs.setNull(8, Types.INTEGER);
1044  } else {
1045  bulkPs.setString(8, eamCase.getExaminerPhone());
1046  }
1047  if ("".equals(eamCase.getNotes())) {
1048  bulkPs.setNull(9, Types.INTEGER);
1049  } else {
1050  bulkPs.setString(9, eamCase.getNotes());
1051  }
1052 
1053  bulkPs.addBatch();
1054 
1055  counter++;
1056 
1057  // limit a batch's max size to bulkArtifactsThreshold
1058  if (counter >= bulkArtifactsThreshold) {
1059  bulkPs.executeBatch();
1060  counter = 0;
1061  }
1062  }
1063  // send the remaining batch records
1064  bulkPs.executeBatch();
1065  } catch (SQLException ex) {
1066  throw new EamDbException("Error inserting bulk cases.", ex); // NON-NLS
1067  } finally {
1069  EamDbUtil.closeConnection(conn);
1070  }
1071  }
1072 
1083  @Override
1084  public void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus) throws EamDbException {
1085  if(eamArtifact == null) {
1086  throw new EamDbException("Correlation attribute is null");
1087  }
1088  if(knownStatus == null) {
1089  throw new EamDbException("Known status is null");
1090  }
1091  if (1 != eamArtifact.getInstances().size()) {
1092  throw new EamDbException("Error: Artifact must have exactly one (1) Artifact Instance to set as notable."); // NON-NLS
1093  }
1094 
1095  List<CorrelationAttributeInstance> eamInstances = eamArtifact.getInstances();
1096  CorrelationAttributeInstance eamInstance = eamInstances.get(0);
1097 
1098  if(eamInstance.getCorrelationCase() == null) {
1099  throw new EamDbException("Correlation case is null");
1100  }
1101  if(eamInstance.getCorrelationDataSource() == null) {
1102  throw new EamDbException("Correlation data source is null");
1103  }
1104 
1105  Connection conn = connect();
1106 
1107  PreparedStatement preparedUpdate = null;
1108  PreparedStatement preparedQuery = null;
1109  ResultSet resultSet = null;
1110 
1111  String tableName = EamDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
1112 
1113  StringBuilder sqlQuery = new StringBuilder();
1114  sqlQuery.append("SELECT id FROM ");
1115  sqlQuery.append(tableName);
1116  sqlQuery.append(" WHERE case_id=(SELECT id FROM cases WHERE case_uid=?) ");
1117  sqlQuery.append("AND data_source_id=(SELECT id FROM data_sources WHERE device_id=?) ");
1118  sqlQuery.append("AND value=? ");
1119  sqlQuery.append("AND file_path=?");
1120 
1121  StringBuilder sqlUpdate = new StringBuilder();
1122  sqlUpdate.append("UPDATE ");
1123  sqlUpdate.append(tableName);
1124  sqlUpdate.append(" SET known_status=?, comment=? ");
1125  sqlUpdate.append("WHERE id=?");
1126 
1127  try {
1128  preparedQuery = conn.prepareStatement(sqlQuery.toString());
1129  preparedQuery.setString(1, eamInstance.getCorrelationCase().getCaseUUID());
1130  preparedQuery.setString(2, eamInstance.getCorrelationDataSource().getDeviceID());
1131  preparedQuery.setString(3, eamArtifact.getCorrelationValue());
1132  preparedQuery.setString(4, eamInstance.getFilePath());
1133  resultSet = preparedQuery.executeQuery();
1134  if (resultSet.next()) {
1135  int instance_id = resultSet.getInt("id");
1136  preparedUpdate = conn.prepareStatement(sqlUpdate.toString());
1137 
1138  preparedUpdate.setByte(1, knownStatus.getFileKnownValue());
1139  // NOTE: if the user tags the same instance as BAD multiple times,
1140  // the comment from the most recent tagging is the one that will
1141  // prevail in the DB.
1142  if ("".equals(eamInstance.getComment())) {
1143  preparedUpdate.setNull(2, Types.INTEGER);
1144  } else {
1145  preparedUpdate.setString(2, eamInstance.getComment());
1146  }
1147  preparedUpdate.setInt(3, instance_id);
1148 
1149  preparedUpdate.executeUpdate();
1150  } else {
1151  // In this case, the user is tagging something that isn't in the database,
1152  // which means the case and/or datasource may also not be in the database.
1153  // We could improve effiency by keeping a list of all datasources and cases
1154  // in the database, but we don't expect the user to be tagging large numbers
1155  // of items (that didn't have the CE ingest module run on them) at once.
1156  CorrelationCase correlationCaseWithId = getCaseByUUID(eamInstance.getCorrelationCase().getCaseUUID());
1157  if (null == correlationCaseWithId) {
1158  correlationCaseWithId = newCase(eamInstance.getCorrelationCase());
1159  }
1160 
1161  if (null == getDataSource(correlationCaseWithId, eamInstance.getCorrelationDataSource().getDeviceID())) {
1162  newDataSource(eamInstance.getCorrelationDataSource());
1163  }
1164  eamArtifact.getInstances().get(0).setKnownStatus(knownStatus);
1165  addArtifact(eamArtifact);
1166  }
1167 
1168  } catch (SQLException ex) {
1169  throw new EamDbException("Error getting/setting artifact instance knownStatus=" + knownStatus.getName(), ex); // NON-NLS
1170  } finally {
1171  EamDbUtil.closePreparedStatement(preparedUpdate);
1172  EamDbUtil.closePreparedStatement(preparedQuery);
1173  EamDbUtil.closeResultSet(resultSet);
1174  EamDbUtil.closeConnection(conn);
1175  }
1176  }
1177 
1187  @Override
1188  public List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
1189  if(aType == null) {
1190  throw new EamDbException("Correlation type is null");
1191  }
1192 
1193  Connection conn = connect();
1194 
1195  List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>();
1196 
1197  CorrelationAttributeInstance artifactInstance;
1198  PreparedStatement preparedStatement = null;
1199  ResultSet resultSet = null;
1200 
1201  String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType);
1202  StringBuilder sql = new StringBuilder();
1203  sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id FROM ");
1204  sql.append(tableName);
1205  sql.append(" LEFT JOIN cases ON ");
1206  sql.append(tableName);
1207  sql.append(".case_id=cases.id");
1208  sql.append(" LEFT JOIN data_sources ON ");
1209  sql.append(tableName);
1210  sql.append(".data_source_id=data_sources.id");
1211  sql.append(" WHERE value=? AND known_status=?");
1212 
1213  try {
1214  preparedStatement = conn.prepareStatement(sql.toString());
1215  preparedStatement.setString(1, value);
1216  preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
1217  resultSet = preparedStatement.executeQuery();
1218  while (resultSet.next()) {
1219  artifactInstance = getEamArtifactInstanceFromResultSet(resultSet);
1220  artifactInstances.add(artifactInstance);
1221  }
1222  } catch (SQLException ex) {
1223  throw new EamDbException("Error getting notable artifact instances.", ex); // NON-NLS
1224  } finally {
1225  EamDbUtil.closePreparedStatement(preparedStatement);
1226  EamDbUtil.closeResultSet(resultSet);
1227  EamDbUtil.closeConnection(conn);
1228  }
1229 
1230  return artifactInstances;
1231  }
1232 
1241  @Override
1243  if(aType == null) {
1244  throw new EamDbException("Correlation type is null");
1245  }
1246 
1247  Connection conn = connect();
1248 
1249  Long badInstances = 0L;
1250  PreparedStatement preparedStatement = null;
1251  ResultSet resultSet = null;
1252 
1253  String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType);
1254  StringBuilder sql = new StringBuilder();
1255  sql.append("SELECT count(*) FROM ");
1256  sql.append(tableName);
1257  sql.append(" WHERE value=? AND known_status=?");
1258 
1259  try {
1260  preparedStatement = conn.prepareStatement(sql.toString());
1261  preparedStatement.setString(1, value);
1262  preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
1263  resultSet = preparedStatement.executeQuery();
1264  resultSet.next();
1265  badInstances = resultSet.getLong(1);
1266  } catch (SQLException ex) {
1267  throw new EamDbException("Error getting count of notable artifact instances.", ex); // NON-NLS
1268  } finally {
1269  EamDbUtil.closePreparedStatement(preparedStatement);
1270  EamDbUtil.closeResultSet(resultSet);
1271  EamDbUtil.closeConnection(conn);
1272  }
1273 
1274  return badInstances;
1275  }
1276 
1289  @Override
1291  if(aType == null) {
1292  throw new EamDbException("Correlation type is null");
1293  }
1294 
1295  Connection conn = connect();
1296 
1297  Collection<String> caseNames = new LinkedHashSet<>();
1298 
1299  PreparedStatement preparedStatement = null;
1300  ResultSet resultSet = null;
1301 
1302  String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType);
1303  StringBuilder sql = new StringBuilder();
1304  sql.append("SELECT DISTINCT case_name FROM ");
1305  sql.append(tableName);
1306  sql.append(" INNER JOIN cases ON ");
1307  sql.append(tableName);
1308  sql.append(".case_id=cases.id WHERE ");
1309  sql.append(tableName);
1310  sql.append(".value=? AND ");
1311  sql.append(tableName);
1312  sql.append(".known_status=?");
1313 
1314  try {
1315  preparedStatement = conn.prepareStatement(sql.toString());
1316  preparedStatement.setString(1, value);
1317  preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
1318  resultSet = preparedStatement.executeQuery();
1319  while (resultSet.next()) {
1320  caseNames.add(resultSet.getString("case_name"));
1321  }
1322  } catch (SQLException ex) {
1323  throw new EamDbException("Error getting notable artifact instances.", ex); // NON-NLS
1324  } finally {
1325  EamDbUtil.closePreparedStatement(preparedStatement);
1326  EamDbUtil.closeResultSet(resultSet);
1327  EamDbUtil.closeConnection(conn);
1328  }
1329 
1330  return caseNames.stream().collect(Collectors.toList());
1331  }
1332 
1339  @Override
1340  public void deleteReferenceSet(int referenceSetID) throws EamDbException {
1341  deleteReferenceSetEntries(referenceSetID);
1342  deleteReferenceSetEntry(referenceSetID);
1343  }
1344 
1351  private void deleteReferenceSetEntry(int referenceSetID) throws EamDbException {
1352  Connection conn = connect();
1353 
1354  PreparedStatement preparedStatement = null;
1355  String sql = "DELETE FROM reference_sets WHERE id=?";
1356 
1357  try {
1358  preparedStatement = conn.prepareStatement(sql);
1359  preparedStatement.setInt(1, referenceSetID);
1360  preparedStatement.executeUpdate();
1361  } catch (SQLException ex) {
1362  throw new EamDbException("Error deleting reference set " + referenceSetID, ex); // NON-NLS
1363  } finally {
1364  EamDbUtil.closePreparedStatement(preparedStatement);
1365  EamDbUtil.closeConnection(conn);
1366  }
1367  }
1368 
1376  private void deleteReferenceSetEntries(int referenceSetID) throws EamDbException {
1377  Connection conn = connect();
1378 
1379  PreparedStatement preparedStatement = null;
1380  String sql = "DELETE FROM %s WHERE reference_set_id=?";
1381 
1382  // When other reference types are added, this will need to loop over all the tables
1384 
1385  try {
1386  preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
1387  preparedStatement.setInt(1, referenceSetID);
1388  preparedStatement.executeUpdate();
1389  } catch (SQLException ex) {
1390  throw new EamDbException("Error deleting files from reference set " + referenceSetID, ex); // NON-NLS
1391  } finally {
1392  EamDbUtil.closePreparedStatement(preparedStatement);
1393  EamDbUtil.closeConnection(conn);
1394  }
1395  }
1396 
1408  @Override
1409  public boolean referenceSetIsValid(int referenceSetID, String setName, String version) throws EamDbException {
1410  EamGlobalSet refSet = this.getReferenceSetByID(referenceSetID);
1411  if(refSet == null) {
1412  return false;
1413  }
1414 
1415  return (refSet.getSetName().equals(setName) && refSet.getVersion().equals(version));
1416  }
1417 
1427  @Override
1428  public boolean isFileHashInReferenceSet(String hash, int referenceSetID) throws EamDbException {
1429  return isValueInReferenceSet(hash, referenceSetID, CorrelationAttribute.FILES_TYPE_ID);
1430  }
1431 
1440  @Override
1441  public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException {
1442 
1443  Connection conn = connect();
1444 
1445  Long matchingInstances = 0L;
1446  PreparedStatement preparedStatement = null;
1447  ResultSet resultSet = null;
1448  String sql = "SELECT count(*) FROM %s WHERE value=? AND reference_set_id=?";
1449 
1450  String fileTableName = EamDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(correlationTypeID));
1451 
1452  try {
1453  preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
1454  preparedStatement.setString(1, value);
1455  preparedStatement.setInt(2, referenceSetID);
1456  resultSet = preparedStatement.executeQuery();
1457  resultSet.next();
1458  matchingInstances = resultSet.getLong(1);
1459  } catch (SQLException ex) {
1460  throw new EamDbException("Error determining if value (" + value + ") is in reference set " + referenceSetID, ex); // NON-NLS
1461  } finally {
1462  EamDbUtil.closePreparedStatement(preparedStatement);
1463  EamDbUtil.closeResultSet(resultSet);
1464  EamDbUtil.closeConnection(conn);
1465  }
1466 
1467  return 0 < matchingInstances;
1468  }
1469 
1478  @Override
1479  public boolean isArtifactKnownBadByReference(CorrelationAttribute.Type aType, String value) throws EamDbException {
1480  if(aType == null) {
1481  throw new EamDbException("null correlation type");
1482  }
1483 
1484  // TEMP: Only support file correlation type
1485  if (aType.getId() != CorrelationAttribute.FILES_TYPE_ID) {
1486  return false;
1487  }
1488 
1489  Connection conn = connect();
1490 
1491  Long badInstances = 0L;
1492  PreparedStatement preparedStatement = null;
1493  ResultSet resultSet = null;
1494  String sql = "SELECT count(*) FROM %s WHERE value=? AND known_status=?";
1495 
1496  try {
1497  preparedStatement = conn.prepareStatement(String.format(sql, EamDbUtil.correlationTypeToReferenceTableName(aType)));
1498  preparedStatement.setString(1, value);
1499  preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
1500  resultSet = preparedStatement.executeQuery();
1501  resultSet.next();
1502  badInstances = resultSet.getLong(1);
1503  } catch (SQLException ex) {
1504  throw new EamDbException("Error determining if artifact is notable by reference.", ex); // NON-NLS
1505  } finally {
1506  EamDbUtil.closePreparedStatement(preparedStatement);
1507  EamDbUtil.closeResultSet(resultSet);
1508  EamDbUtil.closeConnection(conn);
1509  }
1510 
1511  return 0 < badInstances;
1512  }
1513 
1523  @Override
1524  public long newOrganization(EamOrganization eamOrg) throws EamDbException {
1525  if(eamOrg == null) {
1526  throw new EamDbException("EamOrganization is null");
1527  }
1528 
1529  Connection conn = connect();
1530  ResultSet generatedKeys = null;
1531  PreparedStatement preparedStatement = null;
1532  String sql = "INSERT INTO organizations(org_name, poc_name, poc_email, poc_phone) VALUES (?, ?, ?, ?)";
1533 
1534  try {
1535  preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
1536  preparedStatement.setString(1, eamOrg.getName());
1537  preparedStatement.setString(2, eamOrg.getPocName());
1538  preparedStatement.setString(3, eamOrg.getPocEmail());
1539  preparedStatement.setString(4, eamOrg.getPocPhone());
1540 
1541  preparedStatement.executeUpdate();
1542  generatedKeys = preparedStatement.getGeneratedKeys();
1543  if (generatedKeys.next()) {
1544  return generatedKeys.getLong(1);
1545  } else {
1546  throw new SQLException("Creating user failed, no ID obtained.");
1547  }
1548  } catch (SQLException ex) {
1549  throw new EamDbException("Error inserting new organization.", ex); // NON-NLS
1550  } finally {
1551  EamDbUtil.closePreparedStatement(preparedStatement);
1552  EamDbUtil.closeResultSet(generatedKeys);
1553  EamDbUtil.closeConnection(conn);
1554  }
1555  }
1556 
1564  @Override
1565  public List<EamOrganization> getOrganizations() throws EamDbException {
1566  Connection conn = connect();
1567 
1568  List<EamOrganization> orgs = new ArrayList<>();
1569  PreparedStatement preparedStatement = null;
1570  ResultSet resultSet = null;
1571  String sql = "SELECT * FROM organizations";
1572 
1573  try {
1574  preparedStatement = conn.prepareStatement(sql);
1575  resultSet = preparedStatement.executeQuery();
1576  while (resultSet.next()) {
1577  orgs.add(getEamOrganizationFromResultSet(resultSet));
1578  }
1579  return orgs;
1580 
1581  } catch (SQLException ex) {
1582  throw new EamDbException("Error getting all organizations.", ex); // NON-NLS
1583  } finally {
1584  EamDbUtil.closePreparedStatement(preparedStatement);
1585  EamDbUtil.closeResultSet(resultSet);
1586  EamDbUtil.closeConnection(conn);
1587  }
1588  }
1589 
1599  @Override
1601  Connection conn = connect();
1602 
1603  PreparedStatement preparedStatement = null;
1604  ResultSet resultSet = null;
1605  String sql = "SELECT * FROM organizations WHERE id=?";
1606 
1607  try {
1608  preparedStatement = conn.prepareStatement(sql);
1609  preparedStatement.setInt(1, orgID);
1610  resultSet = preparedStatement.executeQuery();
1611  resultSet.next();
1612  return getEamOrganizationFromResultSet(resultSet);
1613 
1614  } catch (SQLException ex) {
1615  throw new EamDbException("Error getting organization by id.", ex); // NON-NLS
1616  } finally {
1617  EamDbUtil.closePreparedStatement(preparedStatement);
1618  EamDbUtil.closeResultSet(resultSet);
1619  EamDbUtil.closeConnection(conn);
1620  }
1621  }
1622 
1630  @Override
1631  public EamOrganization getReferenceSetOrganization(int referenceSetID) throws EamDbException {
1632 
1633  EamGlobalSet globalSet = getReferenceSetByID(referenceSetID);
1634  if(globalSet == null) {
1635  throw new EamDbException("Reference set with ID " + referenceSetID + " not found");
1636  }
1637  return (getOrganizationByID(globalSet.getOrgID()));
1638  }
1639 
1648  @Override
1649  public void updateOrganization(EamOrganization updatedOrganization) throws EamDbException {
1650  if(updatedOrganization == null) {
1651  throw new EamDbException("null updatedOrganization");
1652  }
1653 
1654  Connection conn = connect();
1655  PreparedStatement preparedStatement = null;
1656  String sql = "UPDATE organizations SET org_name = ?, poc_name = ?, poc_email = ?, poc_phone = ? WHERE id = ?";
1657  try {
1658  preparedStatement = conn.prepareStatement(sql);
1659  preparedStatement.setString(1, updatedOrganization.getName());
1660  preparedStatement.setString(2, updatedOrganization.getPocName());
1661  preparedStatement.setString(3, updatedOrganization.getPocEmail());
1662  preparedStatement.setString(4, updatedOrganization.getPocPhone());
1663  preparedStatement.setInt(5, updatedOrganization.getOrgID());
1664  preparedStatement.executeUpdate();
1665  } catch (SQLException ex) {
1666  throw new EamDbException("Error updating organization.", ex); // NON-NLS
1667  } finally {
1668  EamDbUtil.closePreparedStatement(preparedStatement);
1669  EamDbUtil.closeConnection(conn);
1670  }
1671  }
1672 
1673  @Messages({"AbstractSqlEamDb.deleteOrganization.inUseException.message=Can not delete organization "
1674  + "which is currently in use by a case or reference set in the central repository.",
1675  "AbstractSqlEamDb.deleteOrganization.errorDeleting.message=Error executing query when attempting to delete organization by id."})
1676  @Override
1677  public void deleteOrganization(EamOrganization organizationToDelete) throws EamDbException {
1678  if(organizationToDelete == null) {
1679  throw new EamDbException("Organization to delete is null");
1680  }
1681 
1682  Connection conn = connect();
1683  PreparedStatement checkIfUsedStatement = null;
1684  ResultSet resultSet = null;
1685  String checkIfUsedSql = "SELECT (select count(*) FROM cases WHERE org_id=?) + (select count(*) FROM reference_sets WHERE org_id=?)";
1686  PreparedStatement deleteOrgStatement = null;
1687  String deleteOrgSql = "DELETE FROM organizations WHERE id=?";
1688  try {
1689  checkIfUsedStatement = conn.prepareStatement(checkIfUsedSql);
1690  checkIfUsedStatement.setInt(1, organizationToDelete.getOrgID());
1691  checkIfUsedStatement.setInt(2, organizationToDelete.getOrgID());
1692  resultSet = checkIfUsedStatement.executeQuery();
1693  resultSet.next();
1694  if (resultSet.getLong(1) > 0) {
1695  throw new EamDbException(Bundle.AbstractSqlEamDb_deleteOrganization_inUseException_message());
1696  }
1697  deleteOrgStatement = conn.prepareStatement(deleteOrgSql);
1698  deleteOrgStatement.setInt(1, organizationToDelete.getOrgID());
1699  deleteOrgStatement.executeUpdate();
1700  } catch (SQLException ex) {
1701  throw new EamDbException(Bundle.AbstractSqlEamDb_deleteOrganization_errorDeleting_message(), ex); // NON-NLS
1702  } finally {
1703  EamDbUtil.closePreparedStatement(checkIfUsedStatement);
1704  EamDbUtil.closePreparedStatement(deleteOrgStatement);
1705  EamDbUtil.closeResultSet(resultSet);
1706  EamDbUtil.closeConnection(conn);
1707  }
1708  }
1709 
1719  @Override
1720  public int newReferenceSet(EamGlobalSet eamGlobalSet) throws EamDbException {
1721  if(eamGlobalSet == null){
1722  throw new EamDbException("EamGlobalSet argument is null");
1723  }
1724 
1725  if(eamGlobalSet.getFileKnownStatus() == null){
1726  throw new EamDbException("File known status on the EamGlobalSet is null");
1727  }
1728 
1729  if(eamGlobalSet.getType() == null){
1730  throw new EamDbException("Type on the EamGlobalSet is null");
1731  }
1732 
1733  Connection conn = connect();
1734 
1735  PreparedStatement preparedStatement1 = null;
1736  PreparedStatement preparedStatement2 = null;
1737  ResultSet resultSet = null;
1738  String sql1 = "INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, type, import_date) VALUES (?, ?, ?, ?, ?, ?, ?)";
1739  String sql2 = "SELECT id FROM reference_sets WHERE org_id=? AND set_name=? AND version=? AND import_date=? LIMIT 1";
1740 
1741  try {
1742  preparedStatement1 = conn.prepareStatement(sql1);
1743  preparedStatement1.setInt(1, eamGlobalSet.getOrgID());
1744  preparedStatement1.setString(2, eamGlobalSet.getSetName());
1745  preparedStatement1.setString(3, eamGlobalSet.getVersion());
1746  preparedStatement1.setInt(4, eamGlobalSet.getFileKnownStatus().getFileKnownValue());
1747  preparedStatement1.setBoolean(5, eamGlobalSet.isReadOnly());
1748  preparedStatement1.setInt(6, eamGlobalSet.getType().getId());
1749  preparedStatement1.setString(7, eamGlobalSet.getImportDate().toString());
1750 
1751  preparedStatement1.executeUpdate();
1752 
1753  preparedStatement2 = conn.prepareStatement(sql2);
1754  preparedStatement2.setInt(1, eamGlobalSet.getOrgID());
1755  preparedStatement2.setString(2, eamGlobalSet.getSetName());
1756  preparedStatement2.setString(3, eamGlobalSet.getVersion());
1757  preparedStatement2.setString(4, eamGlobalSet.getImportDate().toString());
1758 
1759  resultSet = preparedStatement2.executeQuery();
1760  resultSet.next();
1761  return resultSet.getInt("id");
1762 
1763  } catch (SQLException ex) {
1764  throw new EamDbException("Error inserting new global set.", ex); // NON-NLS
1765  } finally {
1766  EamDbUtil.closePreparedStatement(preparedStatement1);
1767  EamDbUtil.closePreparedStatement(preparedStatement2);
1768  EamDbUtil.closeResultSet(resultSet);
1769  EamDbUtil.closeConnection(conn);
1770  }
1771  }
1772 
1782  @Override
1783  public EamGlobalSet getReferenceSetByID(int referenceSetID) throws EamDbException {
1784  Connection conn = connect();
1785 
1786  PreparedStatement preparedStatement1 = null;
1787  ResultSet resultSet = null;
1788  String sql1 = "SELECT * FROM reference_sets WHERE id=?";
1789 
1790  try {
1791  preparedStatement1 = conn.prepareStatement(sql1);
1792  preparedStatement1.setInt(1, referenceSetID);
1793  resultSet = preparedStatement1.executeQuery();
1794  if(resultSet.next()) {
1795  return getEamGlobalSetFromResultSet(resultSet);
1796  } else {
1797  return null;
1798  }
1799 
1800  } catch (SQLException ex) {
1801  throw new EamDbException("Error getting reference set by id.", ex); // NON-NLS
1802  } finally {
1803  EamDbUtil.closePreparedStatement(preparedStatement1);
1804  EamDbUtil.closeResultSet(resultSet);
1805  EamDbUtil.closeConnection(conn);
1806  }
1807  }
1808 
1818  @Override
1819  public List<EamGlobalSet> getAllReferenceSets(CorrelationAttribute.Type correlationType) throws EamDbException {
1820 
1821  if(correlationType == null){
1822  throw new EamDbException("Correlation type is null");
1823  }
1824 
1825  List<EamGlobalSet> results = new ArrayList<>();
1826  Connection conn = connect();
1827 
1828  PreparedStatement preparedStatement1 = null;
1829  ResultSet resultSet = null;
1830  String sql1 = "SELECT * FROM reference_sets WHERE type=" + correlationType.getId();
1831 
1832  try {
1833  preparedStatement1 = conn.prepareStatement(sql1);
1834  resultSet = preparedStatement1.executeQuery();
1835  while (resultSet.next()) {
1836  results.add(getEamGlobalSetFromResultSet(resultSet));
1837  }
1838 
1839  } catch (SQLException ex) {
1840  throw new EamDbException("Error getting reference sets.", ex); // NON-NLS
1841  } finally {
1842  EamDbUtil.closePreparedStatement(preparedStatement1);
1843  EamDbUtil.closeResultSet(resultSet);
1844  EamDbUtil.closeConnection(conn);
1845  }
1846  return results;
1847  }
1848 
1857  @Override
1858  public void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, CorrelationAttribute.Type correlationType) throws EamDbException {
1859  if(eamGlobalFileInstance.getKnownStatus() == null){
1860  throw new EamDbException("known status of EamGlobalFileInstance is null");
1861  }
1862  if(correlationType == null){
1863  throw new EamDbException("Correlation type is null");
1864  }
1865 
1866  Connection conn = connect();
1867 
1868  PreparedStatement preparedStatement = null;
1869 
1870  String sql = "INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?)";
1871 
1872  try {
1873  preparedStatement = conn.prepareStatement(String.format(sql, EamDbUtil.correlationTypeToReferenceTableName(correlationType)));
1874  preparedStatement.setInt(1, eamGlobalFileInstance.getGlobalSetID());
1875  preparedStatement.setString(2, eamGlobalFileInstance.getMD5Hash());
1876  preparedStatement.setByte(3, eamGlobalFileInstance.getKnownStatus().getFileKnownValue());
1877  preparedStatement.setString(4, eamGlobalFileInstance.getComment());
1878  preparedStatement.executeUpdate();
1879  } catch (SQLException ex) {
1880  throw new EamDbException("Error inserting new reference instance into reference_ table.", ex); // NON-NLS
1881  } finally {
1882  EamDbUtil.closePreparedStatement(preparedStatement);
1883  EamDbUtil.closeConnection(conn);
1884  }
1885  }
1886 
1897  @Override
1898  public boolean referenceSetExists(String referenceSetName, String version) throws EamDbException {
1899  Connection conn = connect();
1900 
1901  PreparedStatement preparedStatement1 = null;
1902  ResultSet resultSet = null;
1903  String sql1 = "SELECT * FROM reference_sets WHERE set_name=? AND version=?";
1904 
1905  try {
1906  preparedStatement1 = conn.prepareStatement(sql1);
1907  preparedStatement1.setString(1, referenceSetName);
1908  preparedStatement1.setString(2, version);
1909  resultSet = preparedStatement1.executeQuery();
1910  return (resultSet.next());
1911 
1912  } catch (SQLException ex) {
1913  throw new EamDbException("Error testing whether reference set exists (name: " + referenceSetName
1914  + " version: " + version, ex); // NON-NLS
1915  } finally {
1916  EamDbUtil.closePreparedStatement(preparedStatement1);
1917  EamDbUtil.closeResultSet(resultSet);
1918  EamDbUtil.closeConnection(conn);
1919  }
1920  }
1921 
1927  @Override
1928  public void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances, CorrelationAttribute.Type contentType) throws EamDbException {
1929  if(contentType == null) {
1930  throw new EamDbException("Null correlation type");
1931  }
1932  if(globalInstances == null) {
1933  throw new EamDbException("Null set of EamGlobalFileInstance");
1934  }
1935 
1936  Connection conn = connect();
1937 
1938  PreparedStatement bulkPs = null;
1939  try {
1940  conn.setAutoCommit(false);
1941 
1942  // FUTURE: have a separate global_files table for each Type.
1943  String sql = "INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) "
1944  + getConflictClause();
1945 
1946  bulkPs = conn.prepareStatement(String.format(sql, EamDbUtil.correlationTypeToReferenceTableName(contentType)));
1947 
1948  for (EamGlobalFileInstance globalInstance : globalInstances) {
1949  if(globalInstance.getKnownStatus() == null){
1950  throw new EamDbException("EamGlobalFileInstance with value " + globalInstance.getMD5Hash() + " has null known status");
1951  }
1952 
1953  bulkPs.setInt(1, globalInstance.getGlobalSetID());
1954  bulkPs.setString(2, globalInstance.getMD5Hash());
1955  bulkPs.setByte(3, globalInstance.getKnownStatus().getFileKnownValue());
1956  bulkPs.setString(4, globalInstance.getComment());
1957  bulkPs.addBatch();
1958  }
1959 
1960  bulkPs.executeBatch();
1961  conn.commit();
1962  } catch (SQLException | EamDbException ex) {
1963  try {
1964  conn.rollback();
1965  } catch (SQLException ex2) {
1966  // We're alredy in an error state
1967  }
1968  throw new EamDbException("Error inserting bulk artifacts.", ex); // NON-NLS
1969  } finally {
1971  EamDbUtil.closeConnection(conn);
1972  }
1973  }
1974 
1985  @Override
1986  public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(CorrelationAttribute.Type aType, String aValue) throws EamDbException {
1987  if(aType == null) {
1988  throw new EamDbException("correlation type is null");
1989  }
1990 
1991  Connection conn = connect();
1992 
1993  List<EamGlobalFileInstance> globalFileInstances = new ArrayList<>();
1994  PreparedStatement preparedStatement1 = null;
1995  ResultSet resultSet = null;
1996  String sql1 = "SELECT * FROM %s WHERE value=?";
1997 
1998  try {
1999  preparedStatement1 = conn.prepareStatement(String.format(sql1, EamDbUtil.correlationTypeToReferenceTableName(aType)));
2000  preparedStatement1.setString(1, aValue);
2001  resultSet = preparedStatement1.executeQuery();
2002  while (resultSet.next()) {
2003  globalFileInstances.add(getEamGlobalFileInstanceFromResultSet(resultSet));
2004  }
2005  return globalFileInstances;
2006 
2007  } catch (SQLException ex) {
2008  throw new EamDbException("Error getting reference instances by type and value.", ex); // NON-NLS
2009  } finally {
2010  EamDbUtil.closePreparedStatement(preparedStatement1);
2011  EamDbUtil.closeResultSet(resultSet);
2012  EamDbUtil.closeConnection(conn);
2013  }
2014  }
2015 
2025  @Override
2027  if (newType == null) {
2028  throw new EamDbException("null correlation type");
2029  }
2030 
2031  Connection conn = connect();
2032 
2033  PreparedStatement preparedStatement = null;
2034  PreparedStatement preparedStatementQuery = null;
2035  ResultSet resultSet = null;
2036  int typeId = 0;
2037  String insertSql;
2038  String querySql;
2039  // if we have a known ID, use it, if not (is -1) let the db assign it.
2040  if (-1 == newType.getId()) {
2041  insertSql = "INSERT INTO correlation_types(display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?)";
2042  } else {
2043  insertSql = "INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?)";
2044  }
2045  querySql = "SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
2046 
2047  try {
2048  preparedStatement = conn.prepareStatement(insertSql);
2049 
2050  if (-1 == newType.getId()) {
2051  preparedStatement.setString(1, newType.getDisplayName());
2052  preparedStatement.setString(2, newType.getDbTableName());
2053  preparedStatement.setInt(3, newType.isSupported() ? 1 : 0);
2054  preparedStatement.setInt(4, newType.isEnabled() ? 1 : 0);
2055  } else {
2056  preparedStatement.setInt(1, newType.getId());
2057  preparedStatement.setString(2, newType.getDisplayName());
2058  preparedStatement.setString(3, newType.getDbTableName());
2059  preparedStatement.setInt(4, newType.isSupported() ? 1 : 0);
2060  preparedStatement.setInt(5, newType.isEnabled() ? 1 : 0);
2061  }
2062 
2063  preparedStatement.executeUpdate();
2064 
2065  preparedStatementQuery = conn.prepareStatement(querySql);
2066  preparedStatementQuery.setString(1, newType.getDisplayName());
2067  preparedStatementQuery.setString(2, newType.getDbTableName());
2068 
2069  resultSet = preparedStatementQuery.executeQuery();
2070  if (resultSet.next()) {
2071  CorrelationAttribute.Type correlationType = getCorrelationTypeFromResultSet(resultSet);
2072  typeId = correlationType.getId();
2073  }
2074  } catch (SQLException ex) {
2075  throw new EamDbException("Error inserting new correlation type.", ex); // NON-NLS
2076  } finally {
2077  EamDbUtil.closePreparedStatement(preparedStatement);
2078  EamDbUtil.closePreparedStatement(preparedStatementQuery);
2079  EamDbUtil.closeResultSet(resultSet);
2080  EamDbUtil.closeConnection(conn);
2081  }
2082  return typeId;
2083  }
2084 
2085  @Override
2087  Connection conn = connect();
2088 
2089  List<CorrelationAttribute.Type> aTypes = new ArrayList<>();
2090  PreparedStatement preparedStatement = null;
2091  ResultSet resultSet = null;
2092  String sql = "SELECT * FROM correlation_types";
2093 
2094  try {
2095  preparedStatement = conn.prepareStatement(sql);
2096  resultSet = preparedStatement.executeQuery();
2097  while (resultSet.next()) {
2098  aTypes.add(getCorrelationTypeFromResultSet(resultSet));
2099  }
2100  return aTypes;
2101 
2102  } catch (SQLException ex) {
2103  throw new EamDbException("Error getting all correlation types.", ex); // NON-NLS
2104  } finally {
2105  EamDbUtil.closePreparedStatement(preparedStatement);
2106  EamDbUtil.closeResultSet(resultSet);
2107  EamDbUtil.closeConnection(conn);
2108  }
2109  }
2110 
2120  @Override
2122  Connection conn = connect();
2123 
2124  List<CorrelationAttribute.Type> aTypes = new ArrayList<>();
2125  PreparedStatement preparedStatement = null;
2126  ResultSet resultSet = null;
2127  String sql = "SELECT * FROM correlation_types WHERE enabled=1";
2128 
2129  try {
2130  preparedStatement = conn.prepareStatement(sql);
2131  resultSet = preparedStatement.executeQuery();
2132  while (resultSet.next()) {
2133  aTypes.add(getCorrelationTypeFromResultSet(resultSet));
2134  }
2135  return aTypes;
2136 
2137  } catch (SQLException ex) {
2138  throw new EamDbException("Error getting enabled correlation types.", ex); // NON-NLS
2139  } finally {
2140  EamDbUtil.closePreparedStatement(preparedStatement);
2141  EamDbUtil.closeResultSet(resultSet);
2142  EamDbUtil.closeConnection(conn);
2143  }
2144  }
2145 
2155  @Override
2157  Connection conn = connect();
2158 
2159  List<CorrelationAttribute.Type> aTypes = new ArrayList<>();
2160  PreparedStatement preparedStatement = null;
2161  ResultSet resultSet = null;
2162  String sql = "SELECT * FROM correlation_types WHERE supported=1";
2163 
2164  try {
2165  preparedStatement = conn.prepareStatement(sql);
2166  resultSet = preparedStatement.executeQuery();
2167  while (resultSet.next()) {
2168  aTypes.add(getCorrelationTypeFromResultSet(resultSet));
2169  }
2170  return aTypes;
2171 
2172  } catch (SQLException ex) {
2173  throw new EamDbException("Error getting supported correlation types.", ex); // NON-NLS
2174  } finally {
2175  EamDbUtil.closePreparedStatement(preparedStatement);
2176  EamDbUtil.closeResultSet(resultSet);
2177  EamDbUtil.closeConnection(conn);
2178  }
2179  }
2180 
2188  @Override
2190  Connection conn = connect();
2191 
2192  PreparedStatement preparedStatement = null;
2193  String sql = "UPDATE correlation_types SET display_name=?, db_table_name=?, supported=?, enabled=? WHERE id=?";
2194 
2195  try {
2196  preparedStatement = conn.prepareStatement(sql);
2197  preparedStatement.setString(1, aType.getDisplayName());
2198  preparedStatement.setString(2, aType.getDbTableName());
2199  preparedStatement.setInt(3, aType.isSupported() ? 1 : 0);
2200  preparedStatement.setInt(4, aType.isEnabled() ? 1 : 0);
2201  preparedStatement.setInt(5, aType.getId());
2202  preparedStatement.executeUpdate();
2203 
2204  } catch (SQLException ex) {
2205  throw new EamDbException("Error updating correlation type.", ex); // NON-NLS
2206  } finally {
2207  EamDbUtil.closePreparedStatement(preparedStatement);
2208  EamDbUtil.closeConnection(conn);
2209  }
2210 
2211  }
2212 
2222  @Override
2224  Connection conn = connect();
2225 
2226  CorrelationAttribute.Type aType;
2227  PreparedStatement preparedStatement = null;
2228  ResultSet resultSet = null;
2229  String sql = "SELECT * FROM correlation_types WHERE id=?";
2230 
2231  try {
2232  preparedStatement = conn.prepareStatement(sql);
2233  preparedStatement.setInt(1, typeId);
2234  resultSet = preparedStatement.executeQuery();
2235  if(resultSet.next()) {
2236  aType = getCorrelationTypeFromResultSet(resultSet);
2237  return aType;
2238  } else {
2239  throw new EamDbException("Failed to find entry for correlation type ID = " + typeId);
2240  }
2241 
2242  } catch (SQLException ex) {
2243  throw new EamDbException("Error getting correlation type by id.", ex); // NON-NLS
2244  } finally {
2245  EamDbUtil.closePreparedStatement(preparedStatement);
2246  EamDbUtil.closeResultSet(resultSet);
2247  EamDbUtil.closeConnection(conn);
2248  }
2249  }
2250 
2261  private CorrelationCase getEamCaseFromResultSet(ResultSet resultSet) throws SQLException {
2262  if (null == resultSet) {
2263  return null;
2264  }
2265 
2266  EamOrganization eamOrg = null;
2267 
2268  resultSet.getInt("org_id");
2269  if (!resultSet.wasNull()) {
2270 
2271  eamOrg = new EamOrganization(resultSet.getInt("org_id"),
2272  resultSet.getString("org_name"),
2273  resultSet.getString("poc_name"),
2274  resultSet.getString("poc_email"),
2275  resultSet.getString("poc_phone"));
2276  }
2277 
2278  CorrelationCase eamCase = new CorrelationCase(resultSet.getInt("case_id"), resultSet.getString("case_uid"), resultSet.getString("case_name"));
2279  eamCase.setOrg(eamOrg);
2280  eamCase.setCreationDate(resultSet.getString("creation_date"));
2281  eamCase.setCaseNumber(resultSet.getString("case_number"));
2282  eamCase.setExaminerName(resultSet.getString("examiner_name"));
2283  eamCase.setExaminerEmail(resultSet.getString("examiner_email"));
2284  eamCase.setExaminerPhone(resultSet.getString("examiner_phone"));
2285  eamCase.setNotes(resultSet.getString("notes"));
2286 
2287  return eamCase;
2288  }
2289 
2290  private CorrelationDataSource getEamDataSourceFromResultSet(ResultSet resultSet) throws SQLException {
2291  if (null == resultSet) {
2292  return null;
2293  }
2294 
2295  CorrelationDataSource eamDataSource = new CorrelationDataSource(
2296  resultSet.getInt("case_id"),
2297  resultSet.getInt("id"),
2298  resultSet.getString("device_id"),
2299  resultSet.getString("name")
2300  );
2301 
2302  return eamDataSource;
2303  }
2304 
2305  private CorrelationAttribute.Type getCorrelationTypeFromResultSet(ResultSet resultSet) throws EamDbException, SQLException {
2306  if (null == resultSet) {
2307  return null;
2308  }
2309 
2310  CorrelationAttribute.Type eamArtifactType = new CorrelationAttribute.Type(
2311  resultSet.getInt("id"),
2312  resultSet.getString("display_name"),
2313  resultSet.getString("db_table_name"),
2314  resultSet.getBoolean("supported"),
2315  resultSet.getBoolean("enabled")
2316  );
2317 
2318  return eamArtifactType;
2319  }
2320 
2331  private CorrelationAttributeInstance getEamArtifactInstanceFromResultSet(ResultSet resultSet) throws SQLException, EamDbException {
2332  if (null == resultSet) {
2333  return null;
2334  }
2336  new CorrelationCase(resultSet.getInt("case_id"), resultSet.getString("case_uid"), resultSet.getString("case_name")),
2337  new CorrelationDataSource(resultSet.getInt("case_id"), -1, resultSet.getString("device_id"), resultSet.getString("name")),
2338  resultSet.getString("file_path"),
2339  resultSet.getString("comment"),
2340  TskData.FileKnown.valueOf(resultSet.getByte("known_status"))
2341  );
2342 
2343  return eamArtifactInstance;
2344  }
2345 
2346  private EamOrganization getEamOrganizationFromResultSet(ResultSet resultSet) throws SQLException {
2347  if (null == resultSet) {
2348  return null;
2349  }
2350 
2351  EamOrganization eamOrganization = new EamOrganization(
2352  resultSet.getInt("id"),
2353  resultSet.getString("org_name"),
2354  resultSet.getString("poc_name"),
2355  resultSet.getString("poc_email"),
2356  resultSet.getString("poc_phone")
2357  );
2358 
2359  return eamOrganization;
2360  }
2361 
2362  private EamGlobalSet getEamGlobalSetFromResultSet(ResultSet resultSet) throws SQLException, EamDbException {
2363  if (null == resultSet) {
2364  return null;
2365  }
2366 
2367  EamGlobalSet eamGlobalSet = new EamGlobalSet(
2368  resultSet.getInt("id"),
2369  resultSet.getInt("org_id"),
2370  resultSet.getString("set_name"),
2371  resultSet.getString("version"),
2372  TskData.FileKnown.valueOf(resultSet.getByte("known_status")),
2373  resultSet.getBoolean("read_only"),
2374  EamDb.getInstance().getCorrelationTypeById(resultSet.getInt("type")),
2375  LocalDate.parse(resultSet.getString("import_date"))
2376  );
2377 
2378  return eamGlobalSet;
2379  }
2380 
2381  private EamGlobalFileInstance getEamGlobalFileInstanceFromResultSet(ResultSet resultSet) throws SQLException, EamDbException {
2382  if (null == resultSet) {
2383  return null;
2384  }
2385 
2386  EamGlobalFileInstance eamGlobalFileInstance = new EamGlobalFileInstance(
2387  resultSet.getInt("id"),
2388  resultSet.getInt("reference_set_id"),
2389  resultSet.getString("value"),
2390  TskData.FileKnown.valueOf(resultSet.getByte("known_status")),
2391  resultSet.getString("comment")
2392  );
2393 
2394  return eamGlobalFileInstance;
2395  }
2396 
2402  @Override
2403  public void upgradeSchema() throws EamDbException, SQLException {
2404 
2405  ResultSet resultSet = null;
2406  Statement statement;
2407  Connection conn = null;
2408  try {
2409 
2410  conn = connect();
2411  conn.setAutoCommit(false);
2412  statement = conn.createStatement();
2413 
2414  int minorVersion = 0;
2415  int majorVersion = 0;
2416  resultSet = statement.executeQuery("SELECT value FROM db_info WHERE name='SCHEMA_MINOR_VERSION'");
2417  if (resultSet.next()) {
2418  String minorVersionStr = resultSet.getString("value");
2419  try {
2420  minorVersion = Integer.parseInt(minorVersionStr);
2421  } catch (NumberFormatException ex) {
2422  throw new EamDbException("Bad value for schema minor version (" + minorVersionStr + ") - database is corrupt");
2423  }
2424  }
2425 
2426  resultSet = statement.executeQuery("SELECT value FROM db_info WHERE name='SCHEMA_VERSION'");
2427  if (resultSet.next()) {
2428  String majorVersionStr = resultSet.getString("value");
2429  try {
2430  majorVersion = Integer.parseInt(majorVersionStr);
2431  } catch (NumberFormatException ex) {
2432  throw new EamDbException("Bad value for schema version (" + majorVersionStr + ") - database is corrupt");
2433  }
2434  }
2435 
2436  CaseDbSchemaVersionNumber dbSchemaVersion = new CaseDbSchemaVersionNumber(majorVersion, minorVersion);
2437  if (dbSchemaVersion.equals(CURRENT_DB_SCHEMA_VERSION)) {
2438  LOGGER.log(Level.INFO, "Central Repository is up to date");
2439  return;
2440  }
2441 
2442  // Update from 1.0 to 1.1
2443  if (dbSchemaVersion.compareTo(new CaseDbSchemaVersionNumber(1, 1)) < 0) {
2444  statement.execute("ALTER TABLE reference_sets ADD COLUMN known_status INTEGER;"); //NON-NLS
2445  statement.execute("ALTER TABLE reference_sets ADD COLUMN read_only BOOLEAN;"); //NON-NLS
2446  statement.execute("ALTER TABLE reference_sets ADD COLUMN type INTEGER;"); //NON-NLS
2447 
2448  // There's an outide chance that the user has already made an organization with the default name,
2449  // and the default org being missing will not impact any database operations, so continue on
2450  // regardless of whether this succeeds.
2451  EamDbUtil.insertDefaultOrganization(conn);
2452  }
2453 
2454  if (!updateSchemaVersion(conn)) {
2455  throw new EamDbException("Error updating schema version");
2456  }
2457 
2458  conn.commit();
2459  LOGGER.log(Level.INFO, "Central Repository upgraded to version " + CURRENT_DB_SCHEMA_VERSION);
2460  } catch (SQLException | EamDbException ex) {
2461  try {
2462  if (conn != null) {
2463  conn.rollback();
2464  }
2465  } catch (SQLException ex2) {
2466  LOGGER.log(Level.SEVERE, "Database rollback failed", ex2);
2467  }
2468  throw ex;
2469  } finally {
2470  EamDbUtil.closeResultSet(resultSet);
2471  EamDbUtil.closeConnection(conn);
2472  }
2473  }
2474 
2475 }
CorrelationAttribute.Type getCorrelationTypeById(int typeId)
List< CorrelationAttributeInstance > getArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value)
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: Tue Feb 20 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.