Refactor cookies database

This commit is contained in:
tarsin committed 2023-03-02 15:34:42 +08:00
1 parent d1d1da7875
commit 98107e40bc
3 files changed
+74 -91

No files matched your search

@@ -18,6 +18,7 @@ package com.hippo.ehviewer.client
import com.hippo.ehviewer.EhApplication
import com.hippo.network.CookieDatabase
import com.hippo.network.CookieSet
import eu.kanade.tachiyomi.util.lang.launchIO
import io.ktor.client.plugins.cookies.CookiesStorage
import io.ktor.http.Url
import okhttp3.Cookie
@@ -179,7 +180,9 @@ object EhCookieStore : CookieJar, CookiesStorage {
@Synchronized
fun clear() {
map.clear()
db.clear()
launchIO {
db.clear()
}
}
override suspend fun addCookie(requestUrl: Url, cookie: io.ktor.http.Cookie) {}
@@ -114,10 +114,10 @@ fun CookieSignInScene() {
ipbPassHashErrorState = false
}
focusManager.clearFocus()
storeCookie(ipbMemberId, ipbPassHash, igneous)
isProgressIndicatorVisible = true
signInJob = coroutineScope.launchIO {
runCatching {
storeCookie(ipbMemberId, ipbPassHash, igneous)
EhEngine.getProfile()
}.onSuccess {
withNonCancellableContext {
@@ -29,41 +29,80 @@ import androidx.room.RoomDatabase
import androidx.room.Update
import okhttp3.Cookie as OkHttpCookie
@Entity(tableName = "OK_HTTP_3_COOKIE")
class Cookie(
@ColumnInfo(name = "NAME")
var name: String,
@ColumnInfo(name = "VALUE")
var value: String,
@ColumnInfo(name = "EXPIRES_AT")
var expiresAt: Long,
@ColumnInfo(name = "DOMAIN")
var domain: String,
@ColumnInfo(name = "PATH")
var path: String,
@ColumnInfo(name = "SECURE")
var secure: Boolean,
@ColumnInfo(name = "HTTP_ONLY")
var httpOnly: Boolean,
@ColumnInfo(name = "PERSISTENT")
var persistent: Boolean,
@ColumnInfo(name = "HOST_ONLY")
var hostOnly: Boolean,
@PrimaryKey
@ColumnInfo(name = "_id")
var id: Long?
)
@Dao
interface CookiesDao {
@Query("SELECT * FROM OK_HTTP_3_COOKIE")
fun list(): List<Cookie>
@Delete
fun delete(cookie: Cookie)
@Insert
fun insert(cookie: Cookie): Long
@Update
fun update(cookie: Cookie)
}
@Database(entities = [Cookie::class], version = 1, exportSchema = false)
abstract class CookiesDatabase : RoomDatabase() {
abstract fun cookiesDao(): CookiesDao
}
internal class CookieDatabase(context: Context, name: String) {
private val cookieIdMap: MutableMap<OkHttpCookie, Long> = HashMap()
private val db =
Room.databaseBuilder(context, CookiesDatabase::class.java, name).allowMainThreadQueries()
.build()
private val db = Room.databaseBuilder(context, CookiesDatabase::class.java, name).build()
val allCookies: MutableMap<String, CookieSet>
get() {
val now = System.currentTimeMillis()
val map: MutableMap<String, CookieSet> = HashMap()
val toRemove: MutableList<Long> = ArrayList()
db.cookiesDao().list().forEach {
if (!it.persistent || it.expiresAt <= now) {
toRemove.add(it.id!!)
} else {
val okhttpCookie = it.toOkHttp3Cookie()
cookieIdMap[okhttpCookie] = it.id!!
// Put cookie to set
val set = map[it.domain] ?: CookieSet().apply { map[it.domain] = this }
set.add(okhttpCookie)
}
val allCookies by lazy {
val now = System.currentTimeMillis()
val map: MutableMap<String, CookieSet> = HashMap()
val toRemove: MutableList<Long> = ArrayList()
db.cookiesDao().list().forEach {
if (!it.persistent || it.expiresAt <= now) {
toRemove.add(it.id!!)
} else {
val okhttpCookie = it.toOkHttp3Cookie()
cookieIdMap[okhttpCookie] = it.id!!
val set = map[it.domain] ?: CookieSet().apply { map[it.domain] = this }
set.add(okhttpCookie)
}
if (toRemove.isNotEmpty()) {
val statement =
db.compileStatement("DELETE FROM $TABLE_COOKIE WHERE $COLUMN_ID = ?;")
db.runInTransaction {
toRemove.forEach {
statement.bindLong(1, it)
statement.executeUpdateDelete()
}
}
}
return map
}
if (toRemove.isNotEmpty()) {
val statement = db.compileStatement("DELETE FROM OK_HTTP_3_COOKIE WHERE _id = ?;")
db.runInTransaction {
toRemove.forEach {
statement.bindLong(1, it)
statement.executeUpdateDelete()
}
}
}
map
}
fun add(cookie: OkHttpCookie) {
db.cookiesDao().insert(cookie.toCookie()).apply { cookieIdMap[cookie] = this }
@@ -88,31 +127,6 @@ internal class CookieDatabase(context: Context, name: String) {
}
}
@Entity(tableName = TABLE_COOKIE)
data class Cookie(
@ColumnInfo(name = COLUMN_NAME)
var name: String,
@ColumnInfo(name = COLUMN_VALUE)
var value: String,
@ColumnInfo(name = COLUMN_EXPIRES_AT)
var expiresAt: Long,
@ColumnInfo(name = COLUMN_DOMAIN)
var domain: String,
@ColumnInfo(name = COLUMN_PATH)
var path: String,
@ColumnInfo(name = COLUMN_SECURE)
var secure: Boolean,
@ColumnInfo(name = COLUMN_HTTP_ONLY)
var httpOnly: Boolean,
@ColumnInfo(name = COLUMN_PERSISTENT)
var persistent: Boolean,
@ColumnInfo(name = COLUMN_HOST_ONLY)
var hostOnly: Boolean,
@PrimaryKey
@ColumnInfo(name = COLUMN_ID)
var id: Long?
)
fun Cookie.toOkHttp3Cookie(): OkHttpCookie {
return OkHttpCookie.Builder().apply {
name(name)
@@ -130,37 +144,3 @@ private fun OkHttpCookie.toCookie(id: Long? = null): Cookie {
name, value, expiresAt, domain, path, secure, httpOnly, persistent, hostOnly, id
)
}
@Dao
interface CookiesDao {
@Query("SELECT * FROM $TABLE_COOKIE")
fun list(): List<Cookie>
@Delete
fun delete(cookie: Cookie)
@Insert
fun insert(cookie: Cookie): Long
@Update
fun update(cookie: Cookie)
}
@Database(entities = [Cookie::class], version = DB_VERSION, exportSchema = false)
abstract class CookiesDatabase : RoomDatabase() {
abstract fun cookiesDao(): CookiesDao
}
private const val VERSION_1 = 1
private const val TABLE_COOKIE = "OK_HTTP_3_COOKIE"
private const val COLUMN_ID = "_id"
private const val COLUMN_NAME = "NAME"
private const val COLUMN_VALUE = "VALUE"
private const val COLUMN_EXPIRES_AT = "EXPIRES_AT"
private const val COLUMN_DOMAIN = "DOMAIN"
private const val COLUMN_PATH = "PATH"
private const val COLUMN_SECURE = "SECURE"
private const val COLUMN_HTTP_ONLY = "HTTP_ONLY"
private const val COLUMN_PERSISTENT = "PERSISTENT"
private const val COLUMN_HOST_ONLY = "HOST_ONLY"
private const val DB_VERSION = VERSION_1