diff --git a/bindings/java/src/org/sleuthkit/datamodel/CommunicationsManager.java b/bindings/java/src/org/sleuthkit/datamodel/CommunicationsManager.java index 4fefb10606bb1f8cb59694f35222527d843212a3..5b1aaa05fd99b552781a4e35e92474933ba5cf7d 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/CommunicationsManager.java +++ b/bindings/java/src/org/sleuthkit/datamodel/CommunicationsManager.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.datamodel; +import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; @@ -35,6 +36,7 @@ import java.util.logging.Logger; import org.sleuthkit.datamodel.Blackboard.BlackboardException; import org.sleuthkit.datamodel.SleuthkitCase.CaseDbConnection; +import org.sleuthkit.datamodel.SleuthkitCase.CaseDbTransaction; import static org.sleuthkit.datamodel.SleuthkitCase.closeResultSet; import static org.sleuthkit.datamodel.SleuthkitCase.closeStatement; @@ -364,7 +366,7 @@ public void addRelationships(AccountFileInstance sender, List<AccountFileInstanc * correctly. */ // Currently we do not save the direction of communication - List<Long> accountIDs = new ArrayList<Long>(); + List<Long> accountIDs = new ArrayList<>(); if (null != sender) { accountIDs.add(sender.getAccount().getAccountID()); @@ -381,17 +383,50 @@ public void addRelationships(AccountFileInstance sender, List<AccountFileInstanc + "Recipient source ID" + recipient.getDataSourceObjectID() + " != relationship source ID" + sourceArtifact.getDataSourceObjectID()); } } + + // Set up the query for the prepared statement + String query = "INTO account_relationships (account1_id, account2_id, relationship_source_obj_id, date_time, relationship_type, data_source_obj_id ) " + + "VALUES (?,?,?,?,?,?)"; + switch (db.getDatabaseType()) { + case POSTGRESQL: + query = "INSERT " + query + " ON CONFLICT DO NOTHING"; + break; + case SQLITE: + query = "INSERT OR IGNORE " + query; + break; + default: + throw new TskCoreException("Unknown DB Type: " + db.getDatabaseType().name()); + } + + CaseDbTransaction trans = db.beginTransaction(); + try { + SleuthkitCase.CaseDbConnection connection = trans.getConnection(); + PreparedStatement preparedStatement = connection.getPreparedStatement(query, Statement.NO_GENERATED_KEYS); + + for (int i = 0; i < accountIDs.size(); i++) { + for (int j = i + 1; j < accountIDs.size(); j++) { + long account1_id = accountIDs.get(i); + long account2_id = accountIDs.get(j); + + preparedStatement.clearParameters(); + preparedStatement.setLong(1, account1_id); + preparedStatement.setLong(2, account2_id); + preparedStatement.setLong(3, sourceArtifact.getId()); + if (dateTime > 0) { + preparedStatement.setLong(4, dateTime); + } else { + preparedStatement.setNull(4, java.sql.Types.BIGINT); + } + preparedStatement.setInt(5, relationshipType.getTypeID()); + preparedStatement.setLong(6, sourceArtifact.getDataSourceObjectID()); - for (int i = 0; i < accountIDs.size(); i++) { - for (int j = i + 1; j < accountIDs.size(); j++) { - try { - addAccountsRelationship(accountIDs.get(i), accountIDs.get(j), - sourceArtifact, relationshipType, dateTime); - } catch (TskCoreException ex) { - // @@@ This should probably not be caught and instead we stop adding - LOGGER.log(Level.WARNING, "Error adding relationship", ex); //NON-NLS + connection.executeUpdate(preparedStatement); } } + trans.commit(); + } catch (SQLException ex) { + trans.rollback(); + throw new TskCoreException("Error adding accounts relationship", ex); } } @@ -586,55 +621,6 @@ public org.sleuthkit.datamodel.Account.Type getAccountType(String accountTypeNam } } - /** - * Add a row in account relationships table. - * - * @param account1_id account_id for account1 - * @param account2_id account_id for account2 - * @param relationshipaArtifact relationship artifact - * @param relationshipType The type of relationship to be created - * @param dateTime datetime of communication/relationship as - * epoch seconds - * - * @throws TskCoreException exception thrown if a critical error occurs - * within TSK core - */ - private void addAccountsRelationship(long account1_id, long account2_id, BlackboardArtifact relationshipaArtifact, Relationship.Type relationshipType, long dateTime) throws TskCoreException { - CaseDbConnection connection = db.getConnection(); - db.acquireSingleUserCaseWriteLock(); - Statement s = null; - ResultSet rs = null; - - try { - String dateTimeValStr = (dateTime > 0) ? Long.toString(dateTime) : "NULL"; - - connection.beginTransaction(); - s = connection.createStatement(); - String query = "INTO account_relationships (account1_id, account2_id, relationship_source_obj_id, date_time, relationship_type, data_source_obj_id ) " - + "VALUES ( " + account1_id + ", " + account2_id + ", " + relationshipaArtifact.getId() + ", " + dateTimeValStr + ", " + relationshipType.getTypeID() + ", " + relationshipaArtifact.getDataSourceObjectID() + ")"; - switch (db.getDatabaseType()) { - case POSTGRESQL: - query = "INSERT " + query + " ON CONFLICT DO NOTHING"; - break; - case SQLITE: - query = "INSERT OR IGNORE " + query; - break; - default: - throw new TskCoreException("Unknown DB Type: " + db.getDatabaseType().name()); - } - s.execute(query); //NON-NLS - connection.commitTransaction(); - } catch (SQLException ex) { - connection.rollbackTransaction(); - throw new TskCoreException("Error adding accounts relationship", ex); - } finally { - closeResultSet(rs); - closeStatement(s); - connection.close(); - db.releaseSingleUserCaseWriteLock(); - } - } - /** * Returns a list of AccountDeviceInstances that have at least one * relationship that meets the criteria listed in the filters.