Tracker.kt (8855B) - raw


      1 package me.rhunk.snapenhance.storage
      2 
      3 import android.content.ContentValues
      4 import com.google.gson.JsonArray
      5 import kotlinx.coroutines.runBlocking
      6 import me.rhunk.snapenhance.common.data.TrackerRule
      7 import me.rhunk.snapenhance.common.data.TrackerRuleAction
      8 import me.rhunk.snapenhance.common.data.TrackerRuleActionParams
      9 import me.rhunk.snapenhance.common.data.TrackerRuleEvent
     10 import me.rhunk.snapenhance.common.data.TrackerScopeType
     11 import me.rhunk.snapenhance.common.util.ktx.getInteger
     12 import me.rhunk.snapenhance.common.util.ktx.getLongOrNull
     13 import me.rhunk.snapenhance.common.util.ktx.getStringOrNull
     14 import kotlin.coroutines.suspendCoroutine
     15 
     16 
     17 fun AppDatabase.clearTrackerRules() {
     18     runBlocking {
     19         suspendCoroutine { continuation ->
     20             executeAsync {
     21                 database.execSQL("DELETE FROM tracker_rules")
     22                 database.execSQL("DELETE FROM tracker_rules_events")
     23                 continuation.resumeWith(Result.success(Unit))
     24             }
     25         }
     26     }
     27 }
     28 
     29 fun AppDatabase.deleteTrackerRule(ruleId: Int) {
     30     executeAsync {
     31         database.execSQL("DELETE FROM tracker_rules WHERE id = ?", arrayOf(ruleId))
     32         database.execSQL("DELETE FROM tracker_rules_events WHERE rule_id = ?", arrayOf(ruleId))
     33     }
     34 }
     35 
     36 fun AppDatabase.newTrackerRule(name: String = "Custom Rule"): Int {
     37     return runBlocking {
     38         suspendCoroutine { continuation ->
     39             executeAsync {
     40                 val id = database.insert("tracker_rules", null, ContentValues().apply {
     41                     put("name", name)
     42                 })
     43                 continuation.resumeWith(Result.success(id.toInt()))
     44             }
     45         }
     46     }
     47 }
     48 
     49 fun AppDatabase.addOrUpdateTrackerRuleEvent(
     50     ruleEventId: Int? = null,
     51     ruleId: Int? = null,
     52     eventType: String? = null,
     53     params: TrackerRuleActionParams,
     54     actions: List<TrackerRuleAction>
     55 ): Int? {
     56     return runBlocking {
     57         suspendCoroutine { continuation ->
     58             executeAsync {
     59                 val id = if (ruleEventId != null) {
     60                     database.execSQL("UPDATE tracker_rules_events SET params = ?, actions = ? WHERE id = ?", arrayOf(
     61                         context.gson.toJson(params),
     62                         context.gson.toJson(actions.map { it.key }),
     63                         ruleEventId
     64                     ))
     65                     ruleEventId
     66                 } else {
     67                     database.insert("tracker_rules_events", null, ContentValues().apply {
     68                         put("rule_id", ruleId)
     69                         put("event_type", eventType)
     70                         put("params", context.gson.toJson(params))
     71                         put("actions", context.gson.toJson(actions.map { it.key }))
     72                     }).toInt()
     73                 }
     74                 continuation.resumeWith(Result.success(id))
     75             }
     76         }
     77     }
     78 }
     79 
     80 fun AppDatabase.deleteTrackerRuleEvent(eventId: Int) {
     81     executeAsync {
     82         database.execSQL("DELETE FROM tracker_rules_events WHERE id = ?", arrayOf(eventId))
     83     }
     84 }
     85 
     86 fun AppDatabase.getTrackerRulesDesc(): List<TrackerRule> {
     87     val rules = mutableListOf<TrackerRule>()
     88 
     89     database.rawQuery("SELECT * FROM tracker_rules ORDER BY id DESC", null).use { cursor ->
     90         while (cursor.moveToNext()) {
     91             rules.add(
     92                 TrackerRule(
     93                     id = cursor.getInteger("id"),
     94                     enabled = cursor.getInteger("enabled") == 1,
     95                     name = cursor.getStringOrNull("name") ?: "",
     96                 )
     97             )
     98         }
     99     }
    100 
    101     return rules
    102 }
    103 
    104 fun AppDatabase.getTrackerRule(ruleId: Int): TrackerRule? {
    105     return database.rawQuery("SELECT * FROM tracker_rules WHERE id = ?", arrayOf(ruleId.toString())).use { cursor ->
    106         if (!cursor.moveToFirst()) return@use null
    107         TrackerRule(
    108             id = cursor.getInteger("id"),
    109             enabled = cursor.getInteger("enabled") == 1,
    110             name = cursor.getStringOrNull("name") ?: "",
    111         )
    112     }
    113 }
    114 
    115 fun AppDatabase.setTrackerRuleName(ruleId: Int, name: String) {
    116     executeAsync {
    117         database.execSQL("UPDATE tracker_rules SET name = ? WHERE id = ?", arrayOf(name, ruleId))
    118     }
    119 }
    120 
    121 fun AppDatabase.setTrackerRuleState(ruleId: Int, enabled: Boolean) {
    122     executeAsync {
    123         database.execSQL("UPDATE tracker_rules SET enabled = ? WHERE id = ?", arrayOf(if (enabled) 1 else 0, ruleId))
    124     }
    125 }
    126 
    127 fun AppDatabase.getTrackerEvents(ruleId: Int): List<TrackerRuleEvent> {
    128     val events = mutableListOf<TrackerRuleEvent>()
    129     database.rawQuery("SELECT * FROM tracker_rules_events WHERE rule_id = ?", arrayOf(ruleId.toString())).use { cursor ->
    130         while (cursor.moveToNext()) {
    131             events.add(
    132                 TrackerRuleEvent(
    133                     id = cursor.getInteger("id"),
    134                     eventType = cursor.getStringOrNull("event_type") ?: continue,
    135                     enabled = cursor.getInteger("flags") == 1,
    136                     params = context.gson.fromJson(cursor.getStringOrNull("params") ?: "{}", TrackerRuleActionParams::class.java),
    137                     actions = context.gson.fromJson(cursor.getStringOrNull("actions") ?: "[]", JsonArray::class.java).mapNotNull {
    138                         TrackerRuleAction.fromString(it.asString)
    139                     }
    140                 )
    141             )
    142         }
    143     }
    144     return events
    145 }
    146 
    147 fun AppDatabase.getTrackerEvents(eventType: String): Map<TrackerRuleEvent, TrackerRule> {
    148     val events = mutableMapOf<TrackerRuleEvent, TrackerRule>()
    149     database.rawQuery("SELECT tracker_rules_events.id as event_id, tracker_rules_events.params as event_params," +
    150             "tracker_rules_events.actions, tracker_rules_events.flags, tracker_rules_events.event_type, tracker_rules.name, tracker_rules.id as rule_id " +
    151             "FROM tracker_rules_events " +
    152             "INNER JOIN tracker_rules " +
    153             "ON tracker_rules_events.rule_id = tracker_rules.id " +
    154             "WHERE event_type = ? AND tracker_rules.enabled = 1", arrayOf(eventType)
    155     ).use { cursor ->
    156         while (cursor.moveToNext()) {
    157             val trackerRule = TrackerRule(
    158                 id = cursor.getInteger("rule_id"),
    159                 enabled = true,
    160                 name = cursor.getStringOrNull("name") ?: "",
    161             )
    162             val trackerRuleEvent = TrackerRuleEvent(
    163                 id = cursor.getInteger("event_id"),
    164                 eventType = cursor.getStringOrNull("event_type") ?: continue,
    165                 enabled = cursor.getInteger("flags") == 1,
    166                 params = context.gson.fromJson(cursor.getStringOrNull("event_params") ?: "{}", TrackerRuleActionParams::class.java),
    167                 actions = context.gson.fromJson(cursor.getStringOrNull("actions") ?: "[]", JsonArray::class.java).mapNotNull {
    168                     TrackerRuleAction.fromString(it.asString)
    169                 }
    170             )
    171             events[trackerRuleEvent] = trackerRule
    172         }
    173     }
    174     return events
    175 }
    176 
    177 fun AppDatabase.setRuleTrackerScopes(ruleId: Int, type: TrackerScopeType, scopes: List<String>) {
    178     executeAsync {
    179         database.execSQL("DELETE FROM tracker_scopes WHERE rule_id = ?", arrayOf(ruleId))
    180         scopes.forEach { scopeId ->
    181             database.execSQL("INSERT INTO tracker_scopes (rule_id, scope_type, scope_id) VALUES (?, ?, ?)", arrayOf(
    182                 ruleId,
    183                 type.key,
    184                 scopeId
    185             ))
    186         }
    187     }
    188 }
    189 
    190 fun AppDatabase.getRuleTrackerScopes(ruleId: Int, limit: Int = Int.MAX_VALUE): Map<String, TrackerScopeType> {
    191     val scopes = mutableMapOf<String, TrackerScopeType>()
    192     database.rawQuery("SELECT * FROM tracker_scopes WHERE rule_id = ? LIMIT ?", arrayOf(ruleId.toString(), limit.toString())).use { cursor ->
    193         while (cursor.moveToNext()) {
    194             scopes[cursor.getStringOrNull("scope_id") ?: continue] = TrackerScopeType.entries.find { it.key == cursor.getStringOrNull("scope_type") } ?: continue
    195         }
    196     }
    197     return scopes
    198 }
    199 
    200 fun AppDatabase.updateFriendScore(userId: String, score: Long): Long {
    201     return runBlocking {
    202         suspendCoroutine { continuation ->
    203             executeAsync {
    204                 val currentScore = database.rawQuery("SELECT score FROM friend_scores WHERE userId = ?", arrayOf(userId)).use { cursor ->
    205                     if (!cursor.moveToFirst()) return@use null
    206                     cursor.getLongOrNull("score")
    207                 }
    208 
    209                 if (currentScore != null) {
    210                     database.execSQL("UPDATE friend_scores SET score = ? WHERE userId = ?", arrayOf(score, userId))
    211                 } else {
    212                     database.execSQL("INSERT INTO friend_scores (userId, score) VALUES (?, ?)", arrayOf(userId, score))
    213                 }
    214 
    215                 continuation.resumeWith(Result.success(currentScore ?: -1))
    216             }
    217         }
    218     }
    219 }