mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-19 11:07:43 +00:00
Merge pull request #5379 from rcordovano/rc-data-src-deletion-integration
5511 Delete data sources from Image Gallery database tables
This commit is contained in:
commit
2b55a6837b
@ -37,7 +37,7 @@ public class DataSourceDeletedEvent extends AutopsyEvent implements Serializable
|
|||||||
* @param dataSourceId The object ID of the data source that was deleted.
|
* @param dataSourceId The object ID of the data source that was deleted.
|
||||||
*/
|
*/
|
||||||
public DataSourceDeletedEvent(Long dataSourceId) {
|
public DataSourceDeletedEvent(Long dataSourceId) {
|
||||||
super(Case.Events.DATA_SOURCE_DELETED.toString(), null, dataSourceId);
|
super(Case.Events.DATA_SOURCE_DELETED.toString(), dataSourceId, null);
|
||||||
this.dataSourceID = dataSourceId;
|
this.dataSourceID = dataSourceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import com.google.common.util.concurrent.MoreExecutors;
|
|||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -55,6 +56,7 @@ import org.sleuthkit.autopsy.casemodule.Case.CaseType;
|
|||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.events.DataSourceDeletedEvent;
|
||||||
import org.sleuthkit.autopsy.coreutils.History;
|
import org.sleuthkit.autopsy.coreutils.History;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
@ -102,7 +104,8 @@ public final class ImageGalleryController {
|
|||||||
Case.Events.CURRENT_CASE,
|
Case.Events.CURRENT_CASE,
|
||||||
Case.Events.DATA_SOURCE_ADDED,
|
Case.Events.DATA_SOURCE_ADDED,
|
||||||
Case.Events.CONTENT_TAG_ADDED,
|
Case.Events.CONTENT_TAG_ADDED,
|
||||||
Case.Events.CONTENT_TAG_DELETED
|
Case.Events.CONTENT_TAG_DELETED,
|
||||||
|
Case.Events.DATA_SOURCE_DELETED
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -802,6 +805,17 @@ public final class ImageGalleryController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case DATA_SOURCE_DELETED:
|
||||||
|
if (((AutopsyEvent) event).getSourceType() == AutopsyEvent.SourceType.LOCAL) {
|
||||||
|
final DataSourceDeletedEvent dataSourceDeletedEvent = (DataSourceDeletedEvent) event;
|
||||||
|
long dataSourceObjId = dataSourceDeletedEvent.getDataSourceId();
|
||||||
|
try {
|
||||||
|
drawableDB.deleteDataSource(dataSourceObjId);
|
||||||
|
} catch (SQLException | TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, String.format("Failed to delete data source (obj_id = %d)", dataSourceObjId), ex); //NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case CONTENT_TAG_ADDED:
|
case CONTENT_TAG_ADDED:
|
||||||
final ContentTagAddedEvent tagAddedEvent = (ContentTagAddedEvent) event;
|
final ContentTagAddedEvent tagAddedEvent = (ContentTagAddedEvent) event;
|
||||||
long objId = tagAddedEvent.getAddedTag().getContent().getId();
|
long objId = tagAddedEvent.getAddedTag().getContent().getId();
|
||||||
|
@ -100,15 +100,15 @@ public final class DrawableDB {
|
|||||||
private static final String GROUPS_SEEN_TABLENAME = "image_gallery_groups_seen"; //NON-NLS
|
private static final String GROUPS_SEEN_TABLENAME = "image_gallery_groups_seen"; //NON-NLS
|
||||||
|
|
||||||
private static final String IG_DB_INFO_TABLE = "image_gallery_db_info";
|
private static final String IG_DB_INFO_TABLE = "image_gallery_db_info";
|
||||||
|
|
||||||
private static final String IG_SCHEMA_MAJOR_VERSION_KEY = "IG_SCHEMA_MAJOR_VERSION";
|
private static final String IG_SCHEMA_MAJOR_VERSION_KEY = "IG_SCHEMA_MAJOR_VERSION";
|
||||||
private static final String IG_SCHEMA_MINOR_VERSION_KEY = "IG_SCHEMA_MINOR_VERSION";
|
private static final String IG_SCHEMA_MINOR_VERSION_KEY = "IG_SCHEMA_MINOR_VERSION";
|
||||||
private static final String IG_CREATION_SCHEMA_MAJOR_VERSION_KEY = "IG_CREATION_SCHEMA_MAJOR_VERSION";
|
private static final String IG_CREATION_SCHEMA_MAJOR_VERSION_KEY = "IG_CREATION_SCHEMA_MAJOR_VERSION";
|
||||||
private static final String IG_CREATION_SCHEMA_MINOR_VERSION_KEY = "IG_CREATION_SCHEMA_MINOR_VERSION";
|
private static final String IG_CREATION_SCHEMA_MINOR_VERSION_KEY = "IG_CREATION_SCHEMA_MINOR_VERSION";
|
||||||
|
|
||||||
private static final VersionNumber IG_STARTING_SCHEMA_VERSION = new VersionNumber(1, 0, 0); // IG Schema Starting version
|
private static final VersionNumber IG_STARTING_SCHEMA_VERSION = new VersionNumber(1, 0, 0); // IG Schema Starting version - DO NOT CHANGE
|
||||||
private static final VersionNumber IG_SCHEMA_VERSION = new VersionNumber(1, 1, 0); // IG Schema Current version
|
private static final VersionNumber IG_SCHEMA_VERSION = new VersionNumber(1, 2, 0); // IG Schema Current version
|
||||||
|
|
||||||
private PreparedStatement insertHashSetStmt;
|
private PreparedStatement insertHashSetStmt;
|
||||||
|
|
||||||
private List<PreparedStatement> preparedStatements = new ArrayList<>();
|
private List<PreparedStatement> preparedStatements = new ArrayList<>();
|
||||||
@ -146,6 +146,8 @@ public final class DrawableDB {
|
|||||||
|
|
||||||
private PreparedStatement pathGroupFilterByDataSrcStmt;
|
private PreparedStatement pathGroupFilterByDataSrcStmt;
|
||||||
|
|
||||||
|
private PreparedStatement deleteDataSourceStmt;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* map from {@link DrawableAttribute} to the {@link PreparedStatement} that
|
* map from {@link DrawableAttribute} to the {@link PreparedStatement} that
|
||||||
* is used to select groups for that attribute
|
* is used to select groups for that attribute
|
||||||
@ -263,6 +265,7 @@ public final class DrawableDB {
|
|||||||
selectHashSetStmt = prepareStatement("SELECT hash_set_id FROM hash_sets WHERE hash_set_name = ?"); //NON-NLS
|
selectHashSetStmt = prepareStatement("SELECT hash_set_id FROM hash_sets WHERE hash_set_name = ?"); //NON-NLS
|
||||||
insertHashHitStmt = prepareStatement("INSERT OR IGNORE INTO hash_set_hits (hash_set_id, obj_id) VALUES (?,?)"); //NON-NLS
|
insertHashHitStmt = prepareStatement("INSERT OR IGNORE INTO hash_set_hits (hash_set_id, obj_id) VALUES (?,?)"); //NON-NLS
|
||||||
removeHashHitStmt = prepareStatement("DELETE FROM hash_set_hits WHERE obj_id = ?"); //NON-NLS
|
removeHashHitStmt = prepareStatement("DELETE FROM hash_set_hits WHERE obj_id = ?"); //NON-NLS
|
||||||
|
deleteDataSourceStmt = prepareStatement("DELETE FROM datasources where ds_obj_id = ?"); //NON-NLS
|
||||||
return true;
|
return true;
|
||||||
} catch (TskCoreException | SQLException ex) {
|
} catch (TskCoreException | SQLException ex) {
|
||||||
logger.log(Level.SEVERE, "Failed to prepare all statements", ex); //NON-NLS
|
logger.log(Level.SEVERE, "Failed to prepare all statements", ex); //NON-NLS
|
||||||
@ -404,11 +407,12 @@ public final class DrawableDB {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the specified table exists in Drawable DB
|
* Checks if the specified table exists in Drawable DB
|
||||||
*
|
*
|
||||||
* @param tableName table to check
|
* @param tableName table to check
|
||||||
|
*
|
||||||
* @return true if the table exists in the database
|
* @return true if the table exists in the database
|
||||||
*
|
*
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
*/
|
*/
|
||||||
private boolean doesTableExist(String tableName) throws SQLException {
|
private boolean doesTableExist(String tableName) throws SQLException {
|
||||||
ResultSet tableQueryResults = null;
|
ResultSet tableQueryResults = null;
|
||||||
@ -421,15 +425,14 @@ public final class DrawableDB {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
if (tableQueryResults != null) {
|
if (tableQueryResults != null) {
|
||||||
tableQueryResults.close();
|
tableQueryResults.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tableExists;
|
return tableExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void deleteDatabaseIfOlderVersion(Path dbPath) throws SQLException, IOException {
|
private static void deleteDatabaseIfOlderVersion(Path dbPath) throws SQLException, IOException {
|
||||||
if (Files.exists(dbPath)) {
|
if (Files.exists(dbPath)) {
|
||||||
boolean hasDrawableFilesTable = false;
|
boolean hasDrawableFilesTable = false;
|
||||||
@ -475,7 +478,7 @@ public final class DrawableDB {
|
|||||||
//allow to query while in transaction - no need read locks
|
//allow to query while in transaction - no need read locks
|
||||||
statement.execute("PRAGMA read_uncommitted = True;"); //NON-NLS
|
statement.execute("PRAGMA read_uncommitted = True;"); //NON-NLS
|
||||||
|
|
||||||
//TODO: do we need this?
|
//used for data source deletion
|
||||||
statement.execute("PRAGMA foreign_keys = ON"); //NON-NLS
|
statement.execute("PRAGMA foreign_keys = ON"); //NON-NLS
|
||||||
|
|
||||||
//TODO: test this
|
//TODO: test this
|
||||||
@ -515,7 +518,7 @@ public final class DrawableDB {
|
|||||||
dbWriteLock();
|
dbWriteLock();
|
||||||
try {
|
try {
|
||||||
boolean drawableDbTablesExist = true;
|
boolean drawableDbTablesExist = true;
|
||||||
|
|
||||||
if (isClosed()) {
|
if (isClosed()) {
|
||||||
logger.log(Level.SEVERE, "The drawables database is closed"); //NON-NLS
|
logger.log(Level.SEVERE, "The drawables database is closed"); //NON-NLS
|
||||||
return false;
|
return false;
|
||||||
@ -532,31 +535,31 @@ public final class DrawableDB {
|
|||||||
* Create tables in the drawables database.
|
* Create tables in the drawables database.
|
||||||
*/
|
*/
|
||||||
try (Statement stmt = con.createStatement()) {
|
try (Statement stmt = con.createStatement()) {
|
||||||
|
|
||||||
// Check if the database is new or an existing database
|
// Check if the database is new or an existing database
|
||||||
drawableDbTablesExist = doesTableExist("drawable_files");
|
drawableDbTablesExist = doesTableExist("drawable_files");
|
||||||
if (false == doesTableExist(IG_DB_INFO_TABLE)) {
|
if (false == doesTableExist(IG_DB_INFO_TABLE)) {
|
||||||
try {
|
try {
|
||||||
VersionNumber ig_creation_schema_version = drawableDbTablesExist
|
VersionNumber ig_creation_schema_version = drawableDbTablesExist
|
||||||
? IG_STARTING_SCHEMA_VERSION
|
? IG_STARTING_SCHEMA_VERSION
|
||||||
: IG_SCHEMA_VERSION;
|
: IG_SCHEMA_VERSION;
|
||||||
|
|
||||||
stmt.execute("CREATE TABLE IF NOT EXISTS " + IG_DB_INFO_TABLE + " (name TEXT PRIMARY KEY, value TEXT NOT NULL)");
|
stmt.execute("CREATE TABLE IF NOT EXISTS " + IG_DB_INFO_TABLE + " (name TEXT PRIMARY KEY, value TEXT NOT NULL)");
|
||||||
|
|
||||||
// backfill creation schema ver
|
// backfill creation schema ver
|
||||||
stmt.execute(String.format("INSERT INTO %s (name, value) VALUES ('%s', '%s')", IG_DB_INFO_TABLE, IG_CREATION_SCHEMA_MAJOR_VERSION_KEY, ig_creation_schema_version.getMajor() ));
|
stmt.execute(String.format("INSERT INTO %s (name, value) VALUES ('%s', '%s')", IG_DB_INFO_TABLE, IG_CREATION_SCHEMA_MAJOR_VERSION_KEY, ig_creation_schema_version.getMajor()));
|
||||||
stmt.execute(String.format("INSERT INTO %s (name, value) VALUES ('%s', '%s')", IG_DB_INFO_TABLE, IG_CREATION_SCHEMA_MINOR_VERSION_KEY, ig_creation_schema_version.getMinor() ));
|
stmt.execute(String.format("INSERT INTO %s (name, value) VALUES ('%s', '%s')", IG_DB_INFO_TABLE, IG_CREATION_SCHEMA_MINOR_VERSION_KEY, ig_creation_schema_version.getMinor()));
|
||||||
|
|
||||||
// set current schema ver: at DB initialization - current version is same as starting version
|
// set current schema ver: at DB initialization - current version is same as starting version
|
||||||
stmt.execute(String.format("INSERT INTO %s (name, value) VALUES ('%s', '%s')", IG_DB_INFO_TABLE, IG_SCHEMA_MAJOR_VERSION_KEY, ig_creation_schema_version.getMajor() ));
|
stmt.execute(String.format("INSERT INTO %s (name, value) VALUES ('%s', '%s')", IG_DB_INFO_TABLE, IG_SCHEMA_MAJOR_VERSION_KEY, ig_creation_schema_version.getMajor()));
|
||||||
stmt.execute(String.format("INSERT INTO %s (name, value) VALUES ('%s', '%s')", IG_DB_INFO_TABLE, IG_SCHEMA_MINOR_VERSION_KEY, ig_creation_schema_version.getMinor() ));
|
stmt.execute(String.format("INSERT INTO %s (name, value) VALUES ('%s', '%s')", IG_DB_INFO_TABLE, IG_SCHEMA_MINOR_VERSION_KEY, ig_creation_schema_version.getMinor()));
|
||||||
|
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
logger.log(Level.SEVERE, "Failed to create ig_db_info table", ex); //NON-NLS
|
logger.log(Level.SEVERE, "Failed to create ig_db_info table", ex); //NON-NLS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String sql = "CREATE TABLE IF NOT EXISTS datasources " //NON-NLS
|
String sql = "CREATE TABLE IF NOT EXISTS datasources " //NON-NLS
|
||||||
+ "( id INTEGER PRIMARY KEY, " //NON-NLS
|
+ "( id INTEGER PRIMARY KEY, " //NON-NLS
|
||||||
@ -578,7 +581,8 @@ public final class DrawableDB {
|
|||||||
+ " modified_time integer, " //NON-NLS
|
+ " modified_time integer, " //NON-NLS
|
||||||
+ " make TEXT DEFAULT NULL, " //NON-NLS
|
+ " make TEXT DEFAULT NULL, " //NON-NLS
|
||||||
+ " model TEXT DEFAULT NULL, " //NON-NLS
|
+ " model TEXT DEFAULT NULL, " //NON-NLS
|
||||||
+ " analyzed integer DEFAULT 0)"; //NON-NLS
|
+ " analyzed integer DEFAULT 0, " //NON-NLS
|
||||||
|
+ " FOREIGN KEY (data_source_obj_id) REFERENCES datasources(ds_obj_id) ON DELETE CASCADE)"; //NON-NLS
|
||||||
stmt.execute(sql);
|
stmt.execute(sql);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
logger.log(Level.SEVERE, "Failed to create drawable_files table", ex); //NON-NLS
|
logger.log(Level.SEVERE, "Failed to create drawable_files table", ex); //NON-NLS
|
||||||
@ -598,8 +602,9 @@ public final class DrawableDB {
|
|||||||
try {
|
try {
|
||||||
String sql = "CREATE TABLE if not exists hash_set_hits " //NON-NLS
|
String sql = "CREATE TABLE if not exists hash_set_hits " //NON-NLS
|
||||||
+ "(hash_set_id INTEGER REFERENCES hash_sets(hash_set_id) not null, " //NON-NLS
|
+ "(hash_set_id INTEGER REFERENCES hash_sets(hash_set_id) not null, " //NON-NLS
|
||||||
+ " obj_id BIGINT REFERENCES drawable_files(obj_id) not null, " //NON-NLS
|
+ " obj_id BIGINT NOT NULL, " //NON-NLS
|
||||||
+ " PRIMARY KEY (hash_set_id, obj_id))"; //NON-NLS
|
+ " PRIMARY KEY (hash_set_id, obj_id), " //NON-NLS
|
||||||
|
+ " FOREIGN KEY (obj_id) REFERENCES drawable_files(obj_id) ON DELETE CASCADE)"; //NON-NLS
|
||||||
stmt.execute(sql);
|
stmt.execute(sql);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
logger.log(Level.SEVERE, "Failed to create hash_set_hits table", ex); //NON-NLS
|
logger.log(Level.SEVERE, "Failed to create hash_set_hits table", ex); //NON-NLS
|
||||||
@ -649,45 +654,45 @@ public final class DrawableDB {
|
|||||||
* Create tables in the case database.
|
* Create tables in the case database.
|
||||||
*/
|
*/
|
||||||
String autogenKeyType = (DbType.POSTGRESQL == tskCase.getDatabaseType()) ? "BIGSERIAL" : "INTEGER";
|
String autogenKeyType = (DbType.POSTGRESQL == tskCase.getDatabaseType()) ? "BIGSERIAL" : "INTEGER";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
boolean caseDbTablesExist = tskCase.getCaseDbAccessManager().tableExists(GROUPS_TABLENAME);
|
boolean caseDbTablesExist = tskCase.getCaseDbAccessManager().tableExists(GROUPS_TABLENAME);
|
||||||
VersionNumber ig_creation_schema_version = caseDbTablesExist
|
VersionNumber ig_creation_schema_version = caseDbTablesExist
|
||||||
? IG_STARTING_SCHEMA_VERSION
|
? IG_STARTING_SCHEMA_VERSION
|
||||||
: IG_SCHEMA_VERSION;
|
: IG_SCHEMA_VERSION;
|
||||||
|
|
||||||
String tableSchema = "( id " + autogenKeyType + " PRIMARY KEY, "
|
String tableSchema = "( id " + autogenKeyType + " PRIMARY KEY, "
|
||||||
+ " name TEXT UNIQUE NOT NULL,"
|
+ " name TEXT UNIQUE NOT NULL,"
|
||||||
+ " value TEXT NOT NULL )";
|
+ " value TEXT NOT NULL )";
|
||||||
tskCase.getCaseDbAccessManager().createTable(IG_DB_INFO_TABLE, tableSchema);
|
tskCase.getCaseDbAccessManager().createTable(IG_DB_INFO_TABLE, tableSchema);
|
||||||
|
|
||||||
// backfill creation version
|
// backfill creation version
|
||||||
String creationMajorVerSQL = String.format(" (name, value) VALUES ('%s', '%s')", IG_CREATION_SCHEMA_MAJOR_VERSION_KEY, ig_creation_schema_version.getMajor());
|
String creationMajorVerSQL = String.format(" (name, value) VALUES ('%s', '%s')", IG_CREATION_SCHEMA_MAJOR_VERSION_KEY, ig_creation_schema_version.getMajor());
|
||||||
String creationMinorVerSQL = String.format(" (name, value) VALUES ('%s', '%s')", IG_CREATION_SCHEMA_MINOR_VERSION_KEY, ig_creation_schema_version.getMinor());
|
String creationMinorVerSQL = String.format(" (name, value) VALUES ('%s', '%s')", IG_CREATION_SCHEMA_MINOR_VERSION_KEY, ig_creation_schema_version.getMinor());
|
||||||
|
|
||||||
// set current version - at the onset, current version is same as creation version
|
// set current version - at the onset, current version is same as creation version
|
||||||
String currentMajorVerSQL = String.format(" (name, value) VALUES ('%s', '%s')", IG_SCHEMA_MAJOR_VERSION_KEY, ig_creation_schema_version.getMajor());
|
String currentMajorVerSQL = String.format(" (name, value) VALUES ('%s', '%s')", IG_SCHEMA_MAJOR_VERSION_KEY, ig_creation_schema_version.getMajor());
|
||||||
String currentMinorVerSQL = String.format(" (name, value) VALUES ('%s', '%s')", IG_SCHEMA_MINOR_VERSION_KEY, ig_creation_schema_version.getMinor());
|
String currentMinorVerSQL = String.format(" (name, value) VALUES ('%s', '%s')", IG_SCHEMA_MINOR_VERSION_KEY, ig_creation_schema_version.getMinor());
|
||||||
|
|
||||||
if (DbType.POSTGRESQL == tskCase.getDatabaseType()) {
|
if (DbType.POSTGRESQL == tskCase.getDatabaseType()) {
|
||||||
creationMajorVerSQL += " ON CONFLICT DO NOTHING ";
|
creationMajorVerSQL += " ON CONFLICT DO NOTHING ";
|
||||||
creationMinorVerSQL += " ON CONFLICT DO NOTHING ";
|
creationMinorVerSQL += " ON CONFLICT DO NOTHING ";
|
||||||
|
|
||||||
currentMajorVerSQL += " ON CONFLICT DO NOTHING ";
|
currentMajorVerSQL += " ON CONFLICT DO NOTHING ";
|
||||||
currentMinorVerSQL += " ON CONFLICT DO NOTHING ";
|
currentMinorVerSQL += " ON CONFLICT DO NOTHING ";
|
||||||
}
|
}
|
||||||
|
|
||||||
tskCase.getCaseDbAccessManager().insert(IG_DB_INFO_TABLE, creationMajorVerSQL);
|
tskCase.getCaseDbAccessManager().insert(IG_DB_INFO_TABLE, creationMajorVerSQL);
|
||||||
tskCase.getCaseDbAccessManager().insert(IG_DB_INFO_TABLE, creationMinorVerSQL);
|
tskCase.getCaseDbAccessManager().insert(IG_DB_INFO_TABLE, creationMinorVerSQL);
|
||||||
|
|
||||||
tskCase.getCaseDbAccessManager().insert(IG_DB_INFO_TABLE, currentMajorVerSQL);
|
tskCase.getCaseDbAccessManager().insert(IG_DB_INFO_TABLE, currentMajorVerSQL);
|
||||||
tskCase.getCaseDbAccessManager().insert(IG_DB_INFO_TABLE, currentMinorVerSQL);
|
tskCase.getCaseDbAccessManager().insert(IG_DB_INFO_TABLE, currentMinorVerSQL);
|
||||||
|
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.SEVERE, "Failed to create ig_db_info table in Case database", ex); //NON-NLS
|
logger.log(Level.SEVERE, "Failed to create ig_db_info table in Case database", ex); //NON-NLS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String tableSchema
|
String tableSchema
|
||||||
= "( group_id " + autogenKeyType + " PRIMARY KEY, " //NON-NLS
|
= "( group_id " + autogenKeyType + " PRIMARY KEY, " //NON-NLS
|
||||||
@ -710,7 +715,7 @@ public final class DrawableDB {
|
|||||||
+ " examiner_id integer not null, " //NON-NLS
|
+ " examiner_id integer not null, " //NON-NLS
|
||||||
+ " seen integer DEFAULT 0, " //NON-NLS
|
+ " seen integer DEFAULT 0, " //NON-NLS
|
||||||
+ " UNIQUE(group_id, examiner_id),"
|
+ " UNIQUE(group_id, examiner_id),"
|
||||||
+ " FOREIGN KEY(group_id) REFERENCES " + GROUPS_TABLENAME + "(group_id),"
|
+ " FOREIGN KEY(group_id) REFERENCES " + GROUPS_TABLENAME + "(group_id) ON DELETE CASCADE,"
|
||||||
+ " FOREIGN KEY(examiner_id) REFERENCES tsk_examiners(examiner_id)"
|
+ " FOREIGN KEY(examiner_id) REFERENCES tsk_examiners(examiner_id)"
|
||||||
+ " )"; //NON-NLS
|
+ " )"; //NON-NLS
|
||||||
|
|
||||||
@ -729,20 +734,21 @@ public final class DrawableDB {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the Schema version from DrawableDB
|
* Gets the Schema version from DrawableDB
|
||||||
*
|
*
|
||||||
* @return image gallery schema version in DrawableDB
|
* @return image gallery schema version in DrawableDB
|
||||||
|
*
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
*/
|
*/
|
||||||
private VersionNumber getDrawableDbIgSchemaVersion() throws SQLException, TskCoreException {
|
private VersionNumber getDrawableDbIgSchemaVersion() throws SQLException, TskCoreException {
|
||||||
|
|
||||||
Statement statement = con.createStatement();
|
Statement statement = con.createStatement();
|
||||||
ResultSet resultSet = null;
|
ResultSet resultSet = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int majorVersion = -1;
|
int majorVersion = -1;
|
||||||
String majorVersionStr = null;
|
String majorVersionStr = null;
|
||||||
resultSet = statement.executeQuery(String.format("SELECT value FROM %s WHERE name='%s'", IG_DB_INFO_TABLE, IG_SCHEMA_MAJOR_VERSION_KEY));
|
resultSet = statement.executeQuery(String.format("SELECT value FROM %s WHERE name='%s'", IG_DB_INFO_TABLE, IG_SCHEMA_MAJOR_VERSION_KEY));
|
||||||
if (resultSet.next()) {
|
if (resultSet.next()) {
|
||||||
majorVersionStr = resultSet.getString("value");
|
majorVersionStr = resultSet.getString("value");
|
||||||
try {
|
try {
|
||||||
@ -751,12 +757,12 @@ public final class DrawableDB {
|
|||||||
throw new TskCoreException("Bad value for schema major version = " + majorVersionStr, ex);
|
throw new TskCoreException("Bad value for schema major version = " + majorVersionStr, ex);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new TskCoreException("Failed to read schema major version from ig_db_info table");
|
throw new TskCoreException("Failed to read schema major version from ig_db_info table");
|
||||||
}
|
}
|
||||||
|
|
||||||
int minorVersion = -1;
|
int minorVersion = -1;
|
||||||
String minorVersionStr = null;
|
String minorVersionStr = null;
|
||||||
resultSet = statement.executeQuery(String.format("SELECT value FROM %s WHERE name='%s'", IG_DB_INFO_TABLE, IG_SCHEMA_MINOR_VERSION_KEY));
|
resultSet = statement.executeQuery(String.format("SELECT value FROM %s WHERE name='%s'", IG_DB_INFO_TABLE, IG_SCHEMA_MINOR_VERSION_KEY));
|
||||||
if (resultSet.next()) {
|
if (resultSet.next()) {
|
||||||
minorVersionStr = resultSet.getString("value");
|
minorVersionStr = resultSet.getString("value");
|
||||||
try {
|
try {
|
||||||
@ -768,9 +774,8 @@ public final class DrawableDB {
|
|||||||
throw new TskCoreException("Failed to read schema minor version from ig_db_info table");
|
throw new TskCoreException("Failed to read schema minor version from ig_db_info table");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new VersionNumber(majorVersion, minorVersion, 0 );
|
return new VersionNumber(majorVersion, minorVersion, 0);
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
if (resultSet != null) {
|
if (resultSet != null) {
|
||||||
resultSet.close();
|
resultSet.close();
|
||||||
}
|
}
|
||||||
@ -782,27 +787,28 @@ public final class DrawableDB {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the ImageGallery schema version from CaseDB
|
* Gets the ImageGallery schema version from CaseDB
|
||||||
*
|
*
|
||||||
* @return image gallery schema version in CaseDB
|
* @return image gallery schema version in CaseDB
|
||||||
|
*
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
*/
|
*/
|
||||||
private VersionNumber getCaseDbIgSchemaVersion() throws TskCoreException {
|
private VersionNumber getCaseDbIgSchemaVersion() throws TskCoreException {
|
||||||
|
|
||||||
// Callback to process result of get version query
|
// Callback to process result of get version query
|
||||||
class GetSchemaVersionQueryResultProcessor implements CaseDbAccessQueryCallback {
|
class GetSchemaVersionQueryResultProcessor implements CaseDbAccessQueryCallback {
|
||||||
|
|
||||||
private int version = -1;
|
private int version = -1;
|
||||||
|
|
||||||
int getVersion() {
|
int getVersion() {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(ResultSet resultSet) {
|
public void process(ResultSet resultSet) {
|
||||||
try {
|
try {
|
||||||
if (resultSet.next()) {
|
if (resultSet.next()) {
|
||||||
String versionStr = resultSet.getString("value");
|
String versionStr = resultSet.getString("value");
|
||||||
try {
|
try {
|
||||||
version = Integer.parseInt(versionStr);
|
version = Integer.parseInt(versionStr);
|
||||||
} catch (NumberFormatException ex) {
|
} catch (NumberFormatException ex) {
|
||||||
@ -811,100 +817,96 @@ public final class DrawableDB {
|
|||||||
} else {
|
} else {
|
||||||
logger.log(Level.SEVERE, "Failed to get version");
|
logger.log(Level.SEVERE, "Failed to get version");
|
||||||
}
|
}
|
||||||
}
|
} catch (SQLException ex) {
|
||||||
catch (SQLException ex) {
|
|
||||||
logger.log(Level.SEVERE, "Failed to get version", ex); //NON-NLS
|
logger.log(Level.SEVERE, "Failed to get version", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GetSchemaVersionQueryResultProcessor majorVersionResultProcessor = new GetSchemaVersionQueryResultProcessor();
|
GetSchemaVersionQueryResultProcessor majorVersionResultProcessor = new GetSchemaVersionQueryResultProcessor();
|
||||||
GetSchemaVersionQueryResultProcessor minorVersionResultProcessor = new GetSchemaVersionQueryResultProcessor();
|
GetSchemaVersionQueryResultProcessor minorVersionResultProcessor = new GetSchemaVersionQueryResultProcessor();
|
||||||
|
|
||||||
String versionQueryTemplate = "value FROM %s WHERE name = \'%s\' ";
|
String versionQueryTemplate = "value FROM %s WHERE name = \'%s\' ";
|
||||||
tskCase.getCaseDbAccessManager().select(String.format(versionQueryTemplate, IG_DB_INFO_TABLE, IG_SCHEMA_MAJOR_VERSION_KEY), majorVersionResultProcessor);
|
tskCase.getCaseDbAccessManager().select(String.format(versionQueryTemplate, IG_DB_INFO_TABLE, IG_SCHEMA_MAJOR_VERSION_KEY), majorVersionResultProcessor);
|
||||||
tskCase.getCaseDbAccessManager().select(String.format(versionQueryTemplate, IG_DB_INFO_TABLE, IG_SCHEMA_MINOR_VERSION_KEY), minorVersionResultProcessor);
|
tskCase.getCaseDbAccessManager().select(String.format(versionQueryTemplate, IG_DB_INFO_TABLE, IG_SCHEMA_MINOR_VERSION_KEY), minorVersionResultProcessor);
|
||||||
|
|
||||||
return new VersionNumber(majorVersionResultProcessor.getVersion(), minorVersionResultProcessor.getVersion(), 0);
|
return new VersionNumber(majorVersionResultProcessor.getVersion(), minorVersionResultProcessor.getVersion(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the IG schema version in the Drawable DB
|
* Updates the IG schema version in the Drawable DB
|
||||||
*
|
*
|
||||||
* @param version new version number
|
* @param version new version number
|
||||||
* @param transaction transaction under which the update happens
|
* @param transaction transaction under which the update happens
|
||||||
*
|
*
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
*/
|
*/
|
||||||
private void updateDrawableDbIgSchemaVersion(VersionNumber version, DrawableTransaction transaction) throws SQLException, TskCoreException {
|
private void updateDrawableDbIgSchemaVersion(VersionNumber version, DrawableTransaction transaction) throws SQLException, TskCoreException {
|
||||||
|
|
||||||
if (transaction == null) {
|
if (transaction == null) {
|
||||||
throw new TskCoreException("Schema version update must be done in a transaction");
|
throw new TskCoreException("Schema version update must be done in a transaction");
|
||||||
}
|
}
|
||||||
|
|
||||||
dbWriteLock();
|
dbWriteLock();
|
||||||
try {
|
try {
|
||||||
Statement statement = con.createStatement();
|
Statement statement = con.createStatement();
|
||||||
|
|
||||||
// update schema version
|
// update schema version
|
||||||
statement.execute(String.format("UPDATE %s SET value = '%s' WHERE name = '%s'", IG_DB_INFO_TABLE, version.getMajor(), IG_SCHEMA_MAJOR_VERSION_KEY ));
|
statement.execute(String.format("UPDATE %s SET value = '%s' WHERE name = '%s'", IG_DB_INFO_TABLE, version.getMajor(), IG_SCHEMA_MAJOR_VERSION_KEY));
|
||||||
statement.execute(String.format("UPDATE %s SET value = '%s' WHERE name = '%s'", IG_DB_INFO_TABLE, version.getMinor(), IG_SCHEMA_MINOR_VERSION_KEY ));
|
statement.execute(String.format("UPDATE %s SET value = '%s' WHERE name = '%s'", IG_DB_INFO_TABLE, version.getMinor(), IG_SCHEMA_MINOR_VERSION_KEY));
|
||||||
|
|
||||||
statement.close();
|
statement.close();
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
dbWriteUnlock();
|
dbWriteUnlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the IG schema version in CaseDB
|
* Updates the IG schema version in CaseDB
|
||||||
*
|
*
|
||||||
* @param version new version number
|
* @param version new version number
|
||||||
* @param caseDbTransaction transaction to use to update the CaseDB
|
* @param caseDbTransaction transaction to use to update the CaseDB
|
||||||
*
|
*
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
*/
|
*/
|
||||||
private void updateCaseDbIgSchemaVersion(VersionNumber version, CaseDbTransaction caseDbTransaction) throws TskCoreException {
|
private void updateCaseDbIgSchemaVersion(VersionNumber version, CaseDbTransaction caseDbTransaction) throws TskCoreException {
|
||||||
|
|
||||||
String updateSQLTemplate = " SET value = %s WHERE name = '%s' ";
|
String updateSQLTemplate = " SET value = %s WHERE name = '%s' ";
|
||||||
tskCase.getCaseDbAccessManager().update(IG_DB_INFO_TABLE, String.format(updateSQLTemplate, version.getMajor(), IG_SCHEMA_MAJOR_VERSION_KEY), caseDbTransaction);
|
tskCase.getCaseDbAccessManager().update(IG_DB_INFO_TABLE, String.format(updateSQLTemplate, version.getMajor(), IG_SCHEMA_MAJOR_VERSION_KEY), caseDbTransaction);
|
||||||
tskCase.getCaseDbAccessManager().update(IG_DB_INFO_TABLE, String.format(updateSQLTemplate, version.getMinor(), IG_SCHEMA_MINOR_VERSION_KEY), caseDbTransaction);
|
tskCase.getCaseDbAccessManager().update(IG_DB_INFO_TABLE, String.format(updateSQLTemplate, version.getMinor(), IG_SCHEMA_MINOR_VERSION_KEY), caseDbTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upgrades the DB schema.
|
* Upgrades the DB schema.
|
||||||
*
|
*
|
||||||
* @return true if the upgrade is successful
|
* @return true if the upgrade is successful
|
||||||
*
|
*
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private boolean upgradeDBSchema() throws TskCoreException, SQLException {
|
private boolean upgradeDBSchema() throws TskCoreException, SQLException {
|
||||||
|
|
||||||
// Read current version from the DBs
|
// Read current version from the DBs
|
||||||
VersionNumber drawableDbIgSchemaVersion = getDrawableDbIgSchemaVersion();
|
VersionNumber drawableDbIgSchemaVersion = getDrawableDbIgSchemaVersion();
|
||||||
VersionNumber caseDbIgSchemaVersion = getCaseDbIgSchemaVersion();
|
VersionNumber caseDbIgSchemaVersion = getCaseDbIgSchemaVersion();
|
||||||
|
|
||||||
// Upgrade Schema in both DrawableDB and CaseDB
|
// Upgrade Schema in both DrawableDB and CaseDB
|
||||||
CaseDbTransaction caseDbTransaction = tskCase.beginTransaction();
|
CaseDbTransaction caseDbTransaction = tskCase.beginTransaction();
|
||||||
DrawableTransaction transaction = beginTransaction();
|
DrawableTransaction transaction = beginTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
caseDbIgSchemaVersion = upgradeCaseDbIgSchema1dot0TO1dot1(caseDbIgSchemaVersion, caseDbTransaction);
|
caseDbIgSchemaVersion = upgradeCaseDbIgSchema1dot0TO1dot1(caseDbIgSchemaVersion, caseDbTransaction);
|
||||||
drawableDbIgSchemaVersion = upgradeDrawableDbIgSchema1dot0TO1dot1(drawableDbIgSchemaVersion, transaction);
|
drawableDbIgSchemaVersion = upgradeDrawableDbIgSchema1dot0TO1dot1(drawableDbIgSchemaVersion, transaction);
|
||||||
|
|
||||||
// update the versions in the tables
|
// update the versions in the tables
|
||||||
updateCaseDbIgSchemaVersion(caseDbIgSchemaVersion, caseDbTransaction );
|
updateCaseDbIgSchemaVersion(caseDbIgSchemaVersion, caseDbTransaction);
|
||||||
updateDrawableDbIgSchemaVersion(drawableDbIgSchemaVersion, transaction);
|
updateDrawableDbIgSchemaVersion(drawableDbIgSchemaVersion, transaction);
|
||||||
|
|
||||||
caseDbTransaction.commit();
|
caseDbTransaction.commit();
|
||||||
caseDbTransaction = null;
|
caseDbTransaction = null;
|
||||||
commitTransaction(transaction, false);
|
commitTransaction(transaction, false);
|
||||||
transaction = null;
|
transaction = null;
|
||||||
}
|
} catch (TskCoreException | SQLException ex) {
|
||||||
catch (TskCoreException | SQLException ex) {
|
|
||||||
if (null != caseDbTransaction) {
|
if (null != caseDbTransaction) {
|
||||||
try {
|
try {
|
||||||
caseDbTransaction.rollback();
|
caseDbTransaction.rollback();
|
||||||
@ -921,57 +923,59 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upgrades IG tables in CaseDB from 1.0 to 1.1
|
* Upgrades IG tables in CaseDB from 1.0 to 1.1 Does nothing if the incoming
|
||||||
* Does nothing if the incoming version is not 1.0
|
* version is not 1.0
|
||||||
*
|
*
|
||||||
* @param currVersion version to upgrade from
|
* @param currVersion version to upgrade from
|
||||||
* @param caseDbTransaction transaction to use for all updates
|
* @param caseDbTransaction transaction to use for all updates
|
||||||
*
|
*
|
||||||
* @return new version number
|
* @return new version number
|
||||||
* @throws TskCoreException
|
*
|
||||||
|
* @throws TskCoreException
|
||||||
*/
|
*/
|
||||||
private VersionNumber upgradeCaseDbIgSchema1dot0TO1dot1(VersionNumber currVersion, CaseDbTransaction caseDbTransaction ) throws TskCoreException {
|
private VersionNumber upgradeCaseDbIgSchema1dot0TO1dot1(VersionNumber currVersion, CaseDbTransaction caseDbTransaction) throws TskCoreException {
|
||||||
|
|
||||||
// Upgrade if current version is 1.0
|
// Upgrade if current version is 1.0
|
||||||
// or 1.1 - a bug in versioning alllowed some databases to be versioned as 1.1 without the actual corresponding upgrade. This allows such databases to be fixed, if needed.
|
// or 1.1 - a bug in versioning alllowed some databases to be versioned as 1.1 without the actual corresponding upgrade. This allows such databases to be fixed, if needed.
|
||||||
if (!(currVersion.getMajor() == 1 &&
|
if (!(currVersion.getMajor() == 1
|
||||||
(currVersion.getMinor() == 0 || currVersion.getMinor() == 1))) {
|
&& (currVersion.getMinor() == 0 || currVersion.getMinor() == 1))) {
|
||||||
return currVersion;
|
return currVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a 'is_analyzed' column to groups table in CaseDB
|
// Add a 'is_analyzed' column to groups table in CaseDB
|
||||||
String alterSQL = " ADD COLUMN is_analyzed integer DEFAULT 1 "; //NON-NLS
|
String alterSQL = " ADD COLUMN is_analyzed integer DEFAULT 1 "; //NON-NLS
|
||||||
if (false == tskCase.getCaseDbAccessManager().columnExists(GROUPS_TABLENAME, "is_analyzed", caseDbTransaction )) {
|
if (false == tskCase.getCaseDbAccessManager().columnExists(GROUPS_TABLENAME, "is_analyzed", caseDbTransaction)) {
|
||||||
tskCase.getCaseDbAccessManager().alterTable(GROUPS_TABLENAME, alterSQL, caseDbTransaction);
|
tskCase.getCaseDbAccessManager().alterTable(GROUPS_TABLENAME, alterSQL, caseDbTransaction);
|
||||||
}
|
}
|
||||||
return new VersionNumber(1,1,0);
|
return new VersionNumber(1, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upgrades IG tables in DrawableDB from 1.0 to 1.1
|
* Upgrades IG tables in DrawableDB from 1.0 to 1.1 Does nothing if the
|
||||||
* Does nothing if the incoming version is not 1.0
|
* incoming version is not 1.0
|
||||||
*
|
*
|
||||||
* @param currVersion version to upgrade from
|
* @param currVersion version to upgrade from
|
||||||
* @param transaction transaction to use for all updates
|
* @param transaction transaction to use for all updates
|
||||||
*
|
*
|
||||||
* @return new version number
|
* @return new version number
|
||||||
* @throws TskCoreException
|
*
|
||||||
|
* @throws TskCoreException
|
||||||
*/
|
*/
|
||||||
private VersionNumber upgradeDrawableDbIgSchema1dot0TO1dot1(VersionNumber currVersion, DrawableTransaction transaction ) throws TskCoreException {
|
private VersionNumber upgradeDrawableDbIgSchema1dot0TO1dot1(VersionNumber currVersion, DrawableTransaction transaction) throws TskCoreException {
|
||||||
|
|
||||||
if (currVersion.getMajor() != 1 ||
|
if (currVersion.getMajor() != 1
|
||||||
currVersion.getMinor() != 0) {
|
|| currVersion.getMinor() != 0) {
|
||||||
return currVersion;
|
return currVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
// There are no changes in DrawableDB schema in 1.0 -> 1.1
|
// There are no changes in DrawableDB schema in 1.0 -> 1.1
|
||||||
return new VersionNumber(1,1,0);
|
return new VersionNumber(1, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void finalize() throws Throwable {
|
protected void finalize() throws Throwable {
|
||||||
/*
|
/*
|
||||||
@ -1143,10 +1147,10 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record in the DB that the group with the given key is seen
|
* Record in the DB that the group with the given key is seen by given
|
||||||
* by given examiner id.
|
* examiner id.
|
||||||
*
|
*
|
||||||
* @param groupKey key identifying the group.
|
* @param groupKey key identifying the group.
|
||||||
* @param examinerID examiner id.
|
* @param examinerID examiner id.
|
||||||
*
|
*
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
@ -1154,16 +1158,16 @@ public final class DrawableDB {
|
|||||||
public void markGroupSeen(GroupKey<?> groupKey, long examinerID) throws TskCoreException {
|
public void markGroupSeen(GroupKey<?> groupKey, long examinerID) throws TskCoreException {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the groupSeenCache to see if the seen status for this group was set recently.
|
* Check the groupSeenCache to see if the seen status for this group was
|
||||||
* If recently set to seen, there's no need to update it
|
* set recently. If recently set to seen, there's no need to update it
|
||||||
*/
|
*/
|
||||||
Boolean cachedValue = groupSeenCache.getIfPresent(groupKey);
|
Boolean cachedValue = groupSeenCache.getIfPresent(groupKey);
|
||||||
if (cachedValue != null && cachedValue == true) {
|
if (cachedValue != null && cachedValue == true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// query to find the group id from attribute/value
|
// query to find the group id from attribute/value
|
||||||
String innerQuery = String.format("( SELECT group_id FROM " + GROUPS_TABLENAME //NON-NLS
|
String innerQuery = String.format("( SELECT group_id FROM " + GROUPS_TABLENAME //NON-NLS
|
||||||
+ " WHERE attribute = \'%s\' AND value = \'%s\' and data_source_obj_id = %d )", //NON-NLS
|
+ " WHERE attribute = \'%s\' AND value = \'%s\' and data_source_obj_id = %d )", //NON-NLS
|
||||||
SleuthkitCase.escapeSingleQuotes(groupKey.getAttribute().attrName.toString()),
|
SleuthkitCase.escapeSingleQuotes(groupKey.getAttribute().attrName.toString()),
|
||||||
SleuthkitCase.escapeSingleQuotes(groupKey.getValueDisplayName()),
|
SleuthkitCase.escapeSingleQuotes(groupKey.getValueDisplayName()),
|
||||||
@ -1180,8 +1184,8 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record in the DB that given group is unseen.
|
* Record in the DB that given group is unseen. The group is marked unseen
|
||||||
* The group is marked unseen for ALL examiners that have seen the group.
|
* for ALL examiners that have seen the group.
|
||||||
*
|
*
|
||||||
* @param groupKey key identifying the group.
|
* @param groupKey key identifying the group.
|
||||||
*
|
*
|
||||||
@ -1190,20 +1194,20 @@ public final class DrawableDB {
|
|||||||
public void markGroupUnseen(GroupKey<?> groupKey) throws TskCoreException {
|
public void markGroupUnseen(GroupKey<?> groupKey) throws TskCoreException {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the groupSeenCache to see if the seen status for this group was set recently.
|
* Check the groupSeenCache to see if the seen status for this group was
|
||||||
* If recently set to unseen, there's no need to update it
|
* set recently. If recently set to unseen, there's no need to update it
|
||||||
*/
|
*/
|
||||||
Boolean cachedValue = groupSeenCache.getIfPresent(groupKey);
|
Boolean cachedValue = groupSeenCache.getIfPresent(groupKey);
|
||||||
if (cachedValue != null && cachedValue == false) {
|
if (cachedValue != null && cachedValue == false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String updateSQL = String.format(" SET seen = 0 WHERE group_id in ( " + getGroupIdQuery(groupKey) + ")" ); //NON-NLS
|
String updateSQL = String.format(" SET seen = 0 WHERE group_id in ( " + getGroupIdQuery(groupKey) + ")"); //NON-NLS
|
||||||
tskCase.getCaseDbAccessManager().update(GROUPS_SEEN_TABLENAME, updateSQL);
|
tskCase.getCaseDbAccessManager().update(GROUPS_SEEN_TABLENAME, updateSQL);
|
||||||
|
|
||||||
groupSeenCache.put(groupKey, false);
|
groupSeenCache.put(groupKey, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the isAnalysed flag in the groups table for the given group to true.
|
* Sets the isAnalysed flag in the groups table for the given group to true.
|
||||||
*
|
*
|
||||||
@ -1213,7 +1217,6 @@ public final class DrawableDB {
|
|||||||
*/
|
*/
|
||||||
public void markGroupAnalyzed(GroupKey<?> groupKey) throws TskCoreException {
|
public void markGroupAnalyzed(GroupKey<?> groupKey) throws TskCoreException {
|
||||||
|
|
||||||
|
|
||||||
String updateSQL = String.format(" SET is_analyzed = %d "
|
String updateSQL = String.format(" SET is_analyzed = %d "
|
||||||
+ " WHERE attribute = \'%s\' AND value = \'%s\' and data_source_obj_id = %d ",
|
+ " WHERE attribute = \'%s\' AND value = \'%s\' and data_source_obj_id = %d ",
|
||||||
1,
|
1,
|
||||||
@ -1223,7 +1226,7 @@ public final class DrawableDB {
|
|||||||
|
|
||||||
tskCase.getCaseDbAccessManager().update(GROUPS_TABLENAME, updateSQL);
|
tskCase.getCaseDbAccessManager().update(GROUPS_TABLENAME, updateSQL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a file from the drawables databse.
|
* Removes a file from the drawables databse.
|
||||||
*
|
*
|
||||||
@ -1254,11 +1257,11 @@ public final class DrawableDB {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the image file.
|
* Updates the image file.
|
||||||
*
|
*
|
||||||
* @param f file to update.
|
* @param f file to update.
|
||||||
*
|
*
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
*/
|
*/
|
||||||
public void updateFile(DrawableFile f) throws TskCoreException, SQLException {
|
public void updateFile(DrawableFile f) throws TskCoreException, SQLException {
|
||||||
DrawableTransaction trans = null;
|
DrawableTransaction trans = null;
|
||||||
@ -1288,14 +1291,13 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update an existing entry (or make a new one) into the DB that includes
|
* Update an existing entry (or make a new one) into the DB that includes
|
||||||
* group information. Called when a file has been analyzed or during a bulk
|
* group information. Called when a file has been analyzed or during a bulk
|
||||||
* rebuild
|
* rebuild
|
||||||
*
|
*
|
||||||
* @param f file to update
|
* @param f file to update
|
||||||
* @param tr
|
* @param tr
|
||||||
* @param caseDbTransaction
|
* @param caseDbTransaction
|
||||||
*/
|
*/
|
||||||
public void updateFile(DrawableFile f, DrawableTransaction tr, CaseDbTransaction caseDbTransaction) {
|
public void updateFile(DrawableFile f, DrawableTransaction tr, CaseDbTransaction caseDbTransaction) {
|
||||||
@ -1601,24 +1603,24 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the build status for the given data source.
|
* Get the build status for the given data source. Will return UNKNOWN if
|
||||||
* Will return UNKNOWN if the data source is not yet in the database.
|
* the data source is not yet in the database.
|
||||||
*
|
*
|
||||||
* @param dataSourceId
|
* @param dataSourceId
|
||||||
*
|
*
|
||||||
* @return The status of the data source or UKNOWN if it is not found.
|
* @return The status of the data source or UKNOWN if it is not found.
|
||||||
*
|
*
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
*/
|
*/
|
||||||
public DrawableDbBuildStatusEnum getDataSourceDbBuildStatus(Long dataSourceId) throws TskCoreException {
|
public DrawableDbBuildStatusEnum getDataSourceDbBuildStatus(Long dataSourceId) throws TskCoreException {
|
||||||
Map<Long, DrawableDbBuildStatusEnum> statusMap = getDataSourceDbBuildStatus();
|
Map<Long, DrawableDbBuildStatusEnum> statusMap = getDataSourceDbBuildStatus();
|
||||||
if (statusMap.containsKey(dataSourceId) == false) {
|
if (statusMap.containsKey(dataSourceId) == false) {
|
||||||
return DrawableDbBuildStatusEnum.UNKNOWN;
|
return DrawableDbBuildStatusEnum.UNKNOWN;
|
||||||
}
|
}
|
||||||
return statusMap.get(dataSourceId);
|
return statusMap.get(dataSourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert/update given data source object id and it's DB rebuild status in
|
* Insert/update given data source object id and it's DB rebuild status in
|
||||||
@ -1687,47 +1689,50 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not the given group is analyzed and ready to be viewed.
|
* Returns whether or not the given group is analyzed and ready to be
|
||||||
*
|
* viewed.
|
||||||
|
*
|
||||||
* @param groupKey group key.
|
* @param groupKey group key.
|
||||||
|
*
|
||||||
* @return true if the group is analyzed.
|
* @return true if the group is analyzed.
|
||||||
|
*
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
*/
|
*/
|
||||||
public Boolean isGroupAnalyzed(GroupKey<?> groupKey) throws SQLException, TskCoreException {
|
public Boolean isGroupAnalyzed(GroupKey<?> groupKey) throws SQLException, TskCoreException {
|
||||||
|
|
||||||
// Callback to process result of isAnalyzed query
|
// Callback to process result of isAnalyzed query
|
||||||
class IsGroupAnalyzedQueryResultProcessor implements CaseDbAccessQueryCallback {
|
class IsGroupAnalyzedQueryResultProcessor implements CaseDbAccessQueryCallback {
|
||||||
|
|
||||||
private boolean isAnalyzed = false;
|
private boolean isAnalyzed = false;
|
||||||
|
|
||||||
boolean getIsAnalyzed() {
|
boolean getIsAnalyzed() {
|
||||||
return isAnalyzed;
|
return isAnalyzed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(ResultSet resultSet) {
|
public void process(ResultSet resultSet) {
|
||||||
try {
|
try {
|
||||||
if (resultSet.next()) {
|
if (resultSet.next()) {
|
||||||
isAnalyzed = resultSet.getInt("is_analyzed") == 1 ? true: false;
|
isAnalyzed = resultSet.getInt("is_analyzed") == 1 ? true : false;
|
||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
logger.log(Level.SEVERE, "Failed to get group is_analyzed", ex); //NON-NLS
|
logger.log(Level.SEVERE, "Failed to get group is_analyzed", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IsGroupAnalyzedQueryResultProcessor queryResultProcessor = new IsGroupAnalyzedQueryResultProcessor();
|
IsGroupAnalyzedQueryResultProcessor queryResultProcessor = new IsGroupAnalyzedQueryResultProcessor();
|
||||||
try {
|
try {
|
||||||
String groupAnalyzedQueryStmt = String.format("is_analyzed FROM " + GROUPS_TABLENAME
|
String groupAnalyzedQueryStmt = String.format("is_analyzed FROM " + GROUPS_TABLENAME
|
||||||
+ " WHERE attribute = \'%s\' AND value = \'%s\' and data_source_obj_id = %d ",
|
+ " WHERE attribute = \'%s\' AND value = \'%s\' and data_source_obj_id = %d ",
|
||||||
SleuthkitCase.escapeSingleQuotes(groupKey.getAttribute().attrName.toString()),
|
SleuthkitCase.escapeSingleQuotes(groupKey.getAttribute().attrName.toString()),
|
||||||
SleuthkitCase.escapeSingleQuotes(groupKey.getValueDisplayName()),
|
SleuthkitCase.escapeSingleQuotes(groupKey.getValueDisplayName()),
|
||||||
groupKey.getAttribute() == DrawableAttribute.PATH ? groupKey.getDataSourceObjId() : 0);
|
groupKey.getAttribute() == DrawableAttribute.PATH ? groupKey.getDataSourceObjId() : 0);
|
||||||
|
|
||||||
tskCase.getCaseDbAccessManager().select(groupAnalyzedQueryStmt, queryResultProcessor);
|
tskCase.getCaseDbAccessManager().select(groupAnalyzedQueryStmt, queryResultProcessor);
|
||||||
return queryResultProcessor.getIsAnalyzed();
|
return queryResultProcessor.getIsAnalyzed();
|
||||||
} catch ( TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
String msg = String.format("Failed to get group is_analyzed for group key %s", groupKey.getValueDisplayName()); //NON-NLS
|
String msg = String.format("Failed to get group is_analyzed for group key %s", groupKey.getValueDisplayName()); //NON-NLS
|
||||||
logger.log(Level.SEVERE, msg, ex);
|
logger.log(Level.SEVERE, msg, ex);
|
||||||
}
|
}
|
||||||
@ -1833,7 +1838,7 @@ public final class DrawableDB {
|
|||||||
|
|
||||||
// skip any null/blank values
|
// skip any null/blank values
|
||||||
query.append("WHERE LENGTH(" + groupBy.attrName.toString() + ") > 0 ");
|
query.append("WHERE LENGTH(" + groupBy.attrName.toString() + ") > 0 ");
|
||||||
|
|
||||||
if (dataSource != null) {
|
if (dataSource != null) {
|
||||||
query.append(" AND data_source_obj_id = ").append(dataSource.getId());
|
query.append(" AND data_source_obj_id = ").append(dataSource.getId());
|
||||||
}
|
}
|
||||||
@ -1922,7 +1927,7 @@ public final class DrawableDB {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int isAnalyzed = (groupBy == DrawableAttribute.PATH) ? 0 : 1;
|
int isAnalyzed = (groupBy == DrawableAttribute.PATH) ? 0 : 1;
|
||||||
String insertSQL = String.format(" (data_source_obj_id, value, attribute, is_analyzed) VALUES (%d, \'%s\', \'%s\', %d)",
|
String insertSQL = String.format(" (data_source_obj_id, value, attribute, is_analyzed) VALUES (%d, \'%s\', \'%s\', %d)",
|
||||||
ds_obj_id, SleuthkitCase.escapeSingleQuotes(value), SleuthkitCase.escapeSingleQuotes(groupBy.attrName.toString()), isAnalyzed);
|
ds_obj_id, SleuthkitCase.escapeSingleQuotes(value), SleuthkitCase.escapeSingleQuotes(groupBy.attrName.toString()), isAnalyzed);
|
||||||
if (DbType.POSTGRESQL == tskCase.getDatabaseType()) {
|
if (DbType.POSTGRESQL == tskCase.getDatabaseType()) {
|
||||||
@ -1995,7 +2000,6 @@ public final class DrawableDB {
|
|||||||
return countFilesWhere(" 1 ");
|
return countFilesWhere(" 1 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* delete the row with obj_id = id.
|
* delete the row with obj_id = id.
|
||||||
*
|
*
|
||||||
@ -2027,6 +2031,37 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a cascading delete of a data source, starting from the
|
||||||
|
* datasources table.
|
||||||
|
*
|
||||||
|
* @param dataSourceID The object ID of the data source to delete.
|
||||||
|
*
|
||||||
|
* @throws SQLException
|
||||||
|
* @throws TskCoreException
|
||||||
|
*/
|
||||||
|
public void deleteDataSource(long dataSourceID) throws SQLException, TskCoreException {
|
||||||
|
dbWriteLock();
|
||||||
|
DrawableTransaction trans = null;
|
||||||
|
try {
|
||||||
|
trans = beginTransaction();
|
||||||
|
deleteDataSourceStmt.setLong(1, dataSourceID);
|
||||||
|
deleteDataSourceStmt.executeUpdate();
|
||||||
|
commitTransaction(trans, true);
|
||||||
|
} catch (SQLException | TskCoreException ex) {
|
||||||
|
if (null != trans) {
|
||||||
|
try {
|
||||||
|
rollbackTransaction(trans);
|
||||||
|
} catch (SQLException ex2) {
|
||||||
|
logger.log(Level.SEVERE, String.format("Failed to roll back drawables db transaction after error: %s", ex.getMessage()), ex2); //NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw ex;
|
||||||
|
} finally {
|
||||||
|
dbWriteUnlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class MultipleTransactionException extends IllegalStateException {
|
public class MultipleTransactionException extends IllegalStateException {
|
||||||
|
|
||||||
public MultipleTransactionException() {
|
public MultipleTransactionException() {
|
||||||
@ -2203,11 +2238,11 @@ public final class DrawableDB {
|
|||||||
|
|
||||||
// The files are processed ORDERED BY parent path
|
// The files are processed ORDERED BY parent path
|
||||||
// We want to preserve that order here, so that we can detect a
|
// We want to preserve that order here, so that we can detect a
|
||||||
// change in path, and thus mark the path group as analyzed
|
// change in path, and thus mark the path group as analyzed
|
||||||
// Hence we use a LinkedHashSet here.
|
// Hence we use a LinkedHashSet here.
|
||||||
private final Set<Long> updatedFiles = new LinkedHashSet<>();
|
private final Set<Long> updatedFiles = new LinkedHashSet<>();
|
||||||
private final Set<Long> removedFiles = new LinkedHashSet<>();
|
private final Set<Long> removedFiles = new LinkedHashSet<>();
|
||||||
|
|
||||||
private boolean completed;
|
private boolean completed;
|
||||||
|
|
||||||
private DrawableTransaction() throws TskCoreException, SQLException {
|
private DrawableTransaction() throws TskCoreException, SQLException {
|
||||||
|
@ -348,7 +348,6 @@ SolrSearch.openCore.msg=Opening text index
|
|||||||
SolrSearch.openGiantCore.msg=Opening text index. Text index for this case is very large and may take long time to load.
|
SolrSearch.openGiantCore.msg=Opening text index. Text index for this case is very large and may take long time to load.
|
||||||
SolrSearch.openLargeCore.msg=Opening text index. This may take several minutes.
|
SolrSearch.openLargeCore.msg=Opening text index. This may take several minutes.
|
||||||
SolrSearch.readingIndexes.msg=Reading text index metadata file
|
SolrSearch.readingIndexes.msg=Reading text index metadata file
|
||||||
SolrSearchService.deleteDataSource.exceptionMessage.noCurrentSolrCore=DeleteDataSource did not contain a current Solr core so could not delete the Data Source
|
|
||||||
# {0} - index folder path
|
# {0} - index folder path
|
||||||
SolrSearchService.exceptionMessage.failedToDeleteIndexFiles=Failed to delete text index files at {0}
|
SolrSearchService.exceptionMessage.failedToDeleteIndexFiles=Failed to delete text index files at {0}
|
||||||
SolrSearchService.exceptionMessage.noCurrentSolrCore=IndexMetadata did not contain a current Solr core so could not delete the case
|
SolrSearchService.exceptionMessage.noCurrentSolrCore=IndexMetadata did not contain a current Solr core so could not delete the case
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#Updated by build script
|
#Updated by build script
|
||||||
#Fri, 04 Oct 2019 14:30:10 -0400
|
#Mon, 28 Oct 2019 16:22:16 -0400
|
||||||
LBL_splash_window_title=Starting Autopsy
|
LBL_splash_window_title=Starting Autopsy
|
||||||
SPLASH_HEIGHT=314
|
SPLASH_HEIGHT=314
|
||||||
SPLASH_WIDTH=538
|
SPLASH_WIDTH=538
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#Updated by build script
|
#Updated by build script
|
||||||
#Fri, 04 Oct 2019 14:30:10 -0400
|
#Mon, 28 Oct 2019 16:22:16 -0400
|
||||||
CTL_MainWindow_Title=Autopsy 4.13.0
|
CTL_MainWindow_Title=Autopsy 4.13.0
|
||||||
CTL_MainWindow_Title_No_Project=Autopsy 4.13.0
|
CTL_MainWindow_Title_No_Project=Autopsy 4.13.0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user