mirror of
https://github.com/greenart7c3/Amber.git
synced 2026-10-05 19:08:23 +00:00
Improve application log performance
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user