summaryrefslogtreecommitdiff
path: root/app/src/main/java/org/terst/feedreader/data/Daos.kt
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/org/terst/feedreader/data/Daos.kt')
-rw-r--r--app/src/main/java/org/terst/feedreader/data/Daos.kt42
1 files changed, 42 insertions, 0 deletions
diff --git a/app/src/main/java/org/terst/feedreader/data/Daos.kt b/app/src/main/java/org/terst/feedreader/data/Daos.kt
index 8a5f50e..ecaac43 100644
--- a/app/src/main/java/org/terst/feedreader/data/Daos.kt
+++ b/app/src/main/java/org/terst/feedreader/data/Daos.kt
@@ -22,13 +22,55 @@ interface FeedDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun upsert(feed: FeedEntity)
+ // Batched, not one upsert() call per feed in a loop: an OPML import can realistically
+ // be 100+ feeds (this app has seen a 107-feed subscription list in the wild -- see
+ // AppDatabase's v9 migration comments), and a per-feed getById()+upsert() pair is 2N
+ // sequential suspend DB round-trips for N feeds. One @Insert(REPLACE) call covers the
+ // whole list.
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun upsertAll(feeds: List<FeedEntity>)
+
@Update
suspend fun update(feed: FeedEntity)
+ // Targeted, not the full-row @Update above: FeedFetchWorker reads every subscribed
+ // feed once at the start of a fetch cycle, then (after a per-feed network round-trip
+ // that can take a while, especially across 100+ feeds) writes back a `.copy()` of
+ // that now-possibly-stale snapshot. If the user toggles readerModeEnabled or edits a
+ // feed's folder via FeedListScreen while that feed's fetch is still in flight, a
+ // full-row update() overwrites the WHOLE row from the stale pre-fetch copy --
+ // including the field the user just changed -- silently reverting their edit. This
+ // only ever touches the columns a fetch actually produces, so it can't clobber
+ // anything the user might be changing concurrently.
+ @Query(
+ "UPDATE feeds SET title = :title, siteUrl = :siteUrl, lastFetchedAt = :lastFetchedAt, " +
+ "etag = :etag, lastModified = :lastModified, lastError = :lastError WHERE id = :id"
+ )
+ suspend fun updateFetchResult(
+ id: String,
+ title: String,
+ siteUrl: String?,
+ lastFetchedAt: Long,
+ etag: String?,
+ lastModified: String?,
+ lastError: String?
+ )
+
@Query("DELETE FROM feeds WHERE id = :id")
suspend fun delete(id: String)
}
+// Persists the toggle and returns the exact confirmation-snackbar text, shared by
+// FeedListScreen's per-row toggle and ReaderScreen's toggleFeedReaderMode (which layers
+// its own extraction logic around this same persist-and-message step) -- previously two
+// independently-typed copies of "Reader mode enabled/disabled for $label", one edit away
+// from silently drifting to say different things for the same action.
+suspend fun FeedDao.setReaderModeEnabled(feed: FeedEntity, enabled: Boolean): String {
+ update(feed.copy(readerModeEnabled = enabled))
+ val label = feed.title.ifBlank { "this feed" }
+ return if (enabled) "Reader mode enabled for $label" else "Reader mode disabled for $label"
+}
+
data class FeedUnreadCount(val feedId: String, val count: Int)
// A projection excluding feedContentHtml/extractedContent -- the potentially