aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/src/androidTest/kotlin/com/pitchedapps/frost/db/CacheDbTest.kt32
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/db/CacheDb.kt38
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/db/NotificationDb.kt2
-rw-r--r--app/src/schemas/com.pitchedapps.frost.db.FrostPrivateDatabase/1.json29
4 files changed, 86 insertions, 15 deletions
diff --git a/app/src/androidTest/kotlin/com/pitchedapps/frost/db/CacheDbTest.kt b/app/src/androidTest/kotlin/com/pitchedapps/frost/db/CacheDbTest.kt
new file mode 100644
index 00000000..780bbd3e
--- /dev/null
+++ b/app/src/androidTest/kotlin/com/pitchedapps/frost/db/CacheDbTest.kt
@@ -0,0 +1,32 @@
+package com.pitchedapps.frost.db
+
+import kotlinx.coroutines.runBlocking
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
+import kotlin.test.fail
+
+class CacheDbTest : BaseDbTest() {
+
+ private val dao get() = db.cacheDao()
+ private val cookieDao get() = db.cookieDao()
+
+ private fun cookie(id: Long) = CookieEntity(id, "name$id", "cookie$id")
+
+ @Test
+ fun save() {
+ val cookie = cookie(1L)
+ val type = "test"
+ val content = "long test".repeat(10000)
+ runBlocking {
+ cookieDao.insertCookie(cookie)
+ dao.save(cookie.id, type, content)
+ val cache = dao.select(cookie.id, type) ?: fail("Cache not found")
+ assertEquals(content, cache.contents, "Content mismatch")
+ assertTrue(
+ System.currentTimeMillis() - cache.lastUpdated < 500,
+ "Cache retrieval took over 500ms (${System.currentTimeMillis() - cache.lastUpdated})"
+ )
+ }
+ }
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/db/CacheDb.kt b/app/src/main/kotlin/com/pitchedapps/frost/db/CacheDb.kt
index 4d6bc938..8c3c9c6b 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/db/CacheDb.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/db/CacheDb.kt
@@ -19,9 +19,11 @@ package com.pitchedapps.frost.db
import android.os.Parcelable
import androidx.room.Dao
import androidx.room.Entity
+import androidx.room.ForeignKey
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
+import com.pitchedapps.frost.utils.L
import kotlinx.android.parcel.Parcelize
/**
@@ -31,11 +33,20 @@ import kotlinx.android.parcel.Parcelize
/**
* Generic cache to store serialized content
*/
-@Entity(tableName = "frost_cache")
+@Entity(
+ tableName = "frost_cache",
+ primaryKeys = ["id", "type"],
+ foreignKeys = [ForeignKey(
+ entity = CookieEntity::class,
+ parentColumns = ["cookie_id"],
+ childColumns = ["id"],
+ onDelete = ForeignKey.CASCADE
+ )]
+)
@Parcelize
data class CacheEntity(
- @androidx.room.PrimaryKey
- val id: String,
+ val id: Long,
+ val type: String,
val lastUpdated: Long,
val contents: String
) : Parcelable
@@ -43,15 +54,24 @@ data class CacheEntity(
@Dao
interface CacheDao {
- @Query("SELECT * FROM frost_cache WHERE id = :id")
- suspend fun selectById(id: Long): CacheEntity?
+ @Query("SELECT * FROM frost_cache WHERE id = :id AND type = :type")
+ suspend fun select(id: Long, type: String): CacheEntity?
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertCache(cache: CacheEntity)
- @Query("DELETE FROM frost_cache WHERE id = :id")
- suspend fun deleteById(id: Long)
+ @Query("DELETE FROM frost_cache WHERE id = :id AND type = :type")
+ suspend fun delete(id: Long, type: String)
}
-suspend fun CacheDao.save(id: String, contents: String) =
- insertCache(CacheEntity(id, System.currentTimeMillis(), contents)) \ No newline at end of file
+/**
+ * Returns true if successful, given that there are constraints to the insertion
+ */
+suspend fun CacheDao.save(id: Long, type: String, contents: String): Boolean =
+ try {
+ insertCache(CacheEntity(id, type, System.currentTimeMillis(), contents))
+ true
+ } catch (e: Exception) {
+ L.e(e) { "Cache save failed for $type" }
+ false
+ } \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/db/NotificationDb.kt b/app/src/main/kotlin/com/pitchedapps/frost/db/NotificationDb.kt
index 7f41fbf8..d2771754 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/db/NotificationDb.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/db/NotificationDb.kt
@@ -146,7 +146,7 @@ suspend fun NotificationDao.saveNotifications(type: String, notifs: List<Notific
_saveNotifications(type, notifs)
true
} catch (e: Exception) {
- L.e(e) { "Notif save failed" }
+ L.e(e) { "Notif save failed for $type" }
false
}
}
diff --git a/app/src/schemas/com.pitchedapps.frost.db.FrostPrivateDatabase/1.json b/app/src/schemas/com.pitchedapps.frost.db.FrostPrivateDatabase/1.json
index 72b86db3..60d5cddd 100644
--- a/app/src/schemas/com.pitchedapps.frost.db.FrostPrivateDatabase/1.json
+++ b/app/src/schemas/com.pitchedapps.frost.db.FrostPrivateDatabase/1.json
@@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 1,
- "identityHash": "099ffebd0f0fe80199c0f6413a549ebb",
+ "identityHash": "0a9d994786b7e07fea95c11d9210ce0e",
"entities": [
{
"tableName": "cookies",
@@ -130,11 +130,17 @@
},
{
"tableName": "frost_cache",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `lastUpdated` INTEGER NOT NULL, `contents` TEXT NOT NULL, PRIMARY KEY(`id`))",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `type` TEXT NOT NULL, `lastUpdated` INTEGER NOT NULL, `contents` TEXT NOT NULL, PRIMARY KEY(`id`, `type`), FOREIGN KEY(`id`) REFERENCES `cookies`(`cookie_id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
"affinity": "TEXT",
"notNull": true
},
@@ -153,18 +159,31 @@
],
"primaryKey": {
"columnNames": [
- "id"
+ "id",
+ "type"
],
"autoGenerate": false
},
"indices": [],
- "foreignKeys": []
+ "foreignKeys": [
+ {
+ "table": "cookies",
+ "onDelete": "CASCADE",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "id"
+ ],
+ "referencedColumns": [
+ "cookie_id"
+ ]
+ }
+ ]
}
],
"views": [],
"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, \"099ffebd0f0fe80199c0f6413a549ebb\")"
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"0a9d994786b7e07fea95c11d9210ce0e\")"
]
}
} \ No newline at end of file