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.List;
28 import java.util.Optional;
30 import java.util.logging.Logger;
31 import java.util.stream.Collectors;
44 private static final Logger LOGGER = Logger.getLogger(
ScoringManager.class.getName());
69 try (CaseDbConnection connection = db.getConnection()) {
88 if (objIds.isEmpty()) {
89 return Collections.emptyMap();
92 String queryString =
"SELECT obj_id, significance, priority FROM tsk_aggregate_score WHERE obj_id in "
93 + objIds.stream().map(l -> l.toString()).collect(Collectors.joining(
",",
"(",
")"));
95 Map<Long, Score> results = objIds.stream().collect(Collectors.toMap( key -> key, key ->
Score.
SCORE_UNKNOWN));
97 try (CaseDbConnection connection = db.getConnection()) {
98 try (Statement s = connection.createStatement(); ResultSet rs = connection.executeQuery(s, queryString)) {
100 Long objId = rs.getLong(
"obj_id");
102 results.put(objId, score);
104 }
catch (SQLException ex) {
105 throw new TskCoreException(
"SQLException thrown while running query: " + queryString, ex);
126 CaseDbConnection connection = transaction.getConnection();
140 private Score
getAggregateScore(
long objId, CaseDbConnection connection)
throws TskCoreException {
141 String queryString =
"SELECT significance, priority FROM tsk_aggregate_score WHERE obj_id = " + objId;
142 try (Statement s = connection.createStatement(); ResultSet rs = connection.executeQuery(s, queryString)) {
144 return new Score(Significance.fromID(rs.getInt(
"significance")), Priority.fromID(rs.getInt(
"priority")));
146 return Score.SCORE_UNKNOWN;
148 }
catch (SQLException ex) {
149 throw new TskCoreException(
"SQLException thrown while running query: " + queryString, ex);
164 private void setAggregateScore(
long objId, Long dataSourceObjectId, Score score, CaseDbTransaction transaction)
throws TskCoreException {
166 String insertSQLString =
"INSERT INTO tsk_aggregate_score (obj_id, data_source_obj_id, significance , priority) VALUES (?, ?, ?, ?)"
167 +
" ON CONFLICT (obj_id) DO UPDATE SET significance = ?, priority = ?";
169 CaseDbConnection connection = transaction.getConnection();
171 PreparedStatement preparedStatement = connection.getPreparedStatement(insertSQLString, Statement.NO_GENERATED_KEYS);
172 preparedStatement.clearParameters();
174 preparedStatement.setLong(1, objId);
175 if (dataSourceObjectId != null) {
176 preparedStatement.setLong(2, dataSourceObjectId);
178 preparedStatement.setNull(2, java.sql.Types.NULL);
180 preparedStatement.setInt(3, score.getSignificance().getId());
181 preparedStatement.setInt(4, score.getPriority().getId());
183 preparedStatement.setInt(5, score.getSignificance().getId());
184 preparedStatement.setInt(6, score.getPriority().getId());
186 connection.executeUpdate(preparedStatement);
187 }
catch (SQLException ex) {
188 throw new TskCoreException(String.format(
"Error updating aggregate score, query: %s for objId = %d", insertSQLString, objId), ex);
209 Score updateAggregateScoreAfterAddition(
long objId, Long dataSourceObjectId, Score newResultScore, CaseDbTransaction transaction)
throws TskCoreException {
221 CaseDbConnection connection = transaction.getConnection();
222 connection.getAggregateScoreTableWriteLock();
223 }
catch (SQLException ex) {
224 throw new TskCoreException(
"Error getting exclusive write lock on aggregate score table", ex);
229 Score currentAggregateScore = ScoringManager.this.getAggregateScore(objId, transaction);
233 if ( (currentAggregateScore.compareTo(Score.SCORE_UNKNOWN) == 0 && newResultScore.compareTo(Score.SCORE_UNKNOWN) != 0)
234 || (Score.getScoreComparator().compare(newResultScore, currentAggregateScore) > 0)) {
235 setAggregateScore(objId, dataSourceObjectId, newResultScore, transaction);
238 transaction.registerScoreChange(
new ScoreChange(objId, dataSourceObjectId, currentAggregateScore, newResultScore));
239 return newResultScore;
242 return currentAggregateScore;
256 Score updateAggregateScoreAfterDeletion(
long objId, Long dataSourceObjectId, CaseDbTransaction transaction)
throws TskCoreException {
258 CaseDbConnection connection = transaction.getConnection();
270 connection.getAggregateScoreTableWriteLock();
271 }
catch (SQLException ex) {
272 throw new TskCoreException(
"Error getting exclusive write lock on aggregate score table", ex);
276 Score currentScore = ScoringManager.this.getAggregateScore(objId, transaction);
280 Score newScore = Score.SCORE_UNKNOWN;
281 for (AnalysisResult iter : analysisResults) {
282 Score iterScore = iter.getScore();
283 if (Score.getScoreComparator().compare(iterScore, newScore) > 0) {
284 newScore = iterScore;
290 Optional<Score> tagScore = db.
getTaggingManager().getMaxTagKnownStatus(objId, transaction)
291 .map(knownStatus -> TaggingManager.getTagScore(knownStatus));
293 if (tagScore.isPresent() && Score.getScoreComparator().compare(tagScore.get(), newScore) > 0) {
294 newScore = tagScore.get();
298 if (newScore.compareTo(currentScore) != 0) {
299 setAggregateScore(objId, dataSourceObjectId, newScore, transaction);
302 transaction.registerScoreChange(
new ScoreChange(objId, dataSourceObjectId, currentScore, newScore));
319 try (CaseDbConnection connection = db.getConnection()) {
340 String queryString =
"SELECT COUNT(obj_id) AS count FROM tsk_aggregate_score"
341 +
" WHERE data_source_obj_id = " + dataSourceObjectId
342 +
" AND significance = " + significance.getId();
344 try (Statement statement = connection.createStatement();
345 ResultSet resultSet = connection.executeQuery(statement, queryString);) {
348 if (resultSet.next()) {
349 count = resultSet.getLong(
"count");
352 }
catch (SQLException ex) {
353 throw new TskCoreException(
"Error getting count of items with significance = " + significance.toString(), ex);
369 try (CaseDbConnection connection = db.getConnection()) {
370 return getContent(dataSourceObjectId, significance, connection);
389 String queryString =
"SELECT obj_id FROM tsk_aggregate_score"
390 +
" WHERE data_source_obj_id = " + dataSourceObjectId
391 +
" AND significance = " + significance.getId();
393 try (Statement statement = connection.createStatement();
394 ResultSet resultSet = connection.executeQuery(statement, queryString);) {
396 List<Content> items =
new ArrayList<>();
397 while (resultSet.next()) {
398 long objId = resultSet.getLong(
"obj_id");
402 }
catch (SQLException ex) {
403 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)
List< AnalysisResult > getAnalysisResults(long sourceObjId)
synchronized TaggingManager getTaggingManager()
long getContentCount(long dataSourceObjectId, Score.Significance significance)
void releaseSingleUserCaseReadLock()
void acquireSingleUserCaseReadLock()
Score getAggregateScore(long objId)