aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/com/pitchedapps/frost/db
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2019-03-05 18:31:47 -0500
committerAllan Wang <me@allanwang.ca>2019-03-05 18:31:47 -0500
commitc917dc13dabe7781a097383ae89f2d00f32fffcb (patch)
treea5a4edb12b6fc002ee76ef175533feb6cd7b7b75 /app/src/main/kotlin/com/pitchedapps/frost/db
parent566fcce5b79cfa22b0828d92e33ac4f109564927 (diff)
downloadfrost-c917dc13dabe7781a097383ae89f2d00f32fffcb.tar.gz
frost-c917dc13dabe7781a097383ae89f2d00f32fffcb.tar.bz2
frost-c917dc13dabe7781a097383ae89f2d00f32fffcb.zip
Create initial room models
Diffstat (limited to 'app/src/main/kotlin/com/pitchedapps/frost/db')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/db/CookiesDb.kt126
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/db/Database.kt62
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/db/DbUtils.kt38
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/db/FbTabsDb.kt108
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/db/NotificationDb.kt72
5 files changed, 406 insertions, 0 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/db/CookiesDb.kt b/app/src/main/kotlin/com/pitchedapps/frost/db/CookiesDb.kt
new file mode 100644
index 00000000..9deb57da
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/db/CookiesDb.kt
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.pitchedapps.frost.db
+
+import android.os.Parcelable
+import androidx.room.Dao
+import androidx.room.Entity
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import com.pitchedapps.frost.utils.L
+import com.raizlabs.android.dbflow.annotation.ConflictAction
+import com.raizlabs.android.dbflow.annotation.Database
+import com.raizlabs.android.dbflow.annotation.PrimaryKey
+import com.raizlabs.android.dbflow.annotation.Table
+import com.raizlabs.android.dbflow.kotlinextensions.async
+import com.raizlabs.android.dbflow.kotlinextensions.delete
+import com.raizlabs.android.dbflow.kotlinextensions.eq
+import com.raizlabs.android.dbflow.kotlinextensions.from
+import com.raizlabs.android.dbflow.kotlinextensions.save
+import com.raizlabs.android.dbflow.kotlinextensions.select
+import com.raizlabs.android.dbflow.kotlinextensions.where
+import com.raizlabs.android.dbflow.structure.BaseModel
+import kotlinx.android.parcel.Parcelize
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+
+/**
+ * Created by Allan Wang on 2017-05-30.
+ */
+
+@Entity(tableName = "cookies")
+@Parcelize
+data class CookieEntity(
+ @androidx.room.PrimaryKey
+ var id: Long,
+ var name: String,
+ var cookie: String
+) : Parcelable {
+ override fun toString(): String = "CookieModel(${hashCode()})"
+
+ fun toSensitiveString(): String = "CookieModel(id=$id, name=$name, cookie=$cookie)"
+}
+
+@Dao
+interface CookieDao {
+
+ @Query("SELECT * FROM cookies")
+ suspend fun selectAll(): List<CookieEntity>
+
+ @Query("SELECT * FROM cookies WHERE id = :id")
+ suspend fun selectById(id: Long): CookieEntity?
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun insertCookie(cookie: CookieEntity)
+
+ @Query("DELETE FROM cookies WHERE id = :id")
+ suspend fun deleteById(id: Long)
+}
+
+@Database(version = CookiesDb.VERSION)
+object CookiesDb {
+ const val NAME = "Cookies"
+ const val VERSION = 2
+}
+
+@Parcelize
+@Table(database = CookiesDb::class, allFields = true, primaryKeyConflict = ConflictAction.REPLACE)
+data class CookieModel(@PrimaryKey var id: Long = -1L, var name: String? = null, var cookie: String? = null) :
+ BaseModel(), Parcelable {
+
+ override fun toString(): String = "CookieModel(${hashCode()})"
+
+ fun toSensitiveString(): String = "CookieModel(id=$id, name=$name, cookie=$cookie)"
+}
+
+fun loadFbCookie(id: Long): CookieModel? =
+ (select from CookieModel::class where (CookieModel_Table.id eq id)).querySingle()
+
+fun loadFbCookie(name: String): CookieModel? =
+ (select from CookieModel::class where (CookieModel_Table.name eq name)).querySingle()
+
+/**
+ * Loads cookies sorted by name
+ */
+fun loadFbCookiesAsync(callback: (cookies: List<CookieModel>) -> Unit) {
+ (select from CookieModel::class).orderBy(CookieModel_Table.name, true).async()
+ .queryListResultCallback { _, tResult -> callback(tResult) }.execute()
+}
+
+fun loadFbCookiesSync(): List<CookieModel> =
+ (select from CookieModel::class).orderBy(CookieModel_Table.name, true).queryList()
+
+// TODO temp method until dbflow supports coroutines
+suspend fun loadFbCookiesSuspend(): List<CookieModel> = withContext(Dispatchers.IO) {
+ loadFbCookiesSync()
+}
+
+inline fun saveFbCookie(cookie: CookieModel, crossinline callback: (() -> Unit) = {}) {
+ cookie.async save {
+ L.d { "Fb cookie saved" }
+ L._d { cookie.toSensitiveString() }
+ callback()
+ }
+}
+
+fun removeCookie(id: Long) {
+ loadFbCookie(id)?.async?.delete {
+ L.d { "Fb cookie deleted" }
+ L._d { id }
+ }
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/db/Database.kt b/app/src/main/kotlin/com/pitchedapps/frost/db/Database.kt
new file mode 100644
index 00000000..34de5e07
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/db/Database.kt
@@ -0,0 +1,62 @@
+package com.pitchedapps.frost.db
+
+import android.content.Context
+import androidx.room.Database
+import androidx.room.Room
+import androidx.room.RoomDatabase
+import androidx.room.TypeConverters
+
+interface FrostPrivateDao {
+ fun cookieDao(): CookieDao
+}
+
+@Database(entities = [CookieEntity::class], version = 1, exportSchema = true)
+abstract class FrostPrivateDatabase : RoomDatabase(), FrostPrivateDao {
+ companion object {
+ const val DATABASE_NAME = "frost-priv-db"
+ }
+}
+
+interface FrostPublicDao {
+ fun tabDao(): FbTabDao
+}
+
+@Database(entities = [FbTabEntity::class], version = 1, exportSchema = true)
+@TypeConverters(FbItemConverter::class)
+abstract class FrostPublicDatabase : RoomDatabase(), FrostPublicDao {
+ companion object {
+ const val DATABASE_NAME = "frost-db"
+ }
+}
+
+interface FrostDao : FrostPrivateDao, FrostPublicDao {
+ fun close()
+}
+
+/**
+ * Composition of all database interfaces
+ */
+class FrostDatabase(private val privateDb: FrostPrivateDatabase, private val publicDb: FrostPublicDatabase) :
+ FrostDao,
+ FrostPrivateDao by privateDb,
+ FrostPublicDao by publicDb {
+
+ override fun close() {
+ privateDb.close()
+ publicDb.close()
+ }
+
+ companion object {
+ fun create(context: Context): FrostDatabase {
+ val privateDb = Room.databaseBuilder(
+ context, FrostPrivateDatabase::class.java,
+ FrostPrivateDatabase.DATABASE_NAME
+ ).build()
+ val publicDb = Room.databaseBuilder(
+ context, FrostPublicDatabase::class.java,
+ FrostPublicDatabase.DATABASE_NAME
+ ).build()
+ return FrostDatabase(privateDb, publicDb)
+ }
+ }
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/db/DbUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/db/DbUtils.kt
new file mode 100644
index 00000000..03aac059
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/db/DbUtils.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.pitchedapps.frost.db
+
+import android.content.Context
+import com.pitchedapps.frost.utils.L
+import com.raizlabs.android.dbflow.config.FlowManager
+import com.raizlabs.android.dbflow.structure.database.transaction.FastStoreModelTransaction
+
+/**
+ * Created by Allan Wang on 2017-05-30.
+ */
+
+object DbUtils {
+ fun db(name: String) = FlowManager.getDatabase(name)
+ fun dbName(name: String) = "$name.db"
+ fun deleteDatabase(c: Context, name: String) = c.deleteDatabase(dbName(name))
+}
+
+inline fun <reified T : Any> List<T>.replace(dbName: String) {
+ L.d { "Replacing $dbName.db" }
+ DbUtils.db(dbName).reset()
+ FastStoreModelTransaction.saveBuilder(FlowManager.getModelAdapter(T::class.java)).addAll(this).build()
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/db/FbTabsDb.kt b/app/src/main/kotlin/com/pitchedapps/frost/db/FbTabsDb.kt
new file mode 100644
index 00000000..2e2a9d62
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/db/FbTabsDb.kt
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.pitchedapps.frost.db
+
+import androidx.room.Dao
+import androidx.room.Entity
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import androidx.room.Transaction
+import com.pitchedapps.frost.facebook.FbItem
+import com.pitchedapps.frost.facebook.defaultTabs
+import com.pitchedapps.frost.utils.L
+import com.raizlabs.android.dbflow.annotation.Database
+import com.raizlabs.android.dbflow.annotation.PrimaryKey
+import com.raizlabs.android.dbflow.annotation.Table
+import com.raizlabs.android.dbflow.kotlinextensions.database
+import com.raizlabs.android.dbflow.kotlinextensions.fastSave
+import com.raizlabs.android.dbflow.kotlinextensions.from
+import com.raizlabs.android.dbflow.kotlinextensions.select
+import com.raizlabs.android.dbflow.structure.BaseModel
+
+/**
+ * Created by Allan Wang on 2017-05-30.
+ */
+
+@Entity(tableName = "tabs")
+data class FbTabEntity(@androidx.room.PrimaryKey var position: Int, var tab: FbItem)
+
+@Dao
+interface FbTabDao {
+
+ @Query("SELECT * FROM tabs ORDER BY position ASC")
+ suspend fun _selectAll(): List<FbTabEntity>
+
+ @Query("DELETE FROM tabs")
+ suspend fun _deleteAll()
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun _insertAll(items: List<FbTabEntity>)
+
+ @Transaction
+ suspend fun _save(items: List<FbTabEntity>) {
+ _deleteAll()
+ _insertAll(items)
+ }
+
+// suspend fun save(items: List<FbItem>) {
+// _save((items.takeIf { it.isNotEmpty() } ?: defaultTabs()).mapIndexed { index, fbItem ->
+// FbTabEntity(
+// index,
+// fbItem
+// )
+// })
+// }
+//
+// suspend fun selectAll(): List<FbItem> = _selectAll().map { it.tab }.takeIf { it.isNotEmpty() } ?: defaultTabs()
+}
+
+object FbItemConverter {
+ @androidx.room.TypeConverter
+ @JvmStatic
+ fun fromItem(item: FbItem): String = item.name
+
+ @androidx.room.TypeConverter
+ @JvmStatic
+ fun toItem(value: String): FbItem = FbItem.valueOf(value)
+}
+
+const val TAB_COUNT = 4
+
+@Database(version = FbTabsDb.VERSION)
+object FbTabsDb {
+ const val NAME = "FrostTabs"
+ const val VERSION = 1
+}
+
+@Table(database = FbTabsDb::class, allFields = true)
+data class FbTabModel(@PrimaryKey var position: Int = -1, var tab: FbItem = FbItem.FEED) : BaseModel()
+
+/**
+ * Load tabs synchronously
+ * Note that tab length should never be a big number anyways
+ */
+fun loadFbTabs(): List<FbItem> {
+ val tabs: List<FbTabModel>? = (select from (FbTabModel::class)).orderBy(FbTabModel_Table.position, true).queryList()
+ if (tabs?.size == TAB_COUNT) return tabs.map(FbTabModel::tab)
+ L.d { "No tabs (${tabs?.size}); loading default" }
+ return defaultTabs()
+}
+
+fun List<FbItem>.save() {
+ database<FbTabsDb>().beginTransactionAsync(mapIndexed(::FbTabModel).fastSave().build()).execute()
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/db/NotificationDb.kt b/app/src/main/kotlin/com/pitchedapps/frost/db/NotificationDb.kt
new file mode 100644
index 00000000..5b501792
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/db/NotificationDb.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.pitchedapps.frost.db
+
+import com.pitchedapps.frost.utils.L
+import com.raizlabs.android.dbflow.annotation.ConflictAction
+import com.raizlabs.android.dbflow.annotation.Database
+import com.raizlabs.android.dbflow.annotation.Migration
+import com.raizlabs.android.dbflow.annotation.PrimaryKey
+import com.raizlabs.android.dbflow.annotation.Table
+import com.raizlabs.android.dbflow.kotlinextensions.async
+import com.raizlabs.android.dbflow.kotlinextensions.eq
+import com.raizlabs.android.dbflow.kotlinextensions.from
+import com.raizlabs.android.dbflow.kotlinextensions.save
+import com.raizlabs.android.dbflow.kotlinextensions.select
+import com.raizlabs.android.dbflow.kotlinextensions.where
+import com.raizlabs.android.dbflow.sql.SQLiteType
+import com.raizlabs.android.dbflow.sql.migration.AlterTableMigration
+import com.raizlabs.android.dbflow.structure.BaseModel
+
+/**
+ * Created by Allan Wang on 2017-05-30.
+ */
+
+@Database(version = NotificationDb.VERSION)
+object NotificationDb {
+ const val NAME = "Notifications"
+ const val VERSION = 2
+}
+
+@Migration(version = 2, database = NotificationDb::class)
+class NotificationMigration2(modelClass: Class<NotificationModel>) :
+ AlterTableMigration<NotificationModel>(modelClass) {
+ override fun onPreMigrate() {
+ super.onPreMigrate()
+ addColumn(SQLiteType.INTEGER, "epochIm")
+ L.d { "Added column" }
+ }
+}
+
+@Table(database = NotificationDb::class, allFields = true, primaryKeyConflict = ConflictAction.REPLACE)
+data class NotificationModel(
+ @PrimaryKey var id: Long = -1L,
+ var epoch: Long = -1L,
+ var epochIm: Long = -1L
+) : BaseModel()
+
+fun lastNotificationTime(id: Long): NotificationModel =
+ (select from NotificationModel::class where (NotificationModel_Table.id eq id)).querySingle()
+ ?: NotificationModel(id = id)
+
+fun saveNotificationTime(notificationModel: NotificationModel, callback: (() -> Unit)? = null) {
+ notificationModel.async save {
+ L.d { "Fb notification model saved" }
+ L._d { notificationModel }
+ callback?.invoke()
+ }
+}