remove unneeded instance id from db cache (#1035)

* remove unneeded instance id from db cache

* fix TimelineDAOTest

* fix TimelineRepositoryTest
This commit is contained in:
Konrad Pozniak 2019-02-13 19:20:31 +01:00 committed by GitHub
parent e371fa0e24
commit 6c93555ad0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 739 additions and 37 deletions

View File

@ -0,0 +1,656 @@
{
"formatVersion": 1,
"database": {
"version": 13,
"identityHash": "9a63a3ab2c05004022c350aab0e472c0",
"entities": [
{
"tableName": "TootEntity",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `text` TEXT, `urls` TEXT, `descriptions` TEXT, `contentWarning` TEXT, `inReplyToId` TEXT, `inReplyToText` TEXT, `inReplyToUsername` TEXT, `visibility` INTEGER)",
"fields": [
{
"fieldPath": "uid",
"columnName": "uid",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "text",
"columnName": "text",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "urls",
"columnName": "urls",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "descriptions",
"columnName": "descriptions",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "contentWarning",
"columnName": "contentWarning",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "inReplyToId",
"columnName": "inReplyToId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "inReplyToText",
"columnName": "inReplyToText",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "inReplyToUsername",
"columnName": "inReplyToUsername",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "visibility",
"columnName": "visibility",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"uid"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "AccountEntity",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `defaultPostPrivacy` INTEGER NOT NULL, `defaultMediaSensitivity` INTEGER NOT NULL, `alwaysShowSensitiveMedia` INTEGER NOT NULL, `mediaPreviewEnabled` INTEGER NOT NULL, `lastNotificationId` TEXT NOT NULL, `activeNotifications` TEXT NOT NULL, `emojis` TEXT NOT NULL, `tabPreferences` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "domain",
"columnName": "domain",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "accessToken",
"columnName": "accessToken",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "isActive",
"columnName": "isActive",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "accountId",
"columnName": "accountId",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "username",
"columnName": "username",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "displayName",
"columnName": "displayName",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "profilePictureUrl",
"columnName": "profilePictureUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationsEnabled",
"columnName": "notificationsEnabled",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "notificationsMentioned",
"columnName": "notificationsMentioned",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "notificationsFollowed",
"columnName": "notificationsFollowed",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "notificationsReblogged",
"columnName": "notificationsReblogged",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "notificationsFavorited",
"columnName": "notificationsFavorited",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "notificationSound",
"columnName": "notificationSound",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "notificationVibration",
"columnName": "notificationVibration",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "notificationLight",
"columnName": "notificationLight",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "defaultPostPrivacy",
"columnName": "defaultPostPrivacy",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "defaultMediaSensitivity",
"columnName": "defaultMediaSensitivity",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "alwaysShowSensitiveMedia",
"columnName": "alwaysShowSensitiveMedia",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mediaPreviewEnabled",
"columnName": "mediaPreviewEnabled",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastNotificationId",
"columnName": "lastNotificationId",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "activeNotifications",
"columnName": "activeNotifications",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "emojis",
"columnName": "emojis",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "tabPreferences",
"columnName": "tabPreferences",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_AccountEntity_domain_accountId",
"unique": true,
"columnNames": [
"domain",
"accountId"
],
"createSql": "CREATE UNIQUE INDEX `index_AccountEntity_domain_accountId` ON `${TABLE_NAME}` (`domain`, `accountId`)"
}
],
"foreignKeys": []
},
{
"tableName": "InstanceEntity",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`instance` TEXT NOT NULL, `emojiList` TEXT, `maximumTootCharacters` INTEGER, PRIMARY KEY(`instance`))",
"fields": [
{
"fieldPath": "instance",
"columnName": "instance",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "emojiList",
"columnName": "emojiList",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "maximumTootCharacters",
"columnName": "maximumTootCharacters",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"instance"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "TimelineStatusEntity",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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 )",
"fields": [
{
"fieldPath": "serverId",
"columnName": "serverId",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "timelineUserId",
"columnName": "timelineUserId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "authorServerId",
"columnName": "authorServerId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "inReplyToId",
"columnName": "inReplyToId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "inReplyToAccountId",
"columnName": "inReplyToAccountId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "content",
"columnName": "content",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "createdAt",
"columnName": "createdAt",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "emojis",
"columnName": "emojis",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "reblogsCount",
"columnName": "reblogsCount",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "favouritesCount",
"columnName": "favouritesCount",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "reblogged",
"columnName": "reblogged",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "favourited",
"columnName": "favourited",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "sensitive",
"columnName": "sensitive",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "spoilerText",
"columnName": "spoilerText",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "visibility",
"columnName": "visibility",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachments",
"columnName": "attachments",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "mentions",
"columnName": "mentions",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "application",
"columnName": "application",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "reblogServerId",
"columnName": "reblogServerId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "reblogAccountId",
"columnName": "reblogAccountId",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"serverId",
"timelineUserId"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_TimelineStatusEntity_authorServerId_timelineUserId",
"unique": false,
"columnNames": [
"authorServerId",
"timelineUserId"
],
"createSql": "CREATE INDEX `index_TimelineStatusEntity_authorServerId_timelineUserId` ON `${TABLE_NAME}` (`authorServerId`, `timelineUserId`)"
}
],
"foreignKeys": [
{
"table": "TimelineAccountEntity",
"onDelete": "NO ACTION",
"onUpdate": "NO ACTION",
"columns": [
"authorServerId",
"timelineUserId"
],
"referencedColumns": [
"serverId",
"timelineUserId"
]
}
]
},
{
"tableName": "TimelineAccountEntity",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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`))",
"fields": [
{
"fieldPath": "serverId",
"columnName": "serverId",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "timelineUserId",
"columnName": "timelineUserId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "localUsername",
"columnName": "localUsername",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "username",
"columnName": "username",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "displayName",
"columnName": "displayName",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "avatar",
"columnName": "avatar",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "emojis",
"columnName": "emojis",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"serverId",
"timelineUserId"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "ConversationEntity",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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`))",
"fields": [
{
"fieldPath": "accountId",
"columnName": "accountId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "accounts",
"columnName": "accounts",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "unread",
"columnName": "unread",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastStatus.id",
"columnName": "s_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "lastStatus.url",
"columnName": "s_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "lastStatus.inReplyToId",
"columnName": "s_inReplyToId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "lastStatus.inReplyToAccountId",
"columnName": "s_inReplyToAccountId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "lastStatus.account",
"columnName": "s_account",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "lastStatus.content",
"columnName": "s_content",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "lastStatus.createdAt",
"columnName": "s_createdAt",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastStatus.emojis",
"columnName": "s_emojis",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "lastStatus.favouritesCount",
"columnName": "s_favouritesCount",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastStatus.favourited",
"columnName": "s_favourited",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastStatus.sensitive",
"columnName": "s_sensitive",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastStatus.spoilerText",
"columnName": "s_spoilerText",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "lastStatus.attachments",
"columnName": "s_attachments",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "lastStatus.mentions",
"columnName": "s_mentions",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "lastStatus.showingHiddenContent",
"columnName": "s_showingHiddenContent",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastStatus.expanded",
"columnName": "s_expanded",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastStatus.collapsible",
"columnName": "s_collapsible",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastStatus.collapsed",
"columnName": "s_collapsed",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id",
"accountId"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
}
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"9a63a3ab2c05004022c350aab0e472c0\")"
]
}
}

View File

@ -133,7 +133,6 @@ class TimelineDAOTest {
val author = TimelineAccountEntity( val author = TimelineAccountEntity(
authorServerId, authorServerId,
accountId, accountId,
"birb.site",
"localUsername", "localUsername",
"username", "username",
"displayName", "displayName",
@ -146,7 +145,6 @@ class TimelineDAOTest {
TimelineAccountEntity( TimelineAccountEntity(
"R$authorServerId", "R$authorServerId",
accountId, accountId,
"Rbirb.site",
"RlocalUsername", "RlocalUsername",
"Rusername", "Rusername",
"RdisplayName", "RdisplayName",
@ -163,7 +161,6 @@ class TimelineDAOTest {
url = "url$statusId", url = "url$statusId",
timelineUserId = accountId, timelineUserId = accountId,
authorServerId = authorServerId, authorServerId = authorServerId,
instance = "birb.site$statusId",
inReplyToId = "inReplyToId$statusId", inReplyToId = "inReplyToId$statusId",
inReplyToAccountId = "inReplyToAccountId$statusId", inReplyToAccountId = "inReplyToAccountId$statusId",
content = "Content!$statusId", content = "Content!$statusId",
@ -191,7 +188,6 @@ class TimelineDAOTest {
url = null, url = null,
timelineUserId = timelineUserId, timelineUserId = timelineUserId,
authorServerId = null, authorServerId = null,
instance = null,
inReplyToId = null, inReplyToId = null,
inReplyToAccountId = null, inReplyToAccountId = null,
content = null, content = null,

View File

@ -67,7 +67,7 @@ public class TuskyApplication extends Application implements HasActivityInjector
.addMigrations(AppDatabase.MIGRATION_2_3, AppDatabase.MIGRATION_3_4, AppDatabase.MIGRATION_4_5, .addMigrations(AppDatabase.MIGRATION_2_3, AppDatabase.MIGRATION_3_4, AppDatabase.MIGRATION_4_5,
AppDatabase.MIGRATION_5_6, AppDatabase.MIGRATION_6_7, AppDatabase.MIGRATION_7_8, AppDatabase.MIGRATION_5_6, AppDatabase.MIGRATION_6_7, AppDatabase.MIGRATION_7_8,
AppDatabase.MIGRATION_8_9, AppDatabase.MIGRATION_9_10, AppDatabase.MIGRATION_10_11, AppDatabase.MIGRATION_8_9, AppDatabase.MIGRATION_9_10, AppDatabase.MIGRATION_10_11,
AppDatabase.MIGRATION_11_12) AppDatabase.MIGRATION_11_12, AppDatabase.MIGRATION_12_13, AppDatabase.MIGRATION_10_13)
.build(); .build();
accountManager = new AccountManager(appDatabase); accountManager = new AccountManager(appDatabase);
serviceLocator = new ServiceLocator() { serviceLocator = new ServiceLocator() {

View File

@ -30,7 +30,7 @@ import androidx.annotation.NonNull;
@Database(entities = {TootEntity.class, AccountEntity.class, InstanceEntity.class, TimelineStatusEntity.class, @Database(entities = {TootEntity.class, AccountEntity.class, InstanceEntity.class, TimelineStatusEntity.class,
TimelineAccountEntity.class, ConversationEntity.class TimelineAccountEntity.class, ConversationEntity.class
}, version = 12) }, version = 13)
public abstract class AppDatabase extends RoomDatabase { public abstract class AppDatabase extends RoomDatabase {
public abstract TootDao tootDao(); public abstract TootDao tootDao();
@ -207,4 +207,61 @@ public abstract class AppDatabase extends RoomDatabase {
} }
}; };
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`)");
}
};
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);
}
};
} }

View File

@ -24,14 +24,14 @@ abstract class TimelineDao {
@Query(""" @Query("""
SELECT s.serverId, s.url, s.timelineUserId, SELECT s.serverId, s.url, s.timelineUserId,
s.authorServerId, s.instance, s.inReplyToId, s.inReplyToAccountId, s.createdAt, s.authorServerId, s.inReplyToId, s.inReplyToAccountId, s.createdAt,
s.emojis, s.reblogsCount, s.favouritesCount, s.reblogged, s.favourited, s.sensitive, s.emojis, s.reblogsCount, s.favouritesCount, s.reblogged, s.favourited, s.sensitive,
s.spoilerText, s.visibility, s.mentions, s.application, s.reblogServerId,s.reblogAccountId, s.spoilerText, s.visibility, s.mentions, s.application, s.reblogServerId,s.reblogAccountId,
s.content, s.attachments, s.content, s.attachments,
a.serverId as 'a_serverId', a.timelineUserId as 'a_timelineUserId', a.instance as 'a_instance', a.serverId as 'a_serverId', a.timelineUserId as 'a_timelineUserId',
a.localUsername as 'a_localUsername', a.username as 'a_username', a.localUsername as 'a_localUsername', a.username as 'a_username',
a.displayName as 'a_displayName', a.url as 'a_url', a.avatar as 'a_avatar', a.emojis as 'a_emojis', a.displayName as 'a_displayName', a.url as 'a_url', a.avatar as 'a_avatar', a.emojis as 'a_emojis',
rb.serverId as 'rb_serverId', rb.timelineUserId 'rb_timelineUserId', rb.instance as 'rb_instance', rb.serverId as 'rb_serverId', rb.timelineUserId 'rb_timelineUserId',
rb.localUsername as 'rb_localUsername', rb.username as 'rb_username', rb.localUsername as 'rb_localUsername', rb.username as 'rb_username',
rb.displayName as 'rb_displayName', rb.url as 'rb_url', rb.avatar as 'rb_avatar', rb.displayName as 'rb_displayName', rb.url as 'rb_url', rb.avatar as 'rb_avatar',
rb.emojis as'rb_emojis' rb.emojis as'rb_emojis'

View File

@ -33,7 +33,6 @@ data class TimelineStatusEntity(
// our local id for the logged in user in case there are multiple accounts per instance // our local id for the logged in user in case there are multiple accounts per instance
val timelineUserId: Long, val timelineUserId: Long,
val authorServerId: String?, val authorServerId: String?,
val instance: String?,
val inReplyToId: String?, val inReplyToId: String?,
val inReplyToAccountId: String?, val inReplyToAccountId: String?,
val content: String?, val content: String?,
@ -59,7 +58,6 @@ data class TimelineStatusEntity(
data class TimelineAccountEntity( data class TimelineAccountEntity(
val serverId: String, val serverId: String,
val timelineUserId: Long, val timelineUserId: Long,
val instance: String,
val localUsername: String, val localUsername: String,
val username: String, val username: String,
val displayName: String, val displayName: String,

View File

@ -52,23 +52,21 @@ class TimelineRepositoryImpl(
): Single<out List<TimelineStatus>> { ): Single<out List<TimelineStatus>> {
val acc = accountManager.activeAccount ?: throw IllegalStateException() val acc = accountManager.activeAccount ?: throw IllegalStateException()
val accountId = acc.id val accountId = acc.id
val instance = acc.domain
return if (requestMode == DISK) { return if (requestMode == DISK) {
this.getStatusesFromDb(accountId, maxId, sinceId, limit) this.getStatusesFromDb(accountId, maxId, sinceId, limit)
} else { } else {
getStatusesFromNetwork(maxId, sinceId, sincedIdMinusOne, limit, instance, accountId, getStatusesFromNetwork(maxId, sinceId, sincedIdMinusOne, limit, accountId, requestMode)
requestMode)
} }
} }
private fun getStatusesFromNetwork(maxId: String?, sinceId: String?, private fun getStatusesFromNetwork(maxId: String?, sinceId: String?,
sinceIdMinusOne: String?, limit: Int, instance: String, sinceIdMinusOne: String?, limit: Int,
accountId: Long, requestMode: TimelineRequestMode accountId: Long, requestMode: TimelineRequestMode
): Single<out List<TimelineStatus>> { ): Single<out List<TimelineStatus>> {
return mastodonApi.homeTimelineSingle(maxId, sinceIdMinusOne, limit + 1) return mastodonApi.homeTimelineSingle(maxId, sinceIdMinusOne, limit + 1)
.map { statuses -> .map { statuses ->
this.saveStatusesToDb(instance, accountId, statuses, maxId, sinceId) this.saveStatusesToDb(accountId, statuses, maxId, sinceId)
} }
.flatMap { statuses -> .flatMap { statuses ->
this.addFromDbIfNeeded(accountId, statuses, maxId, sinceId, limit, requestMode) this.addFromDbIfNeeded(accountId, statuses, maxId, sinceId, limit, requestMode)
@ -116,7 +114,7 @@ class TimelineRepositoryImpl(
} }
} }
private fun saveStatusesToDb(instance: String, accountId: Long, statuses: List<Status>, private fun saveStatusesToDb(accountId: Long, statuses: List<Status>,
maxId: String?, sinceId: String? maxId: String?, sinceId: String?
): List<Either<Placeholder, Status>> { ): List<Either<Placeholder, Status>> {
var placeholderToInsert: Placeholder? = null var placeholderToInsert: Placeholder? = null
@ -146,9 +144,9 @@ class TimelineRepositoryImpl(
Single.fromCallable { Single.fromCallable {
for (status in statuses) { for (status in statuses) {
timelineDao.insertInTransaction( timelineDao.insertInTransaction(
status.toEntity(accountId, instance, htmlConverter, gson), status.toEntity(accountId, htmlConverter, gson),
status.account.toEntity(instance, accountId, gson), status.account.toEntity(accountId, gson),
status.reblog?.account?.toEntity(instance, accountId, gson) status.reblog?.account?.toEntity(accountId, gson)
) )
} }
@ -279,11 +277,10 @@ class TimelineRepositoryImpl(
private val emojisListTypeToken = object : TypeToken<List<Emoji>>() {} private val emojisListTypeToken = object : TypeToken<List<Emoji>>() {}
fun Account.toEntity(instance: String, accountId: Long, gson: Gson): TimelineAccountEntity { fun Account.toEntity(accountId: Long, gson: Gson): TimelineAccountEntity {
return TimelineAccountEntity( return TimelineAccountEntity(
serverId = id, serverId = id,
timelineUserId = accountId, timelineUserId = accountId,
instance = instance,
localUsername = localUsername, localUsername = localUsername,
username = username, username = username,
displayName = displayName, displayName = displayName,
@ -320,7 +317,6 @@ fun Placeholder.toEntity(timelineUserId: Long): TimelineStatusEntity {
return TimelineStatusEntity( return TimelineStatusEntity(
serverId = this.id, serverId = this.id,
url = null, url = null,
instance = null,
timelineUserId = timelineUserId, timelineUserId = timelineUserId,
authorServerId = null, authorServerId = null,
inReplyToId = null, inReplyToId = null,
@ -344,14 +340,13 @@ fun Placeholder.toEntity(timelineUserId: Long): TimelineStatusEntity {
) )
} }
fun Status.toEntity(timelineUserId: Long, instance: String, fun Status.toEntity(timelineUserId: Long,
htmlConverter: HtmlConverter, htmlConverter: HtmlConverter,
gson: Gson): TimelineStatusEntity { gson: Gson): TimelineStatusEntity {
val actionable = actionableStatus val actionable = actionableStatus
return TimelineStatusEntity( return TimelineStatusEntity(
serverId = this.id, serverId = this.id,
url = actionable.url!!, url = actionable.url!!,
instance = instance,
timelineUserId = timelineUserId, timelineUserId = timelineUserId,
authorServerId = actionable.account.id, authorServerId = actionable.account.id,
inReplyToId = actionable.inReplyToId, inReplyToId = actionable.inReplyToId,

View File

@ -93,8 +93,8 @@ class TimelineRepositoryTest {
verify(timelineDao).insertStatusIfNotThere(Placeholder("1").toEntity(account.id)) verify(timelineDao).insertStatusIfNotThere(Placeholder("1").toEntity(account.id))
for (status in statuses) { for (status in statuses) {
verify(timelineDao).insertInTransaction( verify(timelineDao).insertInTransaction(
status.toEntity(account.id, account.domain, htmlConverter, gson), status.toEntity(account.id, htmlConverter, gson),
status.account.toEntity(account.domain, account.id, gson), status.account.toEntity(account.id, gson),
null null
) )
} }
@ -124,8 +124,8 @@ class TimelineRepositoryTest {
// We assume for now that overlapped one is inserted but it's not that important // We assume for now that overlapped one is inserted but it's not that important
for (status in response) { for (status in response) {
verify(timelineDao).insertInTransaction( verify(timelineDao).insertInTransaction(
status.toEntity(account.id, account.domain, htmlConverter, gson), status.toEntity(account.id, htmlConverter, gson),
status.account.toEntity(account.domain, account.id, gson), status.account.toEntity(account.id, gson),
null null
) )
} }
@ -153,8 +153,8 @@ class TimelineRepositoryTest {
testScheduler.advanceTimeBy(100, TimeUnit.SECONDS) testScheduler.advanceTimeBy(100, TimeUnit.SECONDS)
for (status in response) { for (status in response) {
verify(timelineDao).insertInTransaction( verify(timelineDao).insertInTransaction(
status.toEntity(account.id, account.domain, htmlConverter, gson), status.toEntity(account.id, htmlConverter, gson),
status.account.toEntity(account.domain, account.id, gson), status.account.toEntity(account.id, gson),
null null
) )
} }
@ -194,8 +194,8 @@ class TimelineRepositoryTest {
// We assume for now that overlapped one is inserted but it's not that important // We assume for now that overlapped one is inserted but it's not that important
for (status in response) { for (status in response) {
verify(timelineDao).insertInTransaction( verify(timelineDao).insertInTransaction(
status.toEntity(account.id, account.domain, htmlConverter, gson), status.toEntity(account.id, htmlConverter, gson),
status.account.toEntity(account.domain, account.id, gson), status.account.toEntity(account.id, gson),
null null
) )
} }
@ -236,8 +236,8 @@ class TimelineRepositoryTest {
// We assume for now that overlapped one is inserted but it's not that important // We assume for now that overlapped one is inserted but it's not that important
for (status in response) { for (status in response) {
verify(timelineDao).insertInTransaction( verify(timelineDao).insertInTransaction(
status.toEntity(account.id, account.domain, htmlConverter, gson), status.toEntity(account.id, htmlConverter, gson),
status.account.toEntity(account.domain, account.id, gson), status.account.toEntity(account.id, gson),
null null
) )
} }
@ -253,8 +253,8 @@ class TimelineRepositoryTest {
val status = makeStatus("2") val status = makeStatus("2")
val dbStatus = makeStatus("1") val dbStatus = makeStatus("1")
val dbResult = TimelineStatusWithAccount() val dbResult = TimelineStatusWithAccount()
dbResult.status = dbStatus.toEntity(account.id, account.domain, htmlConverter, gson) dbResult.status = dbStatus.toEntity(account.id, htmlConverter, gson)
dbResult.account = status.account.toEntity(account.domain, account.id, gson) dbResult.account = status.account.toEntity(account.id, gson)
whenever(mastodonApi.homeTimelineSingle(any(), any(), any())) whenever(mastodonApi.homeTimelineSingle(any(), any(), any()))
.thenReturn(Single.just(listOf(status))) .thenReturn(Single.just(listOf(status)))