mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 01:07:42 +00:00
allow marking grouos as seen or unseen, update next unseen appropriatly
This commit is contained in:
parent
bf1481d685
commit
efd19fc56f
@ -56,14 +56,15 @@ public class NextUnseenGroup extends Action {
|
|||||||
|
|
||||||
});
|
});
|
||||||
controller.getGroupManager().getUnSeenGroups().addListener((Observable observable) -> {
|
controller.getGroupManager().getUnSeenGroups().addListener((Observable observable) -> {
|
||||||
updateButton();
|
Platform.runLater(this::updateButton);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
setEventHandler((ActionEvent t) -> {
|
setEventHandler((ActionEvent t) -> {
|
||||||
Optional.ofNullable(controller.viewState())
|
Optional.ofNullable(controller.viewState())
|
||||||
.map(ObjectExpression<GroupViewState>::getValue)
|
.map(ObjectExpression<GroupViewState>::getValue)
|
||||||
.map(GroupViewState::getGroup)
|
.map(GroupViewState::getGroup)
|
||||||
.ifPresent(controller.getGroupManager()::markGroupSeen);
|
.ifPresent(group -> controller.getGroupManager().markGroupSeen(group, true));
|
||||||
|
|
||||||
if (false == controller.getGroupManager().getUnSeenGroups().isEmpty()) {
|
if (false == controller.getGroupManager().getUnSeenGroups().isEmpty()) {
|
||||||
controller.advance(GroupViewState.tile(controller.getGroupManager().getUnSeenGroups().get(0)));
|
controller.advance(GroupViewState.tile(controller.getGroupManager().getUnSeenGroups().get(0)));
|
||||||
|
@ -71,51 +71,51 @@ import org.sqlite.SQLiteJDBCLoader;
|
|||||||
* the future. see also {@link EventsDB} in the timeline viewer.
|
* the future. see also {@link EventsDB} in the timeline viewer.
|
||||||
*/
|
*/
|
||||||
public final class DrawableDB {
|
public final class DrawableDB {
|
||||||
|
|
||||||
private static final java.util.logging.Logger LOGGER = Logger.getLogger(DrawableDB.class.getName());
|
private static final java.util.logging.Logger LOGGER = Logger.getLogger(DrawableDB.class.getName());
|
||||||
|
|
||||||
//column name constants//////////////////////
|
//column name constants//////////////////////
|
||||||
private static final String ANALYZED = "analyzed";
|
private static final String ANALYZED = "analyzed";
|
||||||
|
|
||||||
private static final String OBJ_ID = "obj_id";
|
private static final String OBJ_ID = "obj_id";
|
||||||
|
|
||||||
private static final String HASH_SET_NAME = "hash_set_name";
|
private static final String HASH_SET_NAME = "hash_set_name";
|
||||||
|
|
||||||
private final PreparedStatement insertHashSetStmt;
|
private final PreparedStatement insertHashSetStmt;
|
||||||
|
|
||||||
private final PreparedStatement groupSeenQueryStmt;
|
private final PreparedStatement groupSeenQueryStmt;
|
||||||
|
|
||||||
private final PreparedStatement insertGroupStmt;
|
private final PreparedStatement insertGroupStmt;
|
||||||
|
|
||||||
private final List<PreparedStatement> preparedStatements = new ArrayList<>();
|
private final List<PreparedStatement> preparedStatements = new ArrayList<>();
|
||||||
|
|
||||||
private final PreparedStatement removeFileStmt;
|
private final PreparedStatement removeFileStmt;
|
||||||
|
|
||||||
private final PreparedStatement updateGroupStmt;
|
private final PreparedStatement updateGroupStmt;
|
||||||
|
|
||||||
private final PreparedStatement selectHashSetStmt;
|
private final PreparedStatement selectHashSetStmt;
|
||||||
|
|
||||||
private final PreparedStatement selectHashSetNamesStmt;
|
private final PreparedStatement selectHashSetNamesStmt;
|
||||||
|
|
||||||
private final PreparedStatement insertHashHitStmt;
|
private final PreparedStatement insertHashHitStmt;
|
||||||
|
|
||||||
private final PreparedStatement updateFileStmt;
|
private final PreparedStatement updateFileStmt;
|
||||||
private PreparedStatement insertFileStmt;
|
private PreparedStatement insertFileStmt;
|
||||||
|
|
||||||
private final PreparedStatement pathGroupStmt;
|
private final PreparedStatement pathGroupStmt;
|
||||||
|
|
||||||
private final PreparedStatement nameGroupStmt;
|
private final PreparedStatement nameGroupStmt;
|
||||||
|
|
||||||
private final PreparedStatement created_timeGroupStmt;
|
private final PreparedStatement created_timeGroupStmt;
|
||||||
|
|
||||||
private final PreparedStatement modified_timeGroupStmt;
|
private final PreparedStatement modified_timeGroupStmt;
|
||||||
|
|
||||||
private final PreparedStatement makeGroupStmt;
|
private final PreparedStatement makeGroupStmt;
|
||||||
|
|
||||||
private final PreparedStatement modelGroupStmt;
|
private final PreparedStatement modelGroupStmt;
|
||||||
|
|
||||||
private final PreparedStatement analyzedGroupStmt;
|
private final PreparedStatement analyzedGroupStmt;
|
||||||
|
|
||||||
private final PreparedStatement hashSetGroupStmt;
|
private final PreparedStatement hashSetGroupStmt;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,13 +128,13 @@ public final class DrawableDB {
|
|||||||
* list of observers to be notified if the database changes
|
* list of observers to be notified if the database changes
|
||||||
*/
|
*/
|
||||||
private final HashSet<FileUpdateEvent.FileUpdateListener> updateListeners = new HashSet<>();
|
private final HashSet<FileUpdateEvent.FileUpdateListener> updateListeners = new HashSet<>();
|
||||||
|
|
||||||
private GroupManager groupManager;
|
private GroupManager groupManager;
|
||||||
|
|
||||||
private final Path dbPath;
|
private final Path dbPath;
|
||||||
|
|
||||||
volatile private Connection con;
|
volatile private Connection con;
|
||||||
|
|
||||||
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(true); //use fairness policy
|
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(true); //use fairness policy
|
||||||
|
|
||||||
private final Lock DBLock = rwLock.writeLock(); //using exclusing lock for all db ops for now
|
private final Lock DBLock = rwLock.writeLock(); //using exclusing lock for all db ops for now
|
||||||
@ -206,9 +206,9 @@ public final class DrawableDB {
|
|||||||
insertFileStmt = prepareStatement(
|
insertFileStmt = prepareStatement(
|
||||||
"INSERT OR IGNORE INTO drawable_files (obj_id , path, name, created_time, modified_time, make, model, analyzed) "
|
"INSERT OR IGNORE INTO drawable_files (obj_id , path, name, created_time, modified_time, make, model, analyzed) "
|
||||||
+ "VALUES (?,?,?,?,?,?,?,?)");
|
+ "VALUES (?,?,?,?,?,?,?,?)");
|
||||||
|
|
||||||
removeFileStmt = prepareStatement("delete from drawable_files where obj_id = ?");
|
removeFileStmt = prepareStatement("delete from drawable_files where obj_id = ?");
|
||||||
|
|
||||||
pathGroupStmt = prepareStatement("select obj_id , analyzed from drawable_files where path = ? ", DrawableAttribute.PATH);
|
pathGroupStmt = prepareStatement("select obj_id , analyzed from drawable_files where path = ? ", DrawableAttribute.PATH);
|
||||||
nameGroupStmt = prepareStatement("select obj_id , analyzed from drawable_files where name = ? ", DrawableAttribute.NAME);
|
nameGroupStmt = prepareStatement("select obj_id , analyzed from drawable_files where name = ? ", DrawableAttribute.NAME);
|
||||||
created_timeGroupStmt = prepareStatement("select obj_id , analyzed from drawable_files where created_time = ? ", DrawableAttribute.CREATED_TIME);
|
created_timeGroupStmt = prepareStatement("select obj_id , analyzed from drawable_files where created_time = ? ", DrawableAttribute.CREATED_TIME);
|
||||||
@ -217,23 +217,23 @@ public final class DrawableDB {
|
|||||||
modelGroupStmt = prepareStatement("select obj_id , analyzed from drawable_files where model = ? ", DrawableAttribute.MODEL);
|
modelGroupStmt = prepareStatement("select obj_id , analyzed from drawable_files where model = ? ", DrawableAttribute.MODEL);
|
||||||
analyzedGroupStmt = prepareStatement("Select obj_id , analyzed from drawable_files where analyzed = ?", DrawableAttribute.ANALYZED);
|
analyzedGroupStmt = prepareStatement("Select obj_id , analyzed from drawable_files where analyzed = ?", DrawableAttribute.ANALYZED);
|
||||||
hashSetGroupStmt = prepareStatement("select drawable_files.obj_id as obj_id, analyzed from drawable_files , hash_sets , hash_set_hits where drawable_files.obj_id = hash_set_hits.obj_id and hash_sets.hash_set_id = hash_set_hits.hash_set_id and hash_sets.hash_set_name = ?", DrawableAttribute.HASHSET);
|
hashSetGroupStmt = prepareStatement("select drawable_files.obj_id as obj_id, analyzed from drawable_files , hash_sets , hash_set_hits where drawable_files.obj_id = hash_set_hits.obj_id and hash_sets.hash_set_id = hash_set_hits.hash_set_id and hash_sets.hash_set_name = ?", DrawableAttribute.HASHSET);
|
||||||
|
|
||||||
updateGroupStmt = prepareStatement("update groups set seen = 1 where value = ? and attribute = ?");
|
updateGroupStmt = prepareStatement("update groups set seen = ? where value = ? and attribute = ?");
|
||||||
insertGroupStmt = prepareStatement("insert or replace into groups (value, attribute) values (?,?)");
|
insertGroupStmt = prepareStatement("insert or replace into groups (value, attribute) values (?,?)");
|
||||||
|
|
||||||
groupSeenQueryStmt = prepareStatement("select seen from groups where value = ? and attribute = ?");
|
groupSeenQueryStmt = prepareStatement("select seen from groups where value = ? and attribute = ?");
|
||||||
|
|
||||||
selectHashSetNamesStmt = prepareStatement("SELECT DISTINCT hash_set_name FROM hash_sets");
|
selectHashSetNamesStmt = prepareStatement("SELECT DISTINCT hash_set_name FROM hash_sets");
|
||||||
insertHashSetStmt = prepareStatement("insert or ignore into hash_sets (hash_set_name) values (?)");
|
insertHashSetStmt = prepareStatement("insert or ignore into hash_sets (hash_set_name) values (?)");
|
||||||
selectHashSetStmt = prepareStatement("select hash_set_id from hash_sets where hash_set_name = ?");
|
selectHashSetStmt = prepareStatement("select hash_set_id from hash_sets where hash_set_name = ?");
|
||||||
|
|
||||||
insertHashHitStmt = prepareStatement("insert or ignore into hash_set_hits (hash_set_id, obj_id) values (?,?)");
|
insertHashHitStmt = prepareStatement("insert or ignore into hash_set_hits (hash_set_id, obj_id) values (?,?)");
|
||||||
|
|
||||||
initializeImageList();
|
initializeImageList();
|
||||||
} else {
|
} else {
|
||||||
throw new ExceptionInInitializerError();
|
throw new ExceptionInInitializerError();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -271,7 +271,7 @@ public final class DrawableDB {
|
|||||||
if (attr != null) {
|
if (attr != null) {
|
||||||
groupStatementMap.put(attr, prepareStatement);
|
groupStatementMap.put(attr, prepareStatement);
|
||||||
}
|
}
|
||||||
|
|
||||||
return prepareStatement;
|
return prepareStatement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +284,7 @@ public final class DrawableDB {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static DrawableDB getDrawableDB(Path dbPath, SleuthkitCase tskCase) {
|
public static DrawableDB getDrawableDB(Path dbPath, SleuthkitCase tskCase) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return new DrawableDB(dbPath.resolve("drawable.db"), tskCase);
|
return new DrawableDB(dbPath.resolve("drawable.db"), tskCase);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
@ -295,7 +295,7 @@ public final class DrawableDB {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPragmas() throws SQLException {
|
private void setPragmas() throws SQLException {
|
||||||
|
|
||||||
//this should match Sleuthkit db setupt
|
//this should match Sleuthkit db setupt
|
||||||
@ -321,7 +321,7 @@ public final class DrawableDB {
|
|||||||
//we never delete anything so...
|
//we never delete anything so...
|
||||||
statement.execute("PRAGMA auto_vacuum = 0");
|
statement.execute("PRAGMA auto_vacuum = 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
LOGGER.log(Level.INFO, String.format("sqlite-jdbc version %s loaded in %s mode",
|
LOGGER.log(Level.INFO, String.format("sqlite-jdbc version %s loaded in %s mode",
|
||||||
SQLiteJDBCLoader.getVersion(), SQLiteJDBCLoader.isNativeMode()
|
SQLiteJDBCLoader.getVersion(), SQLiteJDBCLoader.isNativeMode()
|
||||||
@ -329,7 +329,7 @@ public final class DrawableDB {
|
|||||||
} catch (Exception exception) {
|
} catch (Exception exception) {
|
||||||
LOGGER.log(Level.WARNING, "exception while checking sqlite-jdbc version and mode", exception);
|
LOGGER.log(Level.WARNING, "exception while checking sqlite-jdbc version and mode", exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -344,7 +344,7 @@ public final class DrawableDB {
|
|||||||
openDBCon();
|
openDBCon();
|
||||||
}
|
}
|
||||||
setPragmas();
|
setPragmas();
|
||||||
|
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "problem accessing database", ex);
|
LOGGER.log(Level.SEVERE, "problem accessing database", ex);
|
||||||
return false;
|
return false;
|
||||||
@ -364,7 +364,7 @@ public final class DrawableDB {
|
|||||||
LOGGER.log(Level.SEVERE, "problem creating drawable_files table", ex);
|
LOGGER.log(Level.SEVERE, "problem creating drawable_files table", ex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Statement stmt = con.createStatement()) {
|
try (Statement stmt = con.createStatement()) {
|
||||||
String sql = "CREATE TABLE if not exists groups "
|
String sql = "CREATE TABLE if not exists groups "
|
||||||
+ "(group_id INTEGER PRIMARY KEY, "
|
+ "(group_id INTEGER PRIMARY KEY, "
|
||||||
@ -377,7 +377,7 @@ public final class DrawableDB {
|
|||||||
LOGGER.log(Level.SEVERE, "problem creating groups table", ex);
|
LOGGER.log(Level.SEVERE, "problem creating groups table", ex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Statement stmt = con.createStatement()) {
|
try (Statement stmt = con.createStatement()) {
|
||||||
String sql = "CREATE TABLE if not exists hash_sets "
|
String sql = "CREATE TABLE if not exists hash_sets "
|
||||||
+ "( hash_set_id INTEGER primary key,"
|
+ "( hash_set_id INTEGER primary key,"
|
||||||
@ -387,7 +387,7 @@ public final class DrawableDB {
|
|||||||
LOGGER.log(Level.SEVERE, "problem creating hash_sets table", ex);
|
LOGGER.log(Level.SEVERE, "problem creating hash_sets table", ex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Statement stmt = con.createStatement()) {
|
try (Statement stmt = con.createStatement()) {
|
||||||
String sql = "CREATE TABLE if not exists hash_set_hits "
|
String sql = "CREATE TABLE if not exists hash_set_hits "
|
||||||
+ "(hash_set_id INTEGER REFERENCES hash_sets(hash_set_id) not null, "
|
+ "(hash_set_id INTEGER REFERENCES hash_sets(hash_set_id) not null, "
|
||||||
@ -398,45 +398,45 @@ public final class DrawableDB {
|
|||||||
LOGGER.log(Level.SEVERE, "problem creating hash_set_hits table", ex);
|
LOGGER.log(Level.SEVERE, "problem creating hash_set_hits table", ex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Statement stmt = con.createStatement()) {
|
try (Statement stmt = con.createStatement()) {
|
||||||
String sql = "CREATE INDEX if not exists path_idx ON drawable_files(path)";
|
String sql = "CREATE INDEX if not exists path_idx ON drawable_files(path)";
|
||||||
stmt.execute(sql);
|
stmt.execute(sql);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "problem creating path_idx", ex);
|
LOGGER.log(Level.WARNING, "problem creating path_idx", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Statement stmt = con.createStatement()) {
|
try (Statement stmt = con.createStatement()) {
|
||||||
String sql = "CREATE INDEX if not exists name_idx ON drawable_files(name)";
|
String sql = "CREATE INDEX if not exists name_idx ON drawable_files(name)";
|
||||||
stmt.execute(sql);
|
stmt.execute(sql);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "problem creating name_idx", ex);
|
LOGGER.log(Level.WARNING, "problem creating name_idx", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Statement stmt = con.createStatement()) {
|
try (Statement stmt = con.createStatement()) {
|
||||||
String sql = "CREATE INDEX if not exists make_idx ON drawable_files(make)";
|
String sql = "CREATE INDEX if not exists make_idx ON drawable_files(make)";
|
||||||
stmt.execute(sql);
|
stmt.execute(sql);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "problem creating make_idx", ex);
|
LOGGER.log(Level.WARNING, "problem creating make_idx", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Statement stmt = con.createStatement()) {
|
try (Statement stmt = con.createStatement()) {
|
||||||
String sql = "CREATE INDEX if not exists model_idx ON drawable_files(model)";
|
String sql = "CREATE INDEX if not exists model_idx ON drawable_files(model)";
|
||||||
stmt.execute(sql);
|
stmt.execute(sql);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "problem creating model_idx", ex);
|
LOGGER.log(Level.WARNING, "problem creating model_idx", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Statement stmt = con.createStatement()) {
|
try (Statement stmt = con.createStatement()) {
|
||||||
String sql = "CREATE INDEX if not exists analyzed_idx ON drawable_files(analyzed)";
|
String sql = "CREATE INDEX if not exists analyzed_idx ON drawable_files(analyzed)";
|
||||||
stmt.execute(sql);
|
stmt.execute(sql);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "problem creating analyzed_idx", ex);
|
LOGGER.log(Level.WARNING, "problem creating analyzed_idx", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void finalize() throws Throwable {
|
public void finalize() throws Throwable {
|
||||||
try {
|
try {
|
||||||
@ -445,7 +445,7 @@ public final class DrawableDB {
|
|||||||
super.finalize();
|
super.finalize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void closeDBCon() {
|
public void closeDBCon() {
|
||||||
if (con != null) {
|
if (con != null) {
|
||||||
try {
|
try {
|
||||||
@ -457,7 +457,7 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
con = null;
|
con = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void openDBCon() {
|
public void openDBCon() {
|
||||||
try {
|
try {
|
||||||
if (con == null || con.isClosed()) {
|
if (con == null || con.isClosed()) {
|
||||||
@ -467,7 +467,7 @@ public final class DrawableDB {
|
|||||||
LOGGER.log(Level.WARNING, "Failed to open connection to drawable.db", ex);
|
LOGGER.log(Level.WARNING, "Failed to open connection to drawable.db", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isClosed() throws SQLException {
|
public boolean isClosed() throws SQLException {
|
||||||
if (con == null) {
|
if (con == null) {
|
||||||
return true;
|
return true;
|
||||||
@ -495,7 +495,7 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isGroupSeen(GroupKey<?> groupKey) {
|
public boolean isGroupSeen(GroupKey<?> groupKey) {
|
||||||
dbReadLock();
|
dbReadLock();
|
||||||
try {
|
try {
|
||||||
@ -514,14 +514,15 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markGroupSeen(GroupKey<?> gk) {
|
public void markGroupSeen(GroupKey<?> gk, boolean seen) {
|
||||||
dbWriteLock();
|
dbWriteLock();
|
||||||
try {
|
try {
|
||||||
//PreparedStatement updateGroup = con.prepareStatement("update groups set seen = 1 where value = ? and attribute = ?");
|
//PreparedStatement updateGroup = con.prepareStatement("update groups set seen = ? where value = ? and attribute = ?");
|
||||||
updateGroupStmt.clearParameters();
|
updateGroupStmt.clearParameters();
|
||||||
updateGroupStmt.setString(1, gk.getValueDisplayName());
|
updateGroupStmt.setBoolean(1, seen);
|
||||||
updateGroupStmt.setString(2, gk.getAttribute().attrName.toString());
|
updateGroupStmt.setString(2, gk.getValueDisplayName());
|
||||||
|
updateGroupStmt.setString(3, gk.getAttribute().attrName.toString());
|
||||||
updateGroupStmt.execute();
|
updateGroupStmt.execute();
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Error marking group as seen", ex);
|
LOGGER.log(Level.SEVERE, "Error marking group as seen", ex);
|
||||||
@ -529,41 +530,41 @@ public final class DrawableDB {
|
|||||||
dbWriteUnlock();
|
dbWriteUnlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean removeFile(long id) {
|
public boolean removeFile(long id) {
|
||||||
DrawableTransaction trans = beginTransaction();
|
DrawableTransaction trans = beginTransaction();
|
||||||
boolean removeFile = removeFile(id, trans);
|
boolean removeFile = removeFile(id, trans);
|
||||||
commitTransaction(trans, true);
|
commitTransaction(trans, true);
|
||||||
return removeFile;
|
return removeFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateFile(DrawableFile<?> f) {
|
public void updateFile(DrawableFile<?> f) {
|
||||||
DrawableTransaction trans = beginTransaction();
|
DrawableTransaction trans = beginTransaction();
|
||||||
updateFile(f, trans);
|
updateFile(f, trans);
|
||||||
commitTransaction(trans, true);
|
commitTransaction(trans, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insertFile(DrawableFile<?> f) {
|
public void insertFile(DrawableFile<?> f) {
|
||||||
DrawableTransaction trans = beginTransaction();
|
DrawableTransaction trans = beginTransaction();
|
||||||
insertFile(f, trans);
|
insertFile(f, trans);
|
||||||
commitTransaction(trans, true);
|
commitTransaction(trans, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insertFile(DrawableFile<?> f, DrawableTransaction tr) {
|
public void insertFile(DrawableFile<?> f, DrawableTransaction tr) {
|
||||||
insertOrUpdateFile(f, tr, insertFileStmt);
|
insertOrUpdateFile(f, tr, insertFileStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateFile(DrawableFile<?> f, DrawableTransaction tr) {
|
public void updateFile(DrawableFile<?> f, DrawableTransaction tr) {
|
||||||
insertOrUpdateFile(f, tr, updateFileStmt);
|
insertOrUpdateFile(f, tr, updateFileStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void insertOrUpdateFile(DrawableFile<?> f, DrawableTransaction tr, PreparedStatement stmt) {
|
private void insertOrUpdateFile(DrawableFile<?> f, DrawableTransaction tr, PreparedStatement stmt) {
|
||||||
|
|
||||||
//TODO: implement batch version -jm
|
//TODO: implement batch version -jm
|
||||||
if (tr.isClosed()) {
|
if (tr.isClosed()) {
|
||||||
throw new IllegalArgumentException("can't update database with closed transaction");
|
throw new IllegalArgumentException("can't update database with closed transaction");
|
||||||
}
|
}
|
||||||
|
|
||||||
dbWriteLock();
|
dbWriteLock();
|
||||||
try {
|
try {
|
||||||
// Update the list of file IDs in memory
|
// Update the list of file IDs in memory
|
||||||
@ -579,9 +580,9 @@ public final class DrawableDB {
|
|||||||
stmt.setString(7, f.getModel());
|
stmt.setString(7, f.getModel());
|
||||||
stmt.setBoolean(8, f.isAnalyzed());
|
stmt.setBoolean(8, f.isAnalyzed());
|
||||||
stmt.executeUpdate();
|
stmt.executeUpdate();
|
||||||
|
|
||||||
final Collection<String> hashSetNames = DrawableAttribute.HASHSET.getValue(f);
|
final Collection<String> hashSetNames = DrawableAttribute.HASHSET.getValue(f);
|
||||||
|
|
||||||
if (hashSetNames.isEmpty() == false) {
|
if (hashSetNames.isEmpty() == false) {
|
||||||
for (String name : hashSetNames) {
|
for (String name : hashSetNames) {
|
||||||
|
|
||||||
@ -612,9 +613,9 @@ public final class DrawableDB {
|
|||||||
insertGroup(val.toString(), attr);
|
insertGroup(val.toString(), attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.addUpdatedFile(f.getId());
|
tr.addUpdatedFile(f.getId());
|
||||||
|
|
||||||
} catch (SQLException | NullPointerException ex) {
|
} catch (SQLException | NullPointerException ex) {
|
||||||
// This is one of the places where we get an error if the case is closed during processing,
|
// This is one of the places where we get an error if the case is closed during processing,
|
||||||
// which doesn't need to be reported here.
|
// which doesn't need to be reported here.
|
||||||
@ -625,38 +626,38 @@ public final class DrawableDB {
|
|||||||
dbWriteUnlock();
|
dbWriteUnlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DrawableTransaction beginTransaction() {
|
public DrawableTransaction beginTransaction() {
|
||||||
return new DrawableTransaction();
|
return new DrawableTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void commitTransaction(DrawableTransaction tr, Boolean notify) {
|
public void commitTransaction(DrawableTransaction tr, Boolean notify) {
|
||||||
if (tr.isClosed()) {
|
if (tr.isClosed()) {
|
||||||
throw new IllegalArgumentException("can't close already closed transaction");
|
throw new IllegalArgumentException("can't close already closed transaction");
|
||||||
}
|
}
|
||||||
tr.commit(notify);
|
tr.commit(notify);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addUpdatedFileListener(FileUpdateEvent.FileUpdateListener l) {
|
public void addUpdatedFileListener(FileUpdateEvent.FileUpdateListener l) {
|
||||||
updateListeners.add(l);
|
updateListeners.add(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fireUpdatedFiles(Collection<Long> fileIDs) {
|
private void fireUpdatedFiles(Collection<Long> fileIDs) {
|
||||||
for (FileUpdateEvent.FileUpdateListener listener : updateListeners) {
|
for (FileUpdateEvent.FileUpdateListener listener : updateListeners) {
|
||||||
listener.handleFileUpdate(FileUpdateEvent.newUpdateEvent(fileIDs, null));
|
listener.handleFileUpdate(FileUpdateEvent.newUpdateEvent(fileIDs, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fireRemovedFiles(Collection<Long> fileIDs) {
|
private void fireRemovedFiles(Collection<Long> fileIDs) {
|
||||||
for (FileUpdateEvent.FileUpdateListener listener : updateListeners) {
|
for (FileUpdateEvent.FileUpdateListener listener : updateListeners) {
|
||||||
listener.handleFileUpdate(FileUpdateEvent.newRemovedEvent(fileIDs));
|
listener.handleFileUpdate(FileUpdateEvent.newRemovedEvent(fileIDs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean isFileAnalyzed(DrawableFile<?> f) {
|
public Boolean isFileAnalyzed(DrawableFile<?> f) {
|
||||||
return isFileAnalyzed(f.getId());
|
return isFileAnalyzed(f.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean isFileAnalyzed(long fileId) {
|
public Boolean isFileAnalyzed(long fileId) {
|
||||||
dbReadLock();
|
dbReadLock();
|
||||||
try (Statement stmt = con.createStatement();
|
try (Statement stmt = con.createStatement();
|
||||||
@ -669,12 +670,12 @@ public final class DrawableDB {
|
|||||||
} finally {
|
} finally {
|
||||||
dbReadUnlock();
|
dbReadUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean areFilesAnalyzed(Collection<Long> fileIds) {
|
public Boolean areFilesAnalyzed(Collection<Long> fileIds) {
|
||||||
|
|
||||||
dbReadLock();
|
dbReadLock();
|
||||||
try (Statement stmt = con.createStatement();
|
try (Statement stmt = con.createStatement();
|
||||||
//Can't make this a preprared statement because of the IN ( ... )
|
//Can't make this a preprared statement because of the IN ( ... )
|
||||||
@ -687,15 +688,15 @@ public final class DrawableDB {
|
|||||||
} finally {
|
} finally {
|
||||||
dbReadUnlock();
|
dbReadUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean isGroupAnalyzed(GroupKey<?> gk) {
|
public Boolean isGroupAnalyzed(GroupKey<?> gk) {
|
||||||
dbReadLock();
|
dbReadLock();
|
||||||
try {
|
try {
|
||||||
List<Long> fileIDsInGroup = getFileIDsInGroup(gk);
|
List<Long> fileIDsInGroup = getFileIDsInGroup(gk);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// In testing, this method appears to be a lot faster than doing one large select statement
|
// In testing, this method appears to be a lot faster than doing one large select statement
|
||||||
for (Long fileID : fileIDsInGroup) {
|
for (Long fileID : fileIDsInGroup) {
|
||||||
@ -708,7 +709,7 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "problem counting analyzed files: ", ex);
|
LOGGER.log(Level.WARNING, "problem counting analyzed files: ", ex);
|
||||||
}
|
}
|
||||||
@ -862,9 +863,9 @@ public final class DrawableDB {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public <A extends Comparable<A>> List<A> findValuesForAttribute(DrawableAttribute<A> groupBy, GroupSortBy sortBy, SortOrder sortOrder) {
|
public <A extends Comparable<A>> List<A> findValuesForAttribute(DrawableAttribute<A> groupBy, GroupSortBy sortBy, SortOrder sortOrder) {
|
||||||
|
|
||||||
List<A> vals = new ArrayList<>();
|
List<A> vals = new ArrayList<>();
|
||||||
|
|
||||||
switch (groupBy.attrName) {
|
switch (groupBy.attrName) {
|
||||||
case ANALYZED:
|
case ANALYZED:
|
||||||
case CATEGORY:
|
case CATEGORY:
|
||||||
@ -876,7 +877,7 @@ public final class DrawableDB {
|
|||||||
dbReadLock();
|
dbReadLock();
|
||||||
//TODO: convert this to prepared statement
|
//TODO: convert this to prepared statement
|
||||||
StringBuilder query = new StringBuilder("select " + groupBy.attrName.toString() + ", count(*) from drawable_files group by " + groupBy.attrName.toString());
|
StringBuilder query = new StringBuilder("select " + groupBy.attrName.toString() + ", count(*) from drawable_files group by " + groupBy.attrName.toString());
|
||||||
|
|
||||||
String orderByClause = "";
|
String orderByClause = "";
|
||||||
switch (sortBy) {
|
switch (sortBy) {
|
||||||
case GROUP_BY_VALUE:
|
case GROUP_BY_VALUE:
|
||||||
@ -889,12 +890,12 @@ public final class DrawableDB {
|
|||||||
// case PRIORITY:
|
// case PRIORITY:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
query.append(orderByClause);
|
query.append(orderByClause);
|
||||||
|
|
||||||
if (orderByClause.equals("") == false) {
|
if (orderByClause.equals("") == false) {
|
||||||
String sortOrderClause = "";
|
String sortOrderClause = "";
|
||||||
|
|
||||||
switch (sortOrder) {
|
switch (sortOrder) {
|
||||||
case DESCENDING:
|
case DESCENDING:
|
||||||
sortOrderClause = " DESC";
|
sortOrderClause = " DESC";
|
||||||
@ -907,7 +908,7 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
query.append(sortOrderClause);
|
query.append(sortOrderClause);
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Statement stmt = con.createStatement();
|
try (Statement stmt = con.createStatement();
|
||||||
ResultSet valsResults = stmt.executeQuery(query.toString())) {
|
ResultSet valsResults = stmt.executeQuery(query.toString())) {
|
||||||
while (valsResults.next()) {
|
while (valsResults.next()) {
|
||||||
@ -919,13 +920,13 @@ public final class DrawableDB {
|
|||||||
dbReadUnlock();
|
dbReadUnlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return vals;
|
return vals;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insertGroup(final String value, DrawableAttribute<?> groupBy) {
|
public void insertGroup(final String value, DrawableAttribute<?> groupBy) {
|
||||||
dbWriteLock();
|
dbWriteLock();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//PreparedStatement insertGroup = con.prepareStatement("insert or replace into groups (value, attribute, seen) values (?,?,0)");
|
//PreparedStatement insertGroup = con.prepareStatement("insert or replace into groups (value, attribute, seen) values (?,?,0)");
|
||||||
insertGroupStmt.clearParameters();
|
insertGroupStmt.clearParameters();
|
||||||
@ -979,9 +980,9 @@ public final class DrawableDB {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Long> getFileIDsInGroup(GroupKey<?> groupKey) throws TskCoreException {
|
public List<Long> getFileIDsInGroup(GroupKey<?> groupKey) throws TskCoreException {
|
||||||
|
|
||||||
if (groupKey.getAttribute().isDBColumn) {
|
if (groupKey.getAttribute().isDBColumn) {
|
||||||
switch (groupKey.getAttribute().attrName) {
|
switch (groupKey.getAttribute().attrName) {
|
||||||
case CATEGORY:
|
case CATEGORY:
|
||||||
@ -995,7 +996,7 @@ public final class DrawableDB {
|
|||||||
try {
|
try {
|
||||||
PreparedStatement statement = getGroupStatment(groupKey.getAttribute());
|
PreparedStatement statement = getGroupStatment(groupKey.getAttribute());
|
||||||
statement.setObject(1, groupKey.getValue());
|
statement.setObject(1, groupKey.getValue());
|
||||||
|
|
||||||
try (ResultSet valsResults = statement.executeQuery()) {
|
try (ResultSet valsResults = statement.executeQuery()) {
|
||||||
while (valsResults.next()) {
|
while (valsResults.next()) {
|
||||||
files.add(valsResults.getLong(OBJ_ID));
|
files.add(valsResults.getLong(OBJ_ID));
|
||||||
@ -1006,10 +1007,10 @@ public final class DrawableDB {
|
|||||||
} finally {
|
} finally {
|
||||||
dbReadUnlock();
|
dbReadUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DrawableFile<?>> getFilesInGroup(GroupKey<?> key) throws TskCoreException {
|
public List<DrawableFile<?>> getFilesInGroup(GroupKey<?> key) throws TskCoreException {
|
||||||
List<DrawableFile<?>> files = new ArrayList<>();
|
List<DrawableFile<?>> files = new ArrayList<>();
|
||||||
dbReadLock();
|
dbReadLock();
|
||||||
@ -1025,9 +1026,9 @@ public final class DrawableDB {
|
|||||||
default:
|
default:
|
||||||
statement = getGroupStatment(key.getAttribute());
|
statement = getGroupStatment(key.getAttribute());
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.setObject(1, key.getValue());
|
statement.setObject(1, key.getValue());
|
||||||
|
|
||||||
try (ResultSet valsResults = statement.executeQuery()) {
|
try (ResultSet valsResults = statement.executeQuery()) {
|
||||||
while (valsResults.next()) {
|
while (valsResults.next()) {
|
||||||
files.add(getFileFromID(valsResults.getLong(OBJ_ID), valsResults.getBoolean(ANALYZED)));
|
files.add(getFileFromID(valsResults.getLong(OBJ_ID), valsResults.getBoolean(ANALYZED)));
|
||||||
@ -1038,16 +1039,16 @@ public final class DrawableDB {
|
|||||||
} finally {
|
} finally {
|
||||||
dbReadUnlock();
|
dbReadUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void closeStatements() throws SQLException {
|
private void closeStatements() throws SQLException {
|
||||||
for (PreparedStatement pStmt : preparedStatements) {
|
for (PreparedStatement pStmt : preparedStatements) {
|
||||||
pStmt.close();
|
pStmt.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DrawableFile<?>> getFilesWithCategory(Category cat) throws TskCoreException, IllegalArgumentException {
|
public List<DrawableFile<?>> getFilesWithCategory(Category cat) throws TskCoreException, IllegalArgumentException {
|
||||||
try {
|
try {
|
||||||
List<DrawableFile<?>> files = new ArrayList<>();
|
List<DrawableFile<?>> files = new ArrayList<>();
|
||||||
@ -1064,18 +1065,18 @@ public final class DrawableDB {
|
|||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private PreparedStatement getGroupStatment(DrawableAttribute<?> groupBy) {
|
private PreparedStatement getGroupStatment(DrawableAttribute<?> groupBy) {
|
||||||
return groupStatementMap.get(groupBy);
|
return groupStatementMap.get(groupBy);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int countAllFiles() {
|
public int countAllFiles() {
|
||||||
int result = -1;
|
int result = -1;
|
||||||
dbReadLock();
|
dbReadLock();
|
||||||
try (ResultSet rs = con.createStatement().executeQuery("select count(*) as COUNT from drawable_files")) {
|
try (ResultSet rs = con.createStatement().executeQuery("select count(*) as COUNT from drawable_files")) {
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
|
|
||||||
result = rs.getInt("COUNT");
|
result = rs.getInt("COUNT");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1100,7 +1101,7 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
int valsResults = 0;
|
int valsResults = 0;
|
||||||
dbWriteLock();
|
dbWriteLock();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Update the list of file IDs in memory
|
// Update the list of file IDs in memory
|
||||||
removeImageFileFromList(id);
|
removeImageFileFromList(id);
|
||||||
@ -1118,11 +1119,11 @@ public final class DrawableDB {
|
|||||||
//indicates succesfull removal of 1 file
|
//indicates succesfull removal of 1 file
|
||||||
return valsResults == 1;
|
return valsResults == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MultipleTransactionException extends IllegalStateException {
|
public class MultipleTransactionException extends IllegalStateException {
|
||||||
|
|
||||||
private static final String CANNOT_HAVE_MORE_THAN_ONE_OPEN_TRANSACTIO = "cannot have more than one open transaction";
|
private static final String CANNOT_HAVE_MORE_THAN_ONE_OPEN_TRANSACTIO = "cannot have more than one open transaction";
|
||||||
|
|
||||||
public MultipleTransactionException() {
|
public MultipleTransactionException() {
|
||||||
super(CANNOT_HAVE_MORE_THAN_ONE_OPEN_TRANSACTIO);
|
super(CANNOT_HAVE_MORE_THAN_ONE_OPEN_TRANSACTIO);
|
||||||
}
|
}
|
||||||
@ -1168,31 +1169,31 @@ public final class DrawableDB {
|
|||||||
*/
|
*/
|
||||||
@GuardedBy("fileIDlist")
|
@GuardedBy("fileIDlist")
|
||||||
private final Set<Long> fileIDsInDB = new HashSet<>();
|
private final Set<Long> fileIDsInDB = new HashSet<>();
|
||||||
|
|
||||||
public boolean isInDB(Long id) {
|
public boolean isInDB(Long id) {
|
||||||
synchronized (fileIDsInDB) {
|
synchronized (fileIDsInDB) {
|
||||||
return fileIDsInDB.contains(id);
|
return fileIDsInDB.contains(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addImageFileToList(Long id) {
|
private void addImageFileToList(Long id) {
|
||||||
synchronized (fileIDsInDB) {
|
synchronized (fileIDsInDB) {
|
||||||
fileIDsInDB.add(id);
|
fileIDsInDB.add(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeImageFileFromList(Long id) {
|
private void removeImageFileFromList(Long id) {
|
||||||
synchronized (fileIDsInDB) {
|
synchronized (fileIDsInDB) {
|
||||||
fileIDsInDB.remove(id);
|
fileIDsInDB.remove(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNumberOfImageFilesInList() {
|
public int getNumberOfImageFilesInList() {
|
||||||
synchronized (fileIDsInDB) {
|
synchronized (fileIDsInDB) {
|
||||||
return fileIDsInDB.size();
|
return fileIDsInDB.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeImageList() {
|
private void initializeImageList() {
|
||||||
synchronized (fileIDsInDB) {
|
synchronized (fileIDsInDB) {
|
||||||
dbReadLock();
|
dbReadLock();
|
||||||
@ -1214,7 +1215,7 @@ public final class DrawableDB {
|
|||||||
* For performance reasons, keep the file type in memory
|
* For performance reasons, keep the file type in memory
|
||||||
*/
|
*/
|
||||||
private final Map<AbstractFile, Boolean> videoFileMap = new ConcurrentHashMap<>();
|
private final Map<AbstractFile, Boolean> videoFileMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public boolean isVideoFile(AbstractFile f) {
|
public boolean isVideoFile(AbstractFile f) {
|
||||||
return videoFileMap.computeIfAbsent(f, ImageGalleryModule::isVideoFile);
|
return videoFileMap.computeIfAbsent(f, ImageGalleryModule::isVideoFile);
|
||||||
}
|
}
|
||||||
@ -1241,7 +1242,7 @@ public final class DrawableDB {
|
|||||||
.map(Content::getId)
|
.map(Content::getId)
|
||||||
.filter(this::isInDB)
|
.filter(this::isInDB)
|
||||||
.count();
|
.count();
|
||||||
|
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Case closed while getting files");
|
LOGGER.log(Level.WARNING, "Case closed while getting files");
|
||||||
} catch (TskCoreException ex1) {
|
} catch (TskCoreException ex1) {
|
||||||
@ -1254,11 +1255,11 @@ public final class DrawableDB {
|
|||||||
* inner class that can reference access database connection
|
* inner class that can reference access database connection
|
||||||
*/
|
*/
|
||||||
public class DrawableTransaction {
|
public class DrawableTransaction {
|
||||||
|
|
||||||
private final Set<Long> updatedFiles;
|
private final Set<Long> updatedFiles;
|
||||||
|
|
||||||
private final Set<Long> removedFiles;
|
private final Set<Long> removedFiles;
|
||||||
|
|
||||||
private boolean closed = false;
|
private boolean closed = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1277,13 +1278,13 @@ public final class DrawableDB {
|
|||||||
dbWriteLock();
|
dbWriteLock();
|
||||||
try {
|
try {
|
||||||
con.setAutoCommit(false);
|
con.setAutoCommit(false);
|
||||||
|
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "failed to set auto-commit to to false", ex);
|
LOGGER.log(Level.SEVERE, "failed to set auto-commit to to false", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized public void rollback() {
|
synchronized public void rollback() {
|
||||||
if (!closed) {
|
if (!closed) {
|
||||||
try {
|
try {
|
||||||
@ -1296,14 +1297,14 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized private void commit(Boolean notify) {
|
synchronized private void commit(Boolean notify) {
|
||||||
if (!closed) {
|
if (!closed) {
|
||||||
try {
|
try {
|
||||||
con.commit();
|
con.commit();
|
||||||
// make sure we close before we update, bc they'll need locks
|
// make sure we close before we update, bc they'll need locks
|
||||||
close();
|
close();
|
||||||
|
|
||||||
if (notify) {
|
if (notify) {
|
||||||
fireUpdatedFiles(updatedFiles);
|
fireUpdatedFiles(updatedFiles);
|
||||||
fireRemovedFiles(removedFiles);
|
fireRemovedFiles(removedFiles);
|
||||||
@ -1318,7 +1319,7 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized private void close() {
|
synchronized private void close() {
|
||||||
if (!closed) {
|
if (!closed) {
|
||||||
try {
|
try {
|
||||||
@ -1335,15 +1336,15 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized public Boolean isClosed() {
|
synchronized public Boolean isClosed() {
|
||||||
return closed;
|
return closed;
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized private void addUpdatedFile(Long f) {
|
synchronized private void addUpdatedFile(Long f) {
|
||||||
updatedFiles.add(f);
|
updatedFiles.add(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized private void addRemovedFile(long id) {
|
synchronized private void addRemovedFile(long id) {
|
||||||
removedFiles.add(id);
|
removedFiles.add(id);
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,6 @@ public class DrawableGroup implements Comparable<DrawableGroup> {
|
|||||||
if (fileIDs.contains(f) == false) {
|
if (fileIDs.contains(f) == false) {
|
||||||
fileIDs.add(f);
|
fileIDs.add(f);
|
||||||
seen.set(false);
|
seen.set(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,8 +154,8 @@ public class DrawableGroup implements Comparable<DrawableGroup> {
|
|||||||
return this.groupKey.getValueDisplayName().compareTo(other.groupKey.getValueDisplayName());
|
return this.groupKey.getValueDisplayName().compareTo(other.groupKey.getValueDisplayName());
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSeen() {
|
void setSeen(boolean isSeen) {
|
||||||
this.seen.set(true);
|
this.seen.set(isSeen);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyBooleanWrapper seenProperty() {
|
public ReadOnlyBooleanWrapper seenProperty() {
|
||||||
|
@ -245,6 +245,9 @@ public class GroupManager implements FileUpdateEvent.FileUpdateListener {
|
|||||||
List<Long> newFiles = files == null ? new ArrayList<>() : files;
|
List<Long> newFiles = files == null ? new ArrayList<>() : files;
|
||||||
|
|
||||||
DrawableGroup g = new DrawableGroup(groupKey, newFiles);
|
DrawableGroup g = new DrawableGroup(groupKey, newFiles);
|
||||||
|
g.seenProperty().addListener((observable, oldSeen, newSeen) -> {
|
||||||
|
markGroupSeen(g, newSeen);
|
||||||
|
});
|
||||||
synchronized (groupMap) {
|
synchronized (groupMap) {
|
||||||
groupMap.put(groupKey, g);
|
groupMap.put(groupKey, g);
|
||||||
}
|
}
|
||||||
@ -258,11 +261,15 @@ public class GroupManager implements FileUpdateEvent.FileUpdateListener {
|
|||||||
* @param group the {@link DrawableGroup} to mark as seen
|
* @param group the {@link DrawableGroup} to mark as seen
|
||||||
*/
|
*/
|
||||||
@ThreadConfined(type = ThreadType.JFX)
|
@ThreadConfined(type = ThreadType.JFX)
|
||||||
public void markGroupSeen(DrawableGroup group) {
|
public void markGroupSeen(DrawableGroup group, boolean seen) {
|
||||||
db.markGroupSeen(group.getGroupKey());
|
db.markGroupSeen(group.getGroupKey(), seen);
|
||||||
group.setSeen();
|
group.setSeen(seen);
|
||||||
unSeenGroups.removeAll(group);
|
if (seen) {
|
||||||
|
unSeenGroups.removeAll(group);
|
||||||
|
} else if (unSeenGroups.contains(group) == false) {
|
||||||
|
unSeenGroups.add(group);
|
||||||
|
FXCollections.sort(unSeenGroups, sortBy.getGrpComparator(sortOrder));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -324,19 +331,13 @@ public class GroupManager implements FileUpdateEvent.FileUpdateListener {
|
|||||||
|
|
||||||
if (task == null || (task.isCancelled() == false)) {
|
if (task == null || (task.isCancelled() == false)) {
|
||||||
final boolean groupSeen = db.isGroupSeen(g.getGroupKey());
|
final boolean groupSeen = db.isGroupSeen(g.getGroupKey());
|
||||||
if (groupSeen) {
|
|
||||||
g.setSeen();
|
|
||||||
}
|
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
if (analyzedGroups.contains(g) == false) {
|
if (analyzedGroups.contains(g) == false) {
|
||||||
analyzedGroups.add(g);
|
analyzedGroups.add(g);
|
||||||
}
|
}
|
||||||
if (groupSeen) {
|
markGroupSeen(g, groupSeen);
|
||||||
unSeenGroups.removeAll(g);
|
|
||||||
} else if (unSeenGroups.contains(g) == false) {
|
|
||||||
unSeenGroups.add(g);
|
|
||||||
FXCollections.sort(unSeenGroups, sortBy.getGrpComparator(sortOrder));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user