diff options
author | Allan Wang <me@allanwang.ca> | 2019-03-05 18:31:47 -0500 |
---|---|---|
committer | Allan Wang <me@allanwang.ca> | 2019-03-05 18:31:47 -0500 |
commit | c917dc13dabe7781a097383ae89f2d00f32fffcb (patch) | |
tree | a5a4edb12b6fc002ee76ef175533feb6cd7b7b75 /app/src/main/kotlin/com/pitchedapps/frost/db | |
parent | 566fcce5b79cfa22b0828d92e33ac4f109564927 (diff) | |
download | frost-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')
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() + } +} |