mirror of
https://github.com/greenart7c3/Amber.git
synced 2026-10-05 19:08:23 +00:00
Refactor: Remove NotificationEntity and use an in-memory cache
Removes the `NotificationEntity` and its associated database table (`notification`). This change simplifies the database schema and removes all related database queries from `ApplicationDao`. Instead of persisting notification data, an in-memory `LruCache` is now used to prevent processing duplicate notification events. The notification subscription service now checks this cache to determine the `since` timestamp for new filter requests.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 11,
|
||||
"identityHash": "431c73ad09acac77a9c7d0edb1372e8b",
|
||||
"identityHash": "f7d5a47e2a7bd4aad354df5a2a2796a4",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "application",
|
||||
@@ -207,56 +207,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "notification",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `eventId` TEXT NOT NULL, `time` INTEGER NOT NULL)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "eventId",
|
||||
"columnName": "eventId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "time",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": true,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_notification_eventId",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"eventId"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_notification_eventId` ON `${TABLE_NAME}` (`eventId`)"
|
||||
},
|
||||
{
|
||||
"name": "index_notification_time",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"time"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_notification_time` ON `${TABLE_NAME}` (`time`)"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "history",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `pkKey` TEXT NOT NULL, `type` TEXT NOT NULL, `kind` INTEGER, `time` INTEGER NOT NULL, `accepted` INTEGER NOT NULL, FOREIGN KEY(`pkKey`) REFERENCES `application`(`key`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
@@ -468,7 +418,7 @@
|
||||
],
|
||||
"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, '431c73ad09acac77a9c7d0edb1372e8b')"
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f7d5a47e2a7bd4aad354df5a2a2796a4')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,424 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 12,
|
||||
"identityHash": "f7d5a47e2a7bd4aad354df5a2a2796a4",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "application",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`key` TEXT NOT NULL, `name` TEXT NOT NULL, `relays` TEXT NOT NULL, `url` TEXT NOT NULL, `icon` TEXT NOT NULL, `description` TEXT NOT NULL, `pubKey` TEXT NOT NULL, `isConnected` INTEGER NOT NULL, `secret` TEXT NOT NULL, `useSecret` INTEGER NOT NULL, `signPolicy` INTEGER NOT NULL, `closeApplication` INTEGER NOT NULL, `deleteAfter` INTEGER NOT NULL, PRIMARY KEY(`key`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "key",
|
||||
"columnName": "key",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "name",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "relays",
|
||||
"columnName": "relays",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "url",
|
||||
"columnName": "url",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "icon",
|
||||
"columnName": "icon",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "description",
|
||||
"columnName": "description",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pubKey",
|
||||
"columnName": "pubKey",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "isConnected",
|
||||
"columnName": "isConnected",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "secret",
|
||||
"columnName": "secret",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "useSecret",
|
||||
"columnName": "useSecret",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "signPolicy",
|
||||
"columnName": "signPolicy",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "closeApplication",
|
||||
"columnName": "closeApplication",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "deleteAfter",
|
||||
"columnName": "deleteAfter",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"key"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_key",
|
||||
"unique": true,
|
||||
"columnNames": [
|
||||
"key"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_key` ON `${TABLE_NAME}` (`key`)"
|
||||
},
|
||||
{
|
||||
"name": "index_name",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"name"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_name` ON `${TABLE_NAME}` (`name`)"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "applicationPermission",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `pkKey` TEXT NOT NULL, `type` TEXT NOT NULL, `kind` INTEGER, `acceptable` INTEGER NOT NULL, `rememberType` INTEGER NOT NULL, `acceptUntil` INTEGER NOT NULL, `rejectUntil` INTEGER NOT NULL, PRIMARY KEY(`id`), FOREIGN KEY(`pkKey`) REFERENCES `application`(`key`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER"
|
||||
},
|
||||
{
|
||||
"fieldPath": "pkKey",
|
||||
"columnName": "pkKey",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "type",
|
||||
"columnName": "type",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "kind",
|
||||
"columnName": "kind",
|
||||
"affinity": "INTEGER"
|
||||
},
|
||||
{
|
||||
"fieldPath": "acceptable",
|
||||
"columnName": "acceptable",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "rememberType",
|
||||
"columnName": "rememberType",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "acceptUntil",
|
||||
"columnName": "acceptUntil",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "rejectUntil",
|
||||
"columnName": "rejectUntil",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "permissions_by_pk_key",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"pkKey"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `permissions_by_pk_key` ON `${TABLE_NAME}` (`pkKey`)"
|
||||
},
|
||||
{
|
||||
"name": "permissions_unique",
|
||||
"unique": true,
|
||||
"columnNames": [
|
||||
"pkKey",
|
||||
"type",
|
||||
"kind"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `permissions_unique` ON `${TABLE_NAME}` (`pkKey`, `type`, `kind`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "application",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"pkKey"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"key"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "history",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `pkKey` TEXT NOT NULL, `type` TEXT NOT NULL, `kind` INTEGER, `time` INTEGER NOT NULL, `accepted` INTEGER NOT NULL, FOREIGN KEY(`pkKey`) REFERENCES `application`(`key`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pkKey",
|
||||
"columnName": "pkKey",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "type",
|
||||
"columnName": "type",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "kind",
|
||||
"columnName": "kind",
|
||||
"affinity": "INTEGER"
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "time",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "accepted",
|
||||
"columnName": "accepted",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": true,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "history_by_pk_key",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"pkKey"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `history_by_pk_key` ON `${TABLE_NAME}` (`pkKey`)"
|
||||
},
|
||||
{
|
||||
"name": "history_by_id",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"id"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `history_by_id` ON `${TABLE_NAME}` (`id`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "application",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"pkKey"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"key"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "amber_log",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `type` TEXT NOT NULL, `message` TEXT NOT NULL, `time` INTEGER NOT NULL)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "url",
|
||||
"columnName": "url",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "type",
|
||||
"columnName": "type",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "message",
|
||||
"columnName": "message",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "time",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": true,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"tableName": "history2",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `pkKey` TEXT NOT NULL, `type` TEXT NOT NULL, `kind` INTEGER, `time` INTEGER NOT NULL, `accepted` INTEGER NOT NULL)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pkKey",
|
||||
"columnName": "pkKey",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "type",
|
||||
"columnName": "type",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "kind",
|
||||
"columnName": "kind",
|
||||
"affinity": "INTEGER"
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "time",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "accepted",
|
||||
"columnName": "accepted",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": true,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "history_by_pk_key2",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"pkKey"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `history_by_pk_key2` ON `${TABLE_NAME}` (`pkKey`)"
|
||||
},
|
||||
{
|
||||
"name": "history_by_id2",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"id"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `history_by_id2` ON `${TABLE_NAME}` (`id`)"
|
||||
},
|
||||
{
|
||||
"name": "history_by_time",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"time"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `history_by_time` ON `${TABLE_NAME}` (`time`)"
|
||||
},
|
||||
{
|
||||
"name": "history_by_key_and_time",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"pkKey",
|
||||
"time"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `history_by_key_and_time` ON `${TABLE_NAME}` (`pkKey`, `time`)"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"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, 'f7d5a47e2a7bd4aad354df5a2a2796a4')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import android.content.Intent
|
||||
import android.net.NetworkCapabilities
|
||||
import android.util.Log
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.collection.LruCache
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
@@ -120,6 +121,7 @@ class Amber : Application(), LifecycleObserver {
|
||||
val isOnOfflineState = mutableStateOf(false)
|
||||
private val isStartingApp = MutableStateFlow(false)
|
||||
val isStartingAppState = isStartingApp
|
||||
val notificationCache = LruCache<String, Long>(10)
|
||||
|
||||
fun isSocksProxyAlive(proxyHost: String, proxyPort: Int): Boolean {
|
||||
try {
|
||||
@@ -264,23 +266,6 @@ class Amber : Application(), LifecycleObserver {
|
||||
client.disconnect()
|
||||
}
|
||||
|
||||
// LocalPreferences.allSavedAccounts(this@Amber).forEach {
|
||||
// List<Int>(100000, init = { 1 }).forEachIndexed { index, it2 ->
|
||||
// launch(Dispatchers.IO) {
|
||||
// getDatabase(it.npub).applicationDao().addHistory(
|
||||
// HistoryEntity2(
|
||||
// id = 0,
|
||||
// pkKey = "com.vitorpamplona.amethyst",
|
||||
// type = "SIGN_EVENT",
|
||||
// kind = 1,
|
||||
// time = TimeUtils.now() + index,
|
||||
// accepted = true,
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
launch(Dispatchers.Main) {
|
||||
ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver {
|
||||
override fun onStart(owner: LifecycleOwner) {
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package com.greenart7c3.nostrsigner.database
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.room.Database
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.room.TypeConverters
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
val MIGRATION_1_2 =
|
||||
@@ -100,16 +102,25 @@ val MIGRATION_10_11 = object : Migration(10, 11) {
|
||||
}
|
||||
}
|
||||
|
||||
val MIGRATION_11_12 = object : Migration(11, 12) {
|
||||
override fun migrate(db: SupportSQLiteDatabase) {
|
||||
try {
|
||||
db.execSQL("DROP TABLE notification")
|
||||
} catch (e: Exception) {
|
||||
Log.e(Amber.TAG, "No notification table", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Database(
|
||||
entities = [
|
||||
ApplicationEntity::class,
|
||||
ApplicationPermissionsEntity::class,
|
||||
NotificationEntity::class,
|
||||
HistoryEntity::class,
|
||||
LogEntity::class,
|
||||
HistoryEntity2::class,
|
||||
],
|
||||
version = 11,
|
||||
version = 12,
|
||||
)
|
||||
@TypeConverters(Converters::class)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
@@ -142,6 +153,7 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
.addMigrations(MIGRATION_8_9)
|
||||
.addMigrations(MIGRATION_9_10)
|
||||
.addMigrations(MIGRATION_10_11)
|
||||
.addMigrations(MIGRATION_11_12)
|
||||
.build()
|
||||
instance.openHelper.writableDatabase.execSQL("VACUUM")
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
@@ -16,27 +15,6 @@ interface ApplicationDao {
|
||||
@Query("SELECT signPolicy FROM application WHERE `key` = :key")
|
||||
fun getSignPolicy(key: String): Int?
|
||||
|
||||
@Query("SELECT MAX(time) FROM notification")
|
||||
fun getLatestNotification(): Long?
|
||||
|
||||
@Query("SELECT * FROM notification WHERE eventId = :eventId")
|
||||
suspend fun getNotification(eventId: String): NotificationEntity?
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
@Transaction
|
||||
suspend fun insertNotification(notificationEntity: NotificationEntity): Long? {
|
||||
deleteNotification(TimeUtils.oneDayAgo())
|
||||
return innerInsertNotification(notificationEntity)
|
||||
}
|
||||
|
||||
@Query("DELETE FROM notification WHERE time <= :time")
|
||||
@Transaction
|
||||
suspend fun deleteNotification(time: Long)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
@Transaction
|
||||
suspend fun innerInsertNotification(notificationEntity: NotificationEntity): Long?
|
||||
|
||||
@Query("SELECT * FROM application where pubKey = :pubKey order by name")
|
||||
suspend fun getAll(pubKey: String): List<ApplicationEntity>
|
||||
|
||||
@@ -219,18 +197,6 @@ interface ApplicationDao {
|
||||
@Transaction
|
||||
suspend fun deleteHistory(historyEntity: HistoryEntity2)
|
||||
|
||||
@Query("SELECT COUNT(*) FROM notification WHERE time < :time")
|
||||
@Transaction
|
||||
suspend fun countOldNotification(time: Long): Long
|
||||
|
||||
@Query("SELECT * FROM notification WHERE time <= :time ORDER BY TIME DESC LIMIT 100")
|
||||
@Transaction
|
||||
suspend fun getOldNotification(time: Long): List<NotificationEntity>
|
||||
|
||||
@Delete
|
||||
@Transaction
|
||||
suspend fun deleteNotification(notificationEntity: NotificationEntity)
|
||||
|
||||
@Query("SELECT COUNT(*) FROM amber_log WHERE time < :time")
|
||||
@Transaction
|
||||
suspend fun countOldLog(time: Long): Long
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
package com.greenart7c3.nostrsigner.database
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(
|
||||
tableName = "notification",
|
||||
indices = [
|
||||
Index(value = ["eventId"]),
|
||||
Index(value = ["time"]),
|
||||
],
|
||||
)
|
||||
data class NotificationEntity(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
val id: Int,
|
||||
val eventId: String,
|
||||
val time: Long,
|
||||
)
|
||||
@@ -33,20 +33,6 @@ class ClearLogsWorker(appContext: Context, workerParams: WorkerParameters) :
|
||||
}
|
||||
}
|
||||
|
||||
val countNotification = database.applicationDao().countOldNotification(oneWeekAgo)
|
||||
Log.d(Amber.TAG, "Deleting $countNotification old notification entries")
|
||||
if (countNotification > 0) {
|
||||
var logs = database.applicationDao().getOldNotification(oneWeekAgo)
|
||||
var count = 0
|
||||
while (logs.isNotEmpty()) {
|
||||
count++
|
||||
logs.forEach { history ->
|
||||
database.applicationDao().deleteNotification(history)
|
||||
}
|
||||
logs = database.applicationDao().getOldNotification(oneWeekAgo)
|
||||
}
|
||||
}
|
||||
|
||||
val countLog = database.applicationDao().countOldLog(oneWeek)
|
||||
Log.d(Amber.TAG, "Deleting $countLog old log entries from ${com.greenart7c3.nostrsigner.models.TimeUtils.formatLongToCustomDateTimeWithSeconds(oneWeek)}")
|
||||
if (countLog > 0) {
|
||||
|
||||
@@ -34,7 +34,6 @@ import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.database.ApplicationWithPermissions
|
||||
import com.greenart7c3.nostrsigner.database.HistoryEntity2
|
||||
import com.greenart7c3.nostrsigner.database.LogEntity
|
||||
import com.greenart7c3.nostrsigner.database.NotificationEntity
|
||||
import com.greenart7c3.nostrsigner.models.Account
|
||||
import com.greenart7c3.nostrsigner.models.AmberBunkerRequest
|
||||
import com.greenart7c3.nostrsigner.models.EncryptionType
|
||||
@@ -150,9 +149,10 @@ class EventNotificationConsumer(private val applicationContext: Context) {
|
||||
val responseRelay = listOf(relay)
|
||||
val database = Amber.instance.getDatabase(acc.npub)
|
||||
val dao = database.applicationDao()
|
||||
val notification = dao.getNotification(event.id)
|
||||
|
||||
val notification = Amber.instance.notificationCache[event.id]
|
||||
if (notification != null) return
|
||||
dao.insertNotification(NotificationEntity(0, event.id, event.createdAt))
|
||||
Amber.instance.notificationCache.put(event.id, event.createdAt)
|
||||
|
||||
dao.insertLog(
|
||||
LogEntity(
|
||||
|
||||
@@ -66,25 +66,15 @@ class NotificationSubscription(
|
||||
client.openReqSubscription(subId, createNotificationsFilter())
|
||||
}
|
||||
|
||||
fun closeSubscription() {
|
||||
client.close(subId)
|
||||
}
|
||||
|
||||
private fun createNotificationsFilter(): Map<NormalizedRelayUrl, List<Filter>> {
|
||||
// TODO: If you break relays per account, you can change this to only send the requests to the right relays for each account.
|
||||
val relays = Amber.instance.getSavedRelays()
|
||||
|
||||
var since = TimeUtils.now()
|
||||
val accounts = LocalPreferences.allSavedAccounts(appContext)
|
||||
var localLatest = 0L
|
||||
accounts.forEach {
|
||||
val latest = Amber.instance.getDatabase(it.npub).applicationDao().getLatestNotification()
|
||||
if (latest != null && latest > localLatest) {
|
||||
localLatest = latest + 1
|
||||
}
|
||||
}
|
||||
if (localLatest > 0) {
|
||||
since = localLatest
|
||||
val latest = if (Amber.instance.notificationCache.size() > 0) Amber.instance.notificationCache.snapshot().maxOf { it.value } else 0L
|
||||
if (latest > 0) {
|
||||
since = latest
|
||||
}
|
||||
|
||||
val pubKeys = accounts.map { it.npub.bechToBytes().toHexKey() }
|
||||
|
||||
@@ -290,21 +290,6 @@ fun SettingsScreen(
|
||||
}
|
||||
}
|
||||
|
||||
val countNotification = database.applicationDao().countOldNotification(oneWeekAgo)
|
||||
if (countNotification > 0) {
|
||||
status = context.getString(R.string.deleting_old_notification_entries, countNotification)
|
||||
var logs = database.applicationDao().getOldNotification(oneWeekAgo)
|
||||
var count = 0
|
||||
while (logs.isNotEmpty()) {
|
||||
count++
|
||||
status = context.getString(R.string.deleting_old_notification_entries_2, 100 * count, countNotification)
|
||||
logs.forEach { history ->
|
||||
database.applicationDao().deleteNotification(history)
|
||||
}
|
||||
logs = database.applicationDao().getOldNotification(oneWeekAgo)
|
||||
}
|
||||
}
|
||||
|
||||
val countLog = database.applicationDao().countOldLog(oneWeek)
|
||||
if (countLog > 0) {
|
||||
status = context.getString(R.string.deleting_old_log_entries, countLog)
|
||||
|
||||
Reference in New Issue
Block a user