2017-11-16 19:18:11 +01:00
/ * Copyright 2017 Andrew Dawson
*
* This file is a part of Tusky .
*
* This program is free software ; you can redistribute it and / or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation ; either version 3 of the
* License , or ( at your option ) any later version .
*
* Tusky is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU General
* Public License for more details .
*
* You should have received a copy of the GNU General Public License along with Tusky ; if not ,
* see < http : //www.gnu.org/licenses>. */
2017-06-28 19:33:20 +02:00
package com.keylesspalace.tusky.db ;
2019-02-12 19:22:37 +01:00
import com.keylesspalace.tusky.TabDataKt ;
import com.keylesspalace.tusky.components.conversation.ConversationEntity ;
2018-12-17 15:25:35 +01:00
import androidx.sqlite.db.SupportSQLiteDatabase ;
import androidx.room.Database ;
import androidx.room.RoomDatabase ;
import androidx.room.migration.Migration ;
import androidx.annotation.NonNull ;
2017-06-28 19:33:20 +02:00
/ * *
2017-06-29 12:03:44 +02:00
* DB version & declare DAO
2017-06-28 19:33:20 +02:00
* /
2019-02-12 19:22:37 +01:00
@Database ( entities = { TootEntity . class , AccountEntity . class , InstanceEntity . class , TimelineStatusEntity . class ,
TimelineAccountEntity . class , ConversationEntity . class
2019-04-09 19:13:54 +02:00
} , version = 14 )
2017-07-05 16:36:14 +02:00
public abstract class AppDatabase extends RoomDatabase {
2017-06-28 19:33:20 +02:00
public abstract TootDao tootDao ( ) ;
2018-02-03 22:45:14 +01:00
public abstract AccountDao accountDao ( ) ;
2018-04-22 10:35:46 +02:00
public abstract InstanceDao instanceDao ( ) ;
2019-02-12 19:22:37 +01:00
public abstract ConversationsDao conversationDao ( ) ;
Caching toots (#809)
* Initial timeline cache implementation
* Fix build/DI errors for caching
* Rename timeline entities tables. Add migration. Add DB scheme file.
* Fix uniqueness problem, change offline strategy, improve mapping
* Try to merge in new statuses, fix bottom loading, fix saving spans.
* Fix reblogs IDs, fix inserting elements from top
* Send one more request to get latest timeline statuses
* Give Timeline placeholders string id. Rewrite Either in Kotlin
* Initial placeholder implementation for caching
* Fix crash on removing overlap statuses
* Migrate counters to long
* Remove unused counters. Add minimal TimelineDAOTest
* Fix bug with placeholder ID
* Update cache in response to events. Refactor TimelineCases
* Fix crash, reduce number of placeholders
* Fix crash, fix filtering, improve placeholder handling
* Fix migration, add 8-9 migration test
* Fix initial timeline update, remove more placeholders
* Add cleanup for old statuses
* Fix cleanup
* Delete ExampleInstrumentedTest
* Improve timeline UX regarding caching
* Fix typos
* Fix initial timeline update
* Cleanup/fix initial timeline update
* Workaround for weird behavior of first post on initial tl update.
* Change counter types back to int
* Clear timeline cache on logout
* Fix loading when timeline is completely empty
* Fix androidx migration issues
* Fix tests
* Apply caching feedback
* Save account emojis to cache
* Fix warnings and bugs
2019-01-14 22:05:08 +01:00
public abstract TimelineDao timelineDao ( ) ;
2017-10-23 21:50:41 +02:00
public static final Migration MIGRATION_2_3 = new Migration ( 2 , 3 ) {
@Override
2017-11-16 19:18:11 +01:00
public void migrate ( @NonNull SupportSQLiteDatabase database ) {
2017-10-23 21:50:41 +02:00
database . execSQL ( " CREATE TABLE TootEntity2 (uid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, text TEXT, urls TEXT, contentWarning TEXT); " ) ;
database . execSQL ( " INSERT INTO TootEntity2 SELECT * FROM TootEntity; " ) ;
database . execSQL ( " DROP TABLE TootEntity; " ) ;
database . execSQL ( " ALTER TABLE TootEntity2 RENAME TO TootEntity; " ) ;
}
} ;
2017-11-16 19:18:11 +01:00
public static final Migration MIGRATION_3_4 = new Migration ( 3 , 4 ) {
@Override
public void migrate ( @NonNull SupportSQLiteDatabase database ) {
database . execSQL ( " ALTER TABLE TootEntity ADD COLUMN inReplyToId TEXT " ) ;
database . execSQL ( " ALTER TABLE TootEntity ADD COLUMN inReplyToText TEXT " ) ;
database . execSQL ( " ALTER TABLE TootEntity ADD COLUMN inReplyToUsername TEXT " ) ;
database . execSQL ( " ALTER TABLE TootEntity ADD COLUMN visibility INTEGER " ) ;
}
} ;
2018-02-04 10:12:01 +01:00
public static final Migration MIGRATION_4_5 = new Migration ( 4 , 5 ) {
@Override
public void migrate ( @NonNull SupportSQLiteDatabase database ) {
database . execSQL ( " CREATE TABLE `AccountEntity` ( " +
" `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
" `domain` TEXT NOT NULL, `accessToken` TEXT NOT NULL, " +
" `isActive` INTEGER NOT NULL, `accountId` TEXT NOT NULL, " +
" `username` TEXT NOT NULL, `displayName` TEXT NOT NULL, " +
" `profilePictureUrl` TEXT NOT NULL, " +
" `notificationsEnabled` INTEGER NOT NULL, " +
" `notificationsMentioned` INTEGER NOT NULL, " +
" `notificationsFollowed` INTEGER NOT NULL, " +
" `notificationsReblogged` INTEGER NOT NULL, " +
" `notificationsFavorited` INTEGER NOT NULL, " +
" `notificationSound` INTEGER NOT NULL, " +
" `notificationVibration` INTEGER NOT NULL, " +
" `notificationLight` INTEGER NOT NULL, " +
" `lastNotificationId` TEXT NOT NULL, " +
" `activeNotifications` TEXT NOT NULL) " ) ;
database . execSQL ( " CREATE UNIQUE INDEX `index_AccountEntity_domain_accountId` ON `AccountEntity` (`domain`, `accountId`) " ) ;
}
} ;
2018-04-13 22:37:21 +02:00
public static final Migration MIGRATION_5_6 = new Migration ( 5 , 6 ) {
@Override
public void migrate ( @NonNull SupportSQLiteDatabase database ) {
database . execSQL ( " CREATE TABLE IF NOT EXISTS `EmojiListEntity` (`instance` TEXT NOT NULL, `emojiList` TEXT NOT NULL, PRIMARY KEY(`instance`)) " ) ;
}
} ;
2018-04-22 10:35:46 +02:00
public static final Migration MIGRATION_6_7 = new Migration ( 6 , 7 ) {
@Override
public void migrate ( @NonNull SupportSQLiteDatabase database ) {
database . execSQL ( " CREATE TABLE IF NOT EXISTS `InstanceEntity` (`instance` TEXT NOT NULL, `emojiList` TEXT, `maximumTootCharacters` INTEGER, PRIMARY KEY(`instance`)) " ) ;
2018-07-30 15:43:27 +02:00
database . execSQL ( " INSERT OR REPLACE INTO `InstanceEntity` SELECT `instance`,`emojiList`, NULL FROM `EmojiListEntity`; " ) ;
2018-04-22 10:35:46 +02:00
database . execSQL ( " DROP TABLE `EmojiListEntity`; " ) ;
}
} ;
2018-07-30 15:43:27 +02:00
public static final Migration MIGRATION_7_8 = new Migration ( 7 , 8 ) {
@Override
public void migrate ( @NonNull SupportSQLiteDatabase database ) {
database . execSQL ( " ALTER TABLE `AccountEntity` ADD COLUMN `emojis` TEXT NOT NULL DEFAULT '[]' " ) ;
}
} ;
2018-11-11 19:25:45 +01:00
public static final Migration MIGRATION_8_9 = new Migration ( 8 , 9 ) {
@Override
public void migrate ( @NonNull SupportSQLiteDatabase database ) {
database . execSQL ( " ALTER TABLE `TootEntity` ADD COLUMN `descriptions` TEXT DEFAULT '[]' " ) ;
}
} ;
2018-11-12 21:09:39 +01:00
public static final Migration MIGRATION_9_10 = new Migration ( 9 , 10 ) {
@Override
public void migrate ( @NonNull SupportSQLiteDatabase database ) {
database . execSQL ( " ALTER TABLE `AccountEntity` ADD COLUMN `defaultPostPrivacy` INTEGER NOT NULL DEFAULT 1 " ) ;
database . execSQL ( " ALTER TABLE `AccountEntity` ADD COLUMN `defaultMediaSensitivity` INTEGER NOT NULL DEFAULT 0 " ) ;
database . execSQL ( " ALTER TABLE `AccountEntity` ADD COLUMN `alwaysShowSensitiveMedia` INTEGER NOT NULL DEFAULT 0 " ) ;
database . execSQL ( " ALTER TABLE `AccountEntity` ADD COLUMN `mediaPreviewEnabled` INTEGER NOT NULL DEFAULT '1' " ) ;
}
} ;
Caching toots (#809)
* Initial timeline cache implementation
* Fix build/DI errors for caching
* Rename timeline entities tables. Add migration. Add DB scheme file.
* Fix uniqueness problem, change offline strategy, improve mapping
* Try to merge in new statuses, fix bottom loading, fix saving spans.
* Fix reblogs IDs, fix inserting elements from top
* Send one more request to get latest timeline statuses
* Give Timeline placeholders string id. Rewrite Either in Kotlin
* Initial placeholder implementation for caching
* Fix crash on removing overlap statuses
* Migrate counters to long
* Remove unused counters. Add minimal TimelineDAOTest
* Fix bug with placeholder ID
* Update cache in response to events. Refactor TimelineCases
* Fix crash, reduce number of placeholders
* Fix crash, fix filtering, improve placeholder handling
* Fix migration, add 8-9 migration test
* Fix initial timeline update, remove more placeholders
* Add cleanup for old statuses
* Fix cleanup
* Delete ExampleInstrumentedTest
* Improve timeline UX regarding caching
* Fix typos
* Fix initial timeline update
* Cleanup/fix initial timeline update
* Workaround for weird behavior of first post on initial tl update.
* Change counter types back to int
* Clear timeline cache on logout
* Fix loading when timeline is completely empty
* Fix androidx migration issues
* Fix tests
* Apply caching feedback
* Save account emojis to cache
* Fix warnings and bugs
2019-01-14 22:05:08 +01:00
public static final Migration MIGRATION_10_11 = new Migration ( 10 , 11 ) {
@Override
public void migrate ( @NonNull SupportSQLiteDatabase database ) {
database . execSQL ( " CREATE TABLE IF NOT EXISTS `TimelineAccountEntity` ( " +
" `serverId` TEXT NOT NULL, " +
" `timelineUserId` INTEGER NOT NULL, " +
" `instance` TEXT NOT NULL, " +
" `localUsername` TEXT NOT NULL, " +
" `username` TEXT NOT NULL, " +
" `displayName` TEXT NOT NULL, " +
" `url` TEXT NOT NULL, " +
" `avatar` TEXT NOT NULL, " +
" `emojis` TEXT NOT NULL, " +
" PRIMARY KEY(`serverId`, `timelineUserId`)) " ) ;
database . execSQL ( " CREATE TABLE IF NOT EXISTS `TimelineStatusEntity` ( " +
" `serverId` TEXT NOT NULL, " +
" `url` TEXT, " +
" `timelineUserId` INTEGER NOT NULL, " +
" `authorServerId` TEXT, " +
" `instance` TEXT, " +
" `inReplyToId` TEXT, " +
" `inReplyToAccountId` TEXT, " +
" `content` TEXT, " +
" `createdAt` INTEGER NOT NULL, " +
" `emojis` TEXT, " +
" `reblogsCount` INTEGER NOT NULL, " +
" `favouritesCount` INTEGER NOT NULL, " +
" `reblogged` INTEGER NOT NULL, " +
" `favourited` INTEGER NOT NULL, " +
" `sensitive` INTEGER NOT NULL, " +
" `spoilerText` TEXT, " +
" `visibility` INTEGER, " +
" `attachments` TEXT, " +
" `mentions` TEXT, " +
" `application` TEXT, " +
" `reblogServerId` TEXT, " +
" `reblogAccountId` TEXT, " +
" PRIMARY KEY(`serverId`, `timelineUserId`), " +
" FOREIGN KEY(`authorServerId`, `timelineUserId`) REFERENCES `TimelineAccountEntity`(`serverId`, `timelineUserId`) " +
" ON UPDATE NO ACTION ON DELETE NO ACTION ) " ) ;
database . execSQL ( " CREATE INDEX IF NOT EXISTS " +
" `index_TimelineStatusEntity_authorServerId_timelineUserId` " +
" ON `TimelineStatusEntity` (`authorServerId`, `timelineUserId`) " ) ;
}
} ;
2019-02-12 19:22:37 +01:00
public static final Migration MIGRATION_11_12 = new Migration ( 11 , 12 ) {
@Override
public void migrate ( @NonNull SupportSQLiteDatabase database ) {
String defaultTabs = TabDataKt . HOME + " ; " +
TabDataKt . NOTIFICATIONS + " ; " +
TabDataKt . LOCAL + " ; " +
TabDataKt . FEDERATED ;
database . execSQL ( " ALTER TABLE `AccountEntity` ADD COLUMN `tabPreferences` TEXT NOT NULL DEFAULT ' " + defaultTabs + " ' " ) ;
database . execSQL ( " CREATE TABLE IF NOT EXISTS `ConversationEntity` ( " +
" `accountId` INTEGER NOT NULL, " +
" `id` TEXT NOT NULL, " +
" `accounts` TEXT NOT NULL, " +
" `unread` INTEGER NOT NULL, " +
" `s_id` TEXT NOT NULL, " +
" `s_url` TEXT, " +
" `s_inReplyToId` TEXT, " +
" `s_inReplyToAccountId` TEXT, " +
" `s_account` TEXT NOT NULL, " +
" `s_content` TEXT NOT NULL, " +
" `s_createdAt` INTEGER NOT NULL, " +
" `s_emojis` TEXT NOT NULL, " +
" `s_favouritesCount` INTEGER NOT NULL, " +
" `s_favourited` INTEGER NOT NULL, " +
" `s_sensitive` INTEGER NOT NULL, " +
" `s_spoilerText` TEXT NOT NULL, " +
" `s_attachments` TEXT NOT NULL, " +
" `s_mentions` TEXT NOT NULL, " +
" `s_showingHiddenContent` INTEGER NOT NULL, " +
" `s_expanded` INTEGER NOT NULL, " +
" `s_collapsible` INTEGER NOT NULL, " +
" `s_collapsed` INTEGER NOT NULL, " +
" PRIMARY KEY(`id`, `accountId`)) " ) ;
}
} ;
2019-02-13 19:20:31 +01:00
public static final Migration MIGRATION_12_13 = new Migration ( 12 , 13 ) {
@Override
public void migrate ( @NonNull SupportSQLiteDatabase database ) {
database . execSQL ( " DROP TABLE IF EXISTS `TimelineAccountEntity` " ) ;
database . execSQL ( " DROP TABLE IF EXISTS `TimelineStatusEntity` " ) ;
database . execSQL ( " CREATE TABLE IF NOT EXISTS `TimelineAccountEntity` ( " +
" `serverId` TEXT NOT NULL, " +
" `timelineUserId` INTEGER NOT NULL, " +
" `localUsername` TEXT NOT NULL, " +
" `username` TEXT NOT NULL, " +
" `displayName` TEXT NOT NULL, " +
" `url` TEXT NOT NULL, " +
" `avatar` TEXT NOT NULL, " +
" `emojis` TEXT NOT NULL, " +
" PRIMARY KEY(`serverId`, `timelineUserId`)) " ) ;
database . execSQL ( " CREATE TABLE IF NOT EXISTS `TimelineStatusEntity` ( " +
" `serverId` TEXT NOT NULL, " +
" `url` TEXT, " +
" `timelineUserId` INTEGER NOT NULL, " +
" `authorServerId` TEXT, " +
" `inReplyToId` TEXT, " +
" `inReplyToAccountId` TEXT, " +
" `content` TEXT, " +
" `createdAt` INTEGER NOT NULL, " +
" `emojis` TEXT, " +
" `reblogsCount` INTEGER NOT NULL, " +
" `favouritesCount` INTEGER NOT NULL, " +
" `reblogged` INTEGER NOT NULL, " +
" `favourited` INTEGER NOT NULL, " +
" `sensitive` INTEGER NOT NULL, " +
" `spoilerText` TEXT, " +
" `visibility` INTEGER, " +
" `attachments` TEXT, " +
" `mentions` TEXT, " +
" `application` TEXT, " +
" `reblogServerId` TEXT, " +
" `reblogAccountId` TEXT, " +
" PRIMARY KEY(`serverId`, `timelineUserId`), " +
" FOREIGN KEY(`authorServerId`, `timelineUserId`) REFERENCES `TimelineAccountEntity`(`serverId`, `timelineUserId`) " +
" ON UPDATE NO ACTION ON DELETE NO ACTION ) " ) ;
database . execSQL ( " CREATE INDEX IF NOT EXISTS " +
" `index_TimelineStatusEntity_authorServerId_timelineUserId` " +
" ON `TimelineStatusEntity` (`authorServerId`, `timelineUserId`) " ) ;
}
} ;
2019-04-09 19:13:54 +02:00
public static final Migration MIGRATION_13_14 = new Migration ( 13 , 14 ) {
@Override
public void migrate ( @NonNull SupportSQLiteDatabase database ) {
database . execSQL ( " ALTER TABLE `AccountEntity` ADD COLUMN `notificationsFilter` TEXT NOT NULL DEFAULT '[]' " ) ;
}
} ;
2019-02-13 19:20:31 +01:00
public static final Migration MIGRATION_10_13 = new Migration ( 10 , 13 ) {
@Override
public void migrate ( @NonNull SupportSQLiteDatabase database ) {
MIGRATION_11_12 . migrate ( database ) ;
MIGRATION_12_13 . migrate ( database ) ;
}
} ;
2017-10-23 21:50:41 +02:00
}