mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-06-13 06:00:46 +02:00
[Events] Add support for selective updates and upserting.
This commit is contained in:
@ -193,6 +193,9 @@ dependencies {
|
||||
implementation "io.coil-kt:coil:0.9.2"
|
||||
|
||||
implementation 'com.github.kuba2k2:NumberSlidingPicker:2921225f76'
|
||||
|
||||
implementation project(":annotation")
|
||||
kapt project(":codegen")
|
||||
}
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
@ -284,7 +284,7 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
|
||||
db.gradeDao().addAll(gradeList)
|
||||
}
|
||||
if (eventList.isNotEmpty()) {
|
||||
db.eventDao().addAll(eventList)
|
||||
db.eventDao().upsertAll(eventList)
|
||||
}
|
||||
if (noticeList.isNotEmpty()) {
|
||||
db.noticeDao().clear(profile.id)
|
||||
|
@ -44,7 +44,7 @@ class AppSync(val app: App, val notifications: MutableList<Notification>, val pr
|
||||
event.addedDate
|
||||
)
|
||||
})
|
||||
return app.db.eventDao().addAll(events).size
|
||||
return app.db.eventDao().upsertAll(events).size
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -5,10 +5,7 @@
|
||||
package pl.szczodrzynski.edziennik.data.db.dao
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.RawQuery
|
||||
import androidx.room.*
|
||||
import androidx.sqlite.db.SimpleSQLiteQuery
|
||||
import androidx.sqlite.db.SupportSQLiteQuery
|
||||
|
||||
@ -24,11 +21,75 @@ interface BaseDao<T, F> {
|
||||
fun getOneNow(query: SupportSQLiteQuery): F?
|
||||
fun getOneNow(query: String) = getOneNow(SimpleSQLiteQuery(query))
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
/**
|
||||
* INSERT an [item] into the database,
|
||||
* ignoring any conflicts.
|
||||
*/
|
||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||
fun add(item: T): Long
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
/**
|
||||
* INSERT [items] into the database,
|
||||
* ignoring any conflicts.
|
||||
*/
|
||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||
fun addAll(items: List<T>): LongArray
|
||||
|
||||
/**
|
||||
* REPLACE an [item] in the database,
|
||||
* removing any conflicting rows.
|
||||
*/
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun replace(item: T)
|
||||
/**
|
||||
* REPLACE [items] in the database,
|
||||
* removing any conflicting rows.
|
||||
*/
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun replaceAll(items: List<T>)
|
||||
|
||||
/**
|
||||
* Selective UPDATE an [item] in the database.
|
||||
* Do nothing if a matching item does not exist.
|
||||
*/
|
||||
fun update(item: T): Long
|
||||
/**
|
||||
* Selective UPDATE [items] in the database.
|
||||
* Do nothing for those items which do not exist.
|
||||
*/
|
||||
fun updateAll(items: List<T>): LongArray
|
||||
|
||||
/**
|
||||
* Remove all items from the database,
|
||||
* that match the given [profileId].
|
||||
*/
|
||||
fun clear(profileId: Int)
|
||||
|
||||
/**
|
||||
* INSERT an [item] into the database,
|
||||
* doing a selective [update] on conflicts.
|
||||
* @return the newly inserted item's ID or -1L if the item was updated instead
|
||||
*/
|
||||
@Transaction
|
||||
fun upsert(item: T): Long {
|
||||
val id = add(item)
|
||||
if (id == -1L) update(item)
|
||||
return id
|
||||
}
|
||||
/**
|
||||
* INSERT [items] into the database,
|
||||
* doing a selective [update] on conflicts.
|
||||
* @return a [LongArray] of IDs of newly inserted items or -1L if the item existed before
|
||||
*/
|
||||
@Transaction
|
||||
fun upsertAll(items: List<T>): LongArray {
|
||||
val insertResult = addAll(items)
|
||||
val updateList = mutableListOf<T>()
|
||||
|
||||
insertResult.forEachIndexed { index, result ->
|
||||
if (result == -1L) updateList.add(items[index])
|
||||
}
|
||||
|
||||
if (updateList.isNotEmpty()) updateAll(items)
|
||||
return insertResult
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,10 @@ import androidx.room.RawQuery
|
||||
import androidx.room.Transaction
|
||||
import androidx.sqlite.db.SimpleSQLiteQuery
|
||||
import androidx.sqlite.db.SupportSQLiteQuery
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.annotation.SelectiveDao
|
||||
import pl.szczodrzynski.edziennik.annotation.UpdateSelective
|
||||
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||
@ -17,6 +21,7 @@ import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||
|
||||
@Dao
|
||||
@SelectiveDao(db = AppDb::class)
|
||||
abstract class EventDao : BaseDao<Event, EventFull> {
|
||||
companion object {
|
||||
private const val QUERY = """
|
||||
@ -37,45 +42,21 @@ abstract class EventDao : BaseDao<Event, EventFull> {
|
||||
private const val NOT_BLACKLISTED = """events.eventBlacklisted = 0"""
|
||||
}
|
||||
|
||||
//abstract fun queryRaw(query: SupportSQLiteQuery)
|
||||
//private fun queryRaw(query: String) = queryRaw(SimpleSQLiteQuery(query))
|
||||
|
||||
@Query("DELETE FROM events WHERE profileId = :profileId")
|
||||
abstract override fun clear(profileId: Int)
|
||||
|
||||
/*fun update(event: Event) =
|
||||
queryRaw("""UPDATE events SET
|
||||
eventDate = '${event.date.stringY_m_d}',
|
||||
eventTime = ${event.time?.stringValue},
|
||||
eventTopic = '${event.topic}'""")*/
|
||||
|
||||
@Query("DELETE FROM events WHERE profileId = :profileId AND eventId = :id")
|
||||
abstract fun remove(profileId: Int, id: Long)
|
||||
|
||||
@Query("DELETE FROM metadata WHERE profileId = :profileId AND thingType = :thingType AND thingId = :thingId")
|
||||
abstract fun removeMetadata(profileId: Int, thingType: Int, thingId: Long)
|
||||
|
||||
@Transaction
|
||||
open fun remove(profileId: Int, type: Long, id: Long) {
|
||||
remove(profileId, id)
|
||||
removeMetadata(profileId, if (type == Event.TYPE_HOMEWORK) Metadata.TYPE_HOMEWORK else Metadata.TYPE_EVENT, id)
|
||||
}
|
||||
|
||||
@Transaction
|
||||
open fun remove(event: Event) {
|
||||
remove(event.profileId, event.type, event.id)
|
||||
}
|
||||
|
||||
@Transaction
|
||||
open fun remove(profileId: Int, event: Event) {
|
||||
remove(profileId, event.type, event.id)
|
||||
}
|
||||
private val selective by lazy { EventDaoSelective(App.db) }
|
||||
|
||||
@RawQuery(observedEntities = [Event::class])
|
||||
abstract override fun getRaw(query: SupportSQLiteQuery): LiveData<List<EventFull>>
|
||||
|
||||
// SELECTIVE UPDATE
|
||||
@UpdateSelective(primaryKeys = ["profileId", "eventId"], skippedColumns = ["homeworkBody", "attachmentIds", "attachmentNames"])
|
||||
override fun update(item: Event) = selective.update(item)
|
||||
override fun updateAll(items: List<Event>) = selective.updateAll(items)
|
||||
|
||||
// CLEAR
|
||||
@Query("DELETE FROM events WHERE profileId = :profileId")
|
||||
abstract override fun clear(profileId: Int)
|
||||
|
||||
// GET ALL - LIVE DATA
|
||||
fun getAll(profileId: Int) =
|
||||
getRaw("$QUERY WHERE $NOT_BLACKLISTED AND events.profileId = $profileId $ORDER_BY")
|
||||
fun getAllByType(profileId: Int, type: Long, filter: String = "1") =
|
||||
@ -87,8 +68,7 @@ abstract class EventDao : BaseDao<Event, EventFull> {
|
||||
fun getAllNearest(profileId: Int, today: Date, limit: Int) =
|
||||
getRaw("$QUERY WHERE $NOT_BLACKLISTED AND events.profileId = $profileId AND eventDate >= '${today.stringY_m_d}' $ORDER_BY LIMIT $limit")
|
||||
|
||||
|
||||
|
||||
// GET ALL - NOW
|
||||
fun getAllNow(profileId: Int) =
|
||||
getRawNow("$QUERY WHERE $NOT_BLACKLISTED AND events.profileId = $profileId $ORDER_BY")
|
||||
fun getNotNotifiedNow() =
|
||||
@ -98,13 +78,11 @@ abstract class EventDao : BaseDao<Event, EventFull> {
|
||||
fun getAllByDateNow(profileId: Int, date: Date) =
|
||||
getRawNow("$QUERY WHERE $NOT_BLACKLISTED AND events.profileId = $profileId AND eventDate = '${date.stringY_m_d}' $ORDER_BY")
|
||||
|
||||
|
||||
|
||||
// GET ONE - NOW
|
||||
fun getByIdNow(profileId: Int, id: Long) =
|
||||
getOneNow("$QUERY WHERE events.profileId = $profileId AND eventId = $id")
|
||||
|
||||
|
||||
|
||||
@Query("SELECT eventId FROM events WHERE profileId = :profileId AND eventBlacklisted = 1")
|
||||
abstract fun getBlacklistedIds(profileId: Int): List<Long>
|
||||
|
||||
@ -147,4 +125,26 @@ abstract class EventDao : BaseDao<Event, EventFull> {
|
||||
@Query("UPDATE events SET eventBlacklisted = :blacklisted WHERE profileId = :profileId AND eventId = :eventId")
|
||||
abstract fun setBlacklisted(profileId: Int, eventId: Long, blacklisted: Boolean)
|
||||
|
||||
@Query("DELETE FROM events WHERE profileId = :profileId AND eventId = :id")
|
||||
abstract fun remove(profileId: Int, id: Long)
|
||||
|
||||
@Query("DELETE FROM metadata WHERE profileId = :profileId AND thingType = :thingType AND thingId = :thingId")
|
||||
abstract fun removeMetadata(profileId: Int, thingType: Int, thingId: Long)
|
||||
|
||||
@Transaction
|
||||
open fun remove(profileId: Int, type: Long, id: Long) {
|
||||
remove(profileId, id)
|
||||
removeMetadata(profileId, if (type == Event.TYPE_HOMEWORK) Metadata.TYPE_HOMEWORK else Metadata.TYPE_EVENT, id)
|
||||
}
|
||||
|
||||
@Transaction
|
||||
open fun remove(event: Event) {
|
||||
remove(event.profileId, event.type, event.id)
|
||||
}
|
||||
|
||||
@Transaction
|
||||
open fun remove(profileId: Int, event: Event) {
|
||||
remove(profileId, event.type, event.id)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ class SzkolnyAppFirebase(val app: App, val profiles: List<Profile>, val message:
|
||||
events += event
|
||||
metadataList += metadata
|
||||
}
|
||||
app.db.eventDao().addAll(events)
|
||||
app.db.eventDao().upsertAll(events)
|
||||
app.db.metadataDao().addAllReplace(metadataList)
|
||||
if (notificationList.isNotEmpty()) {
|
||||
app.db.notificationDao().addAll(notificationList)
|
||||
|
@ -587,7 +587,7 @@ class EventManualDialog(
|
||||
private fun finishAdding(eventObject: Event, metadataObject: Metadata) {
|
||||
launch {
|
||||
withContext(Dispatchers.Default) {
|
||||
app.db.eventDao().add(eventObject)
|
||||
app.db.eventDao().upsert(eventObject)
|
||||
app.db.metadataDao().add(metadataObject)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user