19 package org.sleuthkit.datamodel;
21 import com.google.common.base.Strings;
22 import java.sql.PreparedStatement;
23 import java.sql.ResultSet;
24 import java.sql.SQLException;
25 import java.sql.Statement;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.List;
29 import java.util.Optional;
30 import java.util.stream.Collectors;
59 String queryString =
"SELECT * FROM tsk_persons";
61 List<Person> persons =
new ArrayList<>();
63 try (CaseDbConnection connection = this.db.getConnection();
64 Statement s = connection.createStatement();
65 ResultSet rs = connection.executeQuery(s, queryString)) {
68 persons.add(
new Person(rs.getLong(
"id"), rs.getString(
"name")));
72 }
catch (SQLException ex) {
73 throw new TskCoreException(String.format(
"Error getting persons"), ex);
91 if (Strings.isNullOrEmpty(person.getName())) {
92 throw new TskCoreException(
"Illegal argument passed to updatePerson: Name field for person with ID " + person.getPersonId() +
" is null/empty. Will not update database.");
95 String queryString =
"UPDATE tsk_persons"
96 +
" SET name = ? WHERE id = " + person.getPersonId();
98 try (CaseDbConnection connection = db.getConnection()) {
99 PreparedStatement s = connection.getPreparedStatement(queryString, Statement.NO_GENERATED_KEYS);
101 s.setString(1, person.getName());
103 }
catch (SQLException ex) {
104 throw new TskCoreException(String.format(
"Error updating person with id = %d", person.getPersonId()), ex);
121 String queryString =
"DELETE FROM tsk_persons"
122 +
" WHERE LOWER(name) = LOWER(?)";
124 Person deletedPerson = null;
126 try (CaseDbConnection connection = db.getConnection()) {
127 PreparedStatement s = connection.getPreparedStatement(queryString, Statement.RETURN_GENERATED_KEYS);
129 s.setString(1, name);
132 try (ResultSet resultSet = s.getGeneratedKeys()) {
133 if (resultSet.next()) {
134 deletedPerson =
new Person(resultSet.getLong(1), name);
137 }
catch (SQLException ex) {
138 throw new TskCoreException(String.format(
"Error deleting person with name %s", name), ex);
143 if (deletedPerson != null) {
160 try (CaseDbConnection connection = this.db.getConnection()) {
178 String queryString =
"SELECT * FROM tsk_persons WHERE id = " + id;
180 try (CaseDbConnection connection = this.db.getConnection();
181 Statement s = connection.createStatement();
182 ResultSet rs = connection.executeQuery(s, queryString)) {
185 return Optional.of(
new Person(rs.getLong(
"id"), rs.getString(
"name")));
187 return Optional.empty();
189 }
catch (SQLException ex) {
210 if (Strings.isNullOrEmpty(name)) {
211 throw new TskCoreException(
"Illegal argument passed to createPerson: Non-empty name is required.");
215 CaseDbConnection connection = null;
218 connection = db.getConnection();
222 Optional<Person> person =
getPerson(name, connection);
223 if (person.isPresent()) {
228 String personInsertSQL =
"INSERT INTO tsk_persons(name) VALUES (?)";
229 PreparedStatement preparedStatement = connection.getPreparedStatement(personInsertSQL, Statement.RETURN_GENERATED_KEYS);
230 preparedStatement.clearParameters();
231 preparedStatement.setString(1, name);
232 connection.executeUpdate(preparedStatement);
235 try (ResultSet resultSet = preparedStatement.getGeneratedKeys();) {
236 if (resultSet.next()) {
237 toReturn =
new Person(resultSet.getLong(1), name);
239 throw new SQLException(
"Error executing SQL: " + personInsertSQL);
242 }
catch (SQLException ex) {
243 if (connection != null) {
246 Optional<Person> person =
getPerson(name, connection);
247 if (person.isPresent()) {
251 throw new TskCoreException(String.format(
"Error adding person with name = %s", name), ex);
256 if (toReturn != null) {
273 return executeHostsQuery(
"SELECT * FROM tsk_hosts WHERE person_id = " + person.getPersonId());
285 return executeHostsQuery(
"SELECT * FROM tsk_hosts WHERE person_id IS NULL");
298 private List<Host> executeHostsQuery(String hostsQuery)
throws TskCoreException {
299 String sql = hostsQuery +
" AND db_status = " +
Host.
HostDbStatus.ACTIVE.getId();
300 List<Host> hosts =
new ArrayList<>();
302 try (CaseDbConnection connection = this.db.getConnection();
303 Statement s = connection.createStatement();
304 ResultSet rs = connection.executeQuery(s, sql)) {
306 hosts.add(
new Host(rs.getLong(
"id"), rs.getString(
"name"),
Host.
HostDbStatus.fromID(rs.getInt(
"db_status"))));
309 }
catch (SQLException ex) {
310 throw new TskCoreException(String.format(
"Error executing '" + sql +
"'"), ex);
327 private Optional<Person>
getPerson(String name, CaseDbConnection connection)
throws TskCoreException {
329 String queryString =
"SELECT * FROM tsk_persons"
330 +
" WHERE LOWER(name) = LOWER(?)";
332 PreparedStatement s = connection.getPreparedStatement(queryString, Statement.RETURN_GENERATED_KEYS);
334 s.setString(1, name);
336 try (ResultSet rs = s.executeQuery()) {
338 return Optional.empty();
340 return Optional.of(
new Person(rs.getLong(
"id"), rs.getString(
"name")));
343 }
catch (SQLException ex) {
344 throw new TskCoreException(String.format(
"Error getting person with name = %s", name), ex);
359 String queryString =
"SELECT p.id AS personId, p.name AS name FROM \n"
360 +
"tsk_persons p INNER JOIN tsk_hosts h\n"
361 +
"ON p.id = h.person_id \n"
362 +
"WHERE h.id = " + host.getHostId();
365 try (CaseDbConnection connection = this.db.getConnection();
366 Statement s = connection.createStatement();
367 ResultSet rs = connection.executeQuery(s, queryString)) {
370 return Optional.of(
new Person(rs.getLong(
"personId"), rs.getString(
"name")));
372 return Optional.empty();
374 }
catch (SQLException ex) {
375 throw new TskCoreException(String.format(
"Error getting person for host with ID = %d", host.getHostId()), ex);
390 if (person == null) {
393 if (hosts == null || hosts.isEmpty()) {
394 throw new TskCoreException(
"Illegal argument: hosts must be non-null and non-empty");
408 if (person == null) {
411 if (hosts == null || hosts.isEmpty()) {
412 throw new TskCoreException(
"Illegal argument: hosts must be non-null and non-empty");
414 List<Long> hostIds = getHostIds(hosts);
430 String updateSql = null;
432 try (CaseDbConnection connection = this.db.getConnection(); Statement statement = connection.createStatement()) {
433 updateSql = (person == null)
434 ? String.format(
"UPDATE tsk_hosts SET person_id = NULL")
435 : String.format(
"UPDATE tsk_hosts SET person_id = %d", person.getPersonId());
436 String hostIdsCsvList = hostIds.stream()
437 .map(hostId -> hostId.toString())
438 .collect(Collectors.joining(
","));
439 updateSql +=
" WHERE id IN (" + hostIdsCsvList +
")";
440 statement.executeUpdate(updateSql);
441 db.fireTSKEvent(event);
442 }
catch (SQLException ex) {
443 throw new TskCoreException(String.format(updateSql == null ?
"Error connecting to case database" :
"Error executing '" + updateSql +
"'"), ex);
456 private List<Long> getHostIds(List<Host> hosts) {
457 List<Long> hostIds =
new ArrayList<>();
458 hostIds.addAll(hosts.stream()
459 .map(host -> host.getHostId())
460 .collect(Collectors.toList()));
Optional< Person > getPerson(String name)
List< Host > getHostsWithoutPersons()
List< Person > getPersons()
void deletePerson(String name)
Optional< Person > getPerson(Host host)
void removeHostsFromPerson(Person person, List< Host > hosts)
Person updatePerson(Person person)
void releaseSingleUserCaseReadLock()
void acquireSingleUserCaseWriteLock()
Person newPerson(String name)
void releaseSingleUserCaseWriteLock()
Optional< Person > getPerson(long id)
void acquireSingleUserCaseReadLock()
void addHostsToPerson(Person person, List< Host > hosts)
List< Host > getHostsForPerson(Person person)