diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentDatabase.java index 0384e0bd4..539e34402 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentDatabase.java @@ -122,7 +122,7 @@ public class AttachmentDatabase extends Database { static final String WIDTH = "width"; static final String HEIGHT = "height"; static final String CAPTION = "caption"; - private static final String DATA_HASH = "data_hash"; + static final String DATA_HASH = "data_hash"; static final String VISUAL_HASH = "blur_hash"; static final String TRANSFORM_PROPERTIES = "transform_properties"; static final String DISPLAY_ORDER = "display_order"; @@ -496,14 +496,20 @@ public class AttachmentDatabase extends Database { database.beginTransaction(); try { for (AttachmentId weakReference : removableWeakReferences) { - Log.i(TAG, String.format("[deleteAttachmentOnDisk] Deleting weak reference for %s %s", data, weakReference)); - deletedCount += database.delete(TABLE_NAME, PART_ID_WHERE, weakReference.toStrings()); + Log.i(TAG, String.format("[deleteAttachmentOnDisk] Clearing weak reference for %s %s", data, weakReference)); + ContentValues values = new ContentValues(); + values.putNull(DATA); + values.putNull(DATA_RANDOM); + values.putNull(DATA_HASH); + values.putNull(THUMBNAIL); + values.putNull(THUMBNAIL_RANDOM); + deletedCount += database.update(TABLE_NAME, values, PART_ID_WHERE, weakReference.toStrings()); } database.setTransactionSuccessful(); } finally { database.endTransaction(); } - String logMessage = String.format(Locale.US, "[deleteAttachmentOnDisk] Deleted %d/%d weak references for %s", deletedCount, removableWeakReferences.size(), data); + String logMessage = String.format(Locale.US, "[deleteAttachmentOnDisk] Cleared %d/%d weak references for %s", deletedCount, removableWeakReferences.size(), data); if (deletedCount != removableWeakReferences.size()) { Log.w(TAG, logMessage); } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MediaDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MediaDatabase.java index 534822788..f6e8a1d0b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MediaDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MediaDatabase.java @@ -65,7 +65,7 @@ public class MediaDatabase extends Database { + " WHERE " + MmsDatabase.THREAD_ID + " __EQUALITY__ ?) AND (%s) AND " + MmsDatabase.VIEW_ONCE + " = 0 AND " + AttachmentDatabase.DATA + " IS NOT NULL AND " - + AttachmentDatabase.QUOTE + " = 0 AND " + + "(" + AttachmentDatabase.QUOTE + " = 0 OR (" + AttachmentDatabase.QUOTE + " = 1 AND " + AttachmentDatabase.DATA_HASH + " IS NULL)) AND " + AttachmentDatabase.STICKER_PACK_ID + " IS NULL "; private static final String UNIQUE_MEDIA_QUERY = "SELECT " diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java index 7a40e38d0..fb0d1c755 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java @@ -137,8 +137,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { private static final int LAST_SCROLLED = 62; private static final int LAST_PROFILE_FETCH = 63; private static final int SERVER_DELIVERED_TIMESTAMP = 64; + private static final int QUOTE_CLEANUP = 65; - private static final int DATABASE_VERSION = 64; + private static final int DATABASE_VERSION = 65; private static final String DATABASE_NAME = "signal.db"; private final Context context; @@ -921,6 +922,39 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { db.execSQL("ALTER TABLE push ADD COLUMN server_delivered_timestamp INTEGER DEFAULT 0"); } + if (oldVersion < QUOTE_CLEANUP) { + String query = "SELECT _data " + + "FROM (SELECT _data, MIN(quote) AS all_quotes " + + "FROM part " + + "WHERE _data NOT NULL AND data_hash NOT NULL " + + "GROUP BY _data) " + + "WHERE all_quotes = 1"; + + int count = 0; + + try (Cursor cursor = db.rawQuery(query, null)) { + while (cursor != null && cursor.moveToNext()) { + String data = cursor.getString(cursor.getColumnIndexOrThrow("_data")); + + if (new File(data).delete()) { + ContentValues values = new ContentValues(); + values.putNull("_data"); + values.putNull("data_random"); + values.putNull("thumbnail"); + values.putNull("thumbnail_random"); + values.putNull("data_hash"); + db.update("part", values, "_data = ?", new String[] { data }); + + count++; + } else { + Log.w(TAG, "[QuoteCleanup] Failed to delete " + data); + } + } + } + + Log.i(TAG, "[QuoteCleanup] Cleaned up " + count + " quotes."); + } + db.setTransactionSuccessful(); } finally { db.endTransaction();