package com.vgmlr.varnish
import android.content.Context
import androidx.room.Dao
import androidx.room.Database
import androidx.room.Entity
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Room
import androidx.room.RoomDatabase
import kotlinx.coroutines.flow.Flow
object MarkKind {
const val FOLDER_BLUR = 0
const val FILE_BLUR = 1
const val FAVORITE = 2
const val PINNED = 3
const val LIST_VIEW = 4
}
@Entity(tableName = "marks", primaryKeys = ["path", "kind"])
data class Mark(val path: String, val kind: Int)
@Dao
interface MarkDao {
@Query("SELECT path FROM marks WHERE kind = :kind")
fun paths(kind: Int): Flow<List<String>>
@Query("SELECT path FROM marks WHERE kind = :kind")
suspend fun pathsNow(kind: Int): List<String>
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun add(marks: List<Mark>)
@Query("DELETE FROM marks WHERE kind = :kind AND path IN (:paths)")
suspend fun remove(kind: Int, paths: List<String>)
@Query("DELETE FROM marks WHERE path = :path OR path LIKE :prefix ESCAPE '\\'")
suspend fun purge(path: String, prefix: String)
@Query("UPDATE OR REPLACE marks SET path = :to WHERE path = :from")
suspend fun move(from: String, to: String)
@Query(
"UPDATE OR REPLACE marks SET path = :to || substr(path, :cut) " +
"WHERE path LIKE :prefix ESCAPE '\\'"
)
suspend fun moveTree(to: String, cut: Int, prefix: String)
}
@Database(entities = [Mark::class], version = 1, exportSchema = false)
abstract class VarnishDb : RoomDatabase() {
abstract fun marks(): MarkDao
companion object {
@Volatile
private var inst: VarnishDb? = null
fun get(context: Context): VarnishDb = inst ?: synchronized(this) {
inst ?: Room.databaseBuilder(
context.applicationContext,
VarnishDb::class.java,
"varnish.db"
).build().also { inst = it }
}
}
}
internal fun likeEscape(s: String): String =
s.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_")
internal fun treeLike(path: String): String = likeEscape("$path/") + "%"