19 package org.sleuthkit.datamodel;
21 import java.sql.PreparedStatement;
22 import java.sql.ResultSet;
23 import java.sql.SQLException;
24 import java.sql.Statement;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Optional;
32 import java.util.logging.Logger;
33 import java.util.stream.Collectors;
47 private static final Logger LOGGER = Logger.getLogger(
ScoringManager.class.getName());
72 try (CaseDbConnection connection = db.getConnection()) {
91 if (objIds.isEmpty()) {
92 return Collections.emptyMap();
97 Set<Long> set =
new HashSet<>(objIds);
99 String queryString =
"SELECT obj_id, significance, priority FROM tsk_aggregate_score WHERE obj_id in "
100 + set.stream().map(l -> l.toString()).collect(Collectors.joining(
",",
"(",
")"));
102 Map<Long, Score> results = set.stream().collect(Collectors.toMap( key -> key, key ->
Score.
SCORE_UNKNOWN));
104 try (CaseDbConnection connection = db.getConnection()) {
105 try (Statement s = connection.createStatement(); ResultSet rs = connection.executeQuery(s, queryString)) {
107 Long objId = rs.getLong(
"obj_id");
109 results.put(objId, score);
111 }
catch (SQLException ex) {
112 throw new TskCoreException(
"SQLException thrown while running query: " + queryString, ex);
134 CaseDbConnection connection = transaction.getConnection();
149 private Optional<Score>
getAggregateScore(
long objId,
boolean forUpdate, CaseDbConnection connection)
throws TskCoreException {
150 String queryString =
"SELECT significance, priority FROM tsk_aggregate_score WHERE obj_id = " + objId + (forUpdate?
" FOR UPDATE " :
"");
151 try (Statement s = connection.createStatement(); ResultSet rs = connection.executeQuery(s, queryString)) {
153 return Optional.of(
new Score(Significance.fromID(rs.getInt(
"significance")), Priority.fromID(rs.getInt(
"priority"))));
155 return Optional.empty();
157 }
catch (SQLException ex) {
158 throw new TskCoreException(
"SQLException thrown while running query: " + queryString, ex);
175 private void setAggregateScore(
long objId, Long dataSourceObjectId, Score score,
boolean updateOnly, CaseDbTransaction transaction)
throws TskCoreException {
178 String updateSQLString =
" UPDATE tsk_aggregate_score SET significance = ?, priority = ? where obj_id = ?" ;
180 CaseDbConnection connection = transaction.getConnection();
182 PreparedStatement preparedStatement = connection.getPreparedStatement(updateSQLString, Statement.NO_GENERATED_KEYS);
183 preparedStatement.clearParameters();
185 preparedStatement.setInt(1, score.getSignificance().getId());
186 preparedStatement.setInt(2, score.getPriority().getId());
188 preparedStatement.setLong(3, objId);
190 connection.executeUpdate(preparedStatement);
191 }
catch (SQLException ex) {
192 throw new TskCoreException(String.format(
"Error updating aggregate score, query: %s for objId = %d", updateSQLString, objId), ex);
196 String insertSQLString =
"INSERT INTO tsk_aggregate_score (obj_id, data_source_obj_id, significance , priority) VALUES (?, ?, ?, ?)"
197 +
" ON CONFLICT (obj_id) DO UPDATE SET significance = ?, priority = ?";
199 CaseDbConnection connection = transaction.getConnection();
201 PreparedStatement preparedStatement = connection.getPreparedStatement(insertSQLString, Statement.NO_GENERATED_KEYS);
202 preparedStatement.clearParameters();
204 preparedStatement.setLong(1, objId);
205 if (dataSourceObjectId != null) {
206 preparedStatement.setLong(2, dataSourceObjectId);
208 preparedStatement.setNull(2, java.sql.Types.NULL);
210 preparedStatement.setInt(3, score.getSignificance().getId());
211 preparedStatement.setInt(4, score.getPriority().getId());
213 preparedStatement.setInt(5, score.getSignificance().getId());
214 preparedStatement.setInt(6, score.getPriority().getId());
216 connection.executeUpdate(preparedStatement);
217 }
catch (SQLException ex) {
218 throw new TskCoreException(String.format(
"Error updating aggregate score, query: %s for objId = %d", insertSQLString, objId), ex);
239 Score updateAggregateScoreAfterAddition(
long objId, Long dataSourceObjectId, Score newResultScore, CaseDbTransaction transaction)
throws TskCoreException {
253 Optional<Score> oCurrentAggregateScore = ScoringManager.this.getAggregateScore(objId, db.
getDatabaseType().equals(DbType.POSTGRESQL), transaction);
255 Score currentAggregateScore = oCurrentAggregateScore.orElse(Score.SCORE_UNKNOWN);
259 if ( (currentAggregateScore.compareTo(Score.SCORE_UNKNOWN) == 0 && newResultScore.compareTo(Score.SCORE_UNKNOWN) != 0)
260 || (Score.getScoreComparator().compare(newResultScore, currentAggregateScore) > 0)) {
261 setAggregateScore(objId, dataSourceObjectId, newResultScore, oCurrentAggregateScore.isPresent(), transaction);
263 transaction.registerScoreChange(
new ScoreChange(objId, dataSourceObjectId, currentAggregateScore, newResultScore));
264 return newResultScore;
267 return currentAggregateScore;
281 Score updateAggregateScoreAfterDeletion(
long objId, Long dataSourceObjectId, CaseDbTransaction transaction)
throws TskCoreException {
283 CaseDbConnection connection = transaction.getConnection();
296 Optional<Score> oCurrentAggregateScore = ScoringManager.this.getAggregateScore(objId, db.
getDatabaseType().equals(DbType.POSTGRESQL), transaction);
298 Score currentScore = oCurrentAggregateScore.orElse(Score.SCORE_UNKNOWN);
302 Score newScore = Score.SCORE_UNKNOWN;
303 for (AnalysisResult iter : analysisResults) {
304 Score iterScore = iter.getScore();
305 if (Score.getScoreComparator().compare(iterScore, newScore) > 0) {
306 newScore = iterScore;
312 Optional<Score> tagScore = db.
getTaggingManager().getMaxTagType(objId, transaction)
313 .map(knownStatus -> TaggingManager.getTagScore(knownStatus));
315 if (tagScore.isPresent() && Score.getScoreComparator().compare(tagScore.get(), newScore) > 0) {
316 newScore = tagScore.get();
320 if (newScore.compareTo(currentScore) != 0) {
321 setAggregateScore(objId, dataSourceObjectId, newScore, oCurrentAggregateScore.isPresent(), transaction);
324 transaction.registerScoreChange(
new ScoreChange(objId, dataSourceObjectId, currentScore, newScore));
341 try (CaseDbConnection connection = db.getConnection()) {
362 String queryString =
"SELECT COUNT(obj_id) AS count FROM tsk_aggregate_score"
363 +
" WHERE data_source_obj_id = " + dataSourceObjectId
364 +
" AND significance = " + significance.getId();
366 try (Statement statement = connection.createStatement();
367 ResultSet resultSet = connection.executeQuery(statement, queryString);) {
370 if (resultSet.next()) {
371 count = resultSet.getLong(
"count");
374 }
catch (SQLException ex) {
375 throw new TskCoreException(
"Error getting count of items with significance = " + significance.toString(), ex);
391 try (CaseDbConnection connection = db.getConnection()) {
392 return getContent(dataSourceObjectId, significance, connection);
411 String queryString =
"SELECT obj_id FROM tsk_aggregate_score"
412 +
" WHERE data_source_obj_id = " + dataSourceObjectId
413 +
" AND significance = " + significance.getId();
415 try (Statement statement = connection.createStatement();
416 ResultSet resultSet = connection.executeQuery(statement, queryString);) {
418 List<Content> items =
new ArrayList<>();
419 while (resultSet.next()) {
420 long objId = resultSet.getLong(
"obj_id");
424 }
catch (SQLException ex) {
425 throw new TskCoreException(
"Error getting list of items with significance = " + significance.toString(), ex);
static Priority fromID(int id)
static Significance fromID(int id)
List< Content > getContent(long dataSourceObjectId, Score.Significance significance)
static final Score SCORE_UNKNOWN
Blackboard getBlackboard()
Content getContentById(long id)
Map< Long, Score > getAggregateScores(List< Long > objIds)
synchronized TaggingManager getTaggingManager()
long getContentCount(long dataSourceObjectId, Score.Significance significance)
List< AnalysisResult > getAnalysisResults(long dataSourceObjId, Integer artifactTypeID)
void releaseSingleUserCaseReadLock()
void acquireSingleUserCaseReadLock()
Score getAggregateScore(long objId)