Improve application log performance

This commit is contained in:
greenart7c3
2025-12-10 09:37:25 -03:00
parent cf19691833
commit 181957c5f4
7 changed files with 149 additions and 45 deletions
@@ -2,11 +2,11 @@
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "29d5da9510c1dd78f8bdf4641d6cdf33",
"identityHash": "ffb6b79cf1c4bf0c70f58083cfc0990e",
"entities": [
{
"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)",
"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, `translatedPermission` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "id",
@@ -42,6 +42,12 @@
"columnName": "accepted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "translatedPermission",
"columnName": "translatedPermission",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
@@ -93,7 +99,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, '29d5da9510c1dd78f8bdf4641d6cdf33')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'ffb6b79cf1c4bf0c70f58083cfc0990e')"
]
}
}
@@ -0,0 +1,105 @@
{
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "ffb6b79cf1c4bf0c70f58083cfc0990e",
"entities": [
{
"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, `translatedPermission` TEXT 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
},
{
"fieldPath": "translatedPermission",
"columnName": "translatedPermission",
"affinity": "TEXT",
"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`)"
},
{
"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, 'ffb6b79cf1c4bf0c70f58083cfc0990e')"
]
}
}
@@ -1,6 +1,8 @@
package com.greenart7c3.nostrsigner.database
import android.util.Log
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.text.toLowerCase
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
@@ -8,6 +10,7 @@ import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import com.greenart7c3.nostrsigner.Amber
import com.greenart7c3.nostrsigner.models.Permission
import kotlinx.coroutines.flow.Flow
@Dao
@@ -15,9 +18,15 @@ interface HistoryDao {
@Query("SELECT * FROM history where pkKey = :pk ORDER BY time DESC")
fun getAllHistory(pk: String): Flow<List<HistoryEntity>>
@Query("SELECT * FROM history where (kind = :query OR LOWER(type) LIKE '%' || :query || '%' OR LOWER(translatedPermission) LIKE '%' || :query || '%') AND pkKey = :pk ORDER BY time DESC")
fun searchAllHistory(pk: String, query: String): Flow<List<HistoryEntity>>
@Query("SELECT * FROM history ORDER BY time DESC")
fun getAllHistory(): Flow<List<HistoryEntity>>
@Query("SELECT * FROM history where (kind = :query OR LOWER(type) LIKE '%' || :query || '%' OR LOWER(translatedPermission) LIKE '%' || :query || '%') ORDER BY time DESC")
fun searchAllHistory(query: String): Flow<List<HistoryEntity>>
@Query("DELETE FROM history where pkKey = :pk")
suspend fun deleteHistory(pk: String)
@@ -41,7 +50,11 @@ interface HistoryDao {
@Transaction
suspend fun addHistory(entity: HistoryEntity, npub: String?) {
try {
innerAddHistory(entity)
val permission = Permission(entity.type.toLowerCase(Locale.current), entity.kind)
val localEntity = entity.copy(
translatedPermission = permission.toLocalizedString(Amber.instance, true),
)
innerAddHistory(localEntity)
npub?.let {
Amber.instance.getDatabase(npub).dao().updateLastUsed(entity.pkKey, entity.time)
}
@@ -5,13 +5,21 @@ 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 java.util.concurrent.Executors
val migration_1_2 = object : Migration(1, 2) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE history ADD COLUMN translatedPermission TEXT NOT NULL DEFAULT ''")
}
}
@Database(
entities = [
HistoryEntity::class,
],
version = 1,
version = 2,
)
@TypeConverters(Converters::class)
abstract class HistoryDatabase : RoomDatabase() {
@@ -33,6 +41,7 @@ abstract class HistoryDatabase : RoomDatabase() {
)
.setQueryExecutor(executor)
.setTransactionExecutor(transactionExecutor)
.addMigrations(migration_1_2)
.build()
instance.openHelper.writableDatabase.execSQL("VACUUM")
@@ -33,4 +33,5 @@ data class HistoryEntity(
val kind: Int?,
val time: Long,
val accepted: Boolean,
val translatedPermission: String = "",
)
@@ -44,7 +44,6 @@ import com.greenart7c3.nostrsigner.Amber
import com.greenart7c3.nostrsigner.R
import com.greenart7c3.nostrsigner.database.AppDatabase
import com.greenart7c3.nostrsigner.models.Account
import com.greenart7c3.nostrsigner.models.Permission
import com.greenart7c3.nostrsigner.models.TimeUtils
import com.greenart7c3.nostrsigner.models.supportedKindNumbers
import com.greenart7c3.nostrsigner.service.ApplicationNameCache
@@ -62,20 +61,13 @@ fun ActivitiesScreen(
account: Account,
) {
val database = Amber.instance.getHistoryDatabase(account.npub)
val activities = database.dao().getAllHistory().collectAsStateWithLifecycle(emptyList())
val context = LocalContext.current
// State for the search query
var searchQuery by remember { mutableStateOf("") }
// Filtered activities based on the search query
val filteredActivities = activities.value.filter { activity ->
if (searchQuery.isEmpty()) {
true
} else {
val permission = Permission(activity.type.toLowerCase(Locale.current), activity.kind)
permission.toLocalizedString(context, true).contains(searchQuery, ignoreCase = true)
}
}
val filteredActivities = if (searchQuery.isEmpty()) database.dao().getAllHistory().collectAsStateWithLifecycle(emptyList()) else database.dao().searchAllHistory(searchQuery.toLowerCase(Locale.current)).collectAsStateWithLifecycle(emptyList())
val textFieldState by remember { mutableStateOf(TextFieldState(initialText = searchQuery)) }
Column(
@@ -100,7 +92,7 @@ fun ActivitiesScreen(
),
) {
item {
if (filteredActivities.isEmpty()) {
if (filteredActivities.value.isEmpty()) {
Text(
stringResource(R.string.no_activities_found),
Modifier
@@ -113,12 +105,7 @@ fun ActivitiesScreen(
}
}
items(filteredActivities) { activity ->
val permission =
Permission(
activity.type.toLowerCase(Locale.current),
activity.kind,
)
items(filteredActivities.value) { activity ->
Column {
Row(
modifier = Modifier
@@ -138,7 +125,7 @@ fun ActivitiesScreen(
)
Text(
text = if (permission.type == "connect") stringResource(R.string.connect) else permission.toLocalizedString(context),
text = activity.translatedPermission,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
color = if (activity.accepted) Color.Unspecified else Color.Gray,
@@ -42,7 +42,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.greenart7c3.nostrsigner.Amber
import com.greenart7c3.nostrsigner.R
import com.greenart7c3.nostrsigner.models.Account
import com.greenart7c3.nostrsigner.models.Permission
import com.greenart7c3.nostrsigner.models.TimeUtils
import com.greenart7c3.nostrsigner.models.supportedKindNumbers
import com.greenart7c3.nostrsigner.ui.components.SimpleSearchBar
@@ -56,20 +55,9 @@ fun ActivityScreen(
account: Account,
key: String,
) {
val activities = Amber.instance.getHistoryDatabase(account.npub).dao().getAllHistory(key).collectAsStateWithLifecycle(emptyList())
val context = LocalContext.current
// State for the search query
var searchQuery by remember { mutableStateOf("") }
// Filtered activities based on the search query
val filteredActivities = activities.value.filter { activity ->
if (searchQuery.isEmpty()) {
true
} else {
val permission = Permission(activity.type.toLowerCase(Locale.current), activity.kind)
permission.toLocalizedString(context, true).contains(searchQuery, ignoreCase = true)
}
}
val filteredActivities = if (searchQuery.isEmpty()) Amber.instance.getHistoryDatabase(account.npub).dao().getAllHistory(key).collectAsStateWithLifecycle(emptyList()) else Amber.instance.getHistoryDatabase(account.npub).dao().searchAllHistory(key, searchQuery.toLowerCase(Locale.current)).collectAsStateWithLifecycle(emptyList())
val textFieldState by remember { mutableStateOf(TextFieldState(initialText = searchQuery)) }
Column(
@@ -94,7 +82,7 @@ fun ActivityScreen(
),
) {
item {
if (filteredActivities.isEmpty()) {
if (filteredActivities.value.isEmpty()) {
Text(
stringResource(R.string.no_activities_found),
Modifier
@@ -107,12 +95,7 @@ fun ActivityScreen(
}
}
items(filteredActivities) { activity ->
val permission =
Permission(
activity.type.toLowerCase(Locale.current),
activity.kind,
)
items(filteredActivities.value) { activity ->
Column {
Row(
modifier = Modifier
@@ -126,7 +109,7 @@ fun ActivityScreen(
) {
Text(
modifier = Modifier.padding(top = 16.dp),
text = if (permission.type == "connect") stringResource(R.string.connect) else permission.toLocalizedString(context),
text = activity.translatedPermission,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
color = if (activity.accepted) Color.Unspecified else Color.Gray,