handle repeatable event fetching in Room

This commit is contained in:
tibbi 2018-11-16 15:15:07 +01:00
parent 932cee76b0
commit 50c6826ec0
4 changed files with 137 additions and 153 deletions

View File

@ -166,7 +166,7 @@ fun Context.notifyEvent(originalEvent: Event) {
var eventStartTS = if (event.getIsAllDay()) Formatter.getDayStartTS(Formatter.getDayCodeFromTS(event.startTS)) else event.startTS
// make sure refer to the proper repeatable event instance with "Tomorrow", or the specific date
if (event.repeatInterval != 0 && eventStartTS - event.reminder1Minutes * 60 < currentSeconds) {
val events = dbHelper.getRepeatableEventsFor(currentSeconds - WEEK_SECONDS, currentSeconds + YEAR_SECONDS, event.id!!)
val events = eventsHelper.getRepeatableEventsFor(currentSeconds - WEEK_SECONDS, currentSeconds + YEAR_SECONDS, event.id!!)
for (currEvent in events) {
eventStartTS = if (currEvent.getIsAllDay()) Formatter.getDayStartTS(Formatter.getDayCodeFromTS(currEvent.startTS)) else currEvent.startTS
if (eventStartTS - currEvent.reminder1Minutes * 60 > currentSeconds) {

View File

@ -4,12 +4,8 @@ import android.content.Context
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.text.TextUtils
import androidx.collection.LongSparseArray
import com.simplemobiletools.calendar.pro.extensions.config
import com.simplemobiletools.calendar.pro.extensions.eventTypesDB
import com.simplemobiletools.calendar.pro.extensions.isTsOnProperDay
import com.simplemobiletools.calendar.pro.extensions.isXWeeklyRepetition
import com.simplemobiletools.calendar.pro.models.Event
import com.simplemobiletools.commons.extensions.getIntValue
import com.simplemobiletools.commons.extensions.getLongValue
@ -57,131 +53,6 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {}
fun getRepeatableEventsFor(fromTS: Long, toTS: Long, eventId: Long = -1L, applyTypeFilter: Boolean = false): List<Event> {
val newEvents = ArrayList<Event>()
//var selection = "$COL_REPEAT_INTERVAL != 0 AND $COL_START_TS <= $toTS AND $COL_START_TS != 0"
var selection = "$COL_START_TS <= $toTS AND $COL_START_TS != 0"
if (eventId != -1L)
selection += " AND $MAIN_TABLE_NAME.$COL_ID = $eventId"
if (applyTypeFilter) {
val displayEventTypes = context.config.displayEventTypes
if (displayEventTypes.isEmpty()) {
return ArrayList()
} else {
val types = TextUtils.join(",", displayEventTypes)
selection += " AND $COL_EVENT_TYPE IN ($types)"
}
}
val events = getEvents(selection)
val startTimes = LongSparseArray<Long>()
events.forEach {
startTimes.put(it.id!!, it.startTS)
if (it.repeatLimit >= 0) {
newEvents.addAll(getEventsRepeatingTillDateOrForever(fromTS, toTS, startTimes, it))
} else {
newEvents.addAll(getEventsRepeatingXTimes(fromTS, toTS, startTimes, it))
}
}
return newEvents
}
private fun getEventsRepeatingTillDateOrForever(fromTS: Long, toTS: Long, startTimes: LongSparseArray<Long>, event: Event): ArrayList<Event> {
val original = event.copy()
val events = ArrayList<Event>()
while (event.startTS <= toTS && (event.repeatLimit == 0L || event.repeatLimit >= event.startTS)) {
if (event.endTS >= fromTS) {
if (event.repeatInterval.isXWeeklyRepetition()) {
if (event.startTS.isTsOnProperDay(event)) {
if (event.isOnProperWeek(startTimes)) {
event.copy().apply {
updateIsPastEvent()
color = event.color
events.add(this)
}
}
}
} else {
event.copy().apply {
updateIsPastEvent()
color = event.color
events.add(this)
}
}
}
if (event.getIsAllDay()) {
if (event.repeatInterval.isXWeeklyRepetition()) {
if (event.endTS >= toTS && event.startTS.isTsOnProperDay(event)) {
if (event.isOnProperWeek(startTimes)) {
event.copy().apply {
updateIsPastEvent()
color = event.color
events.add(this)
}
}
}
} else {
val dayCode = Formatter.getDayCodeFromTS(fromTS)
val endDayCode = Formatter.getDayCodeFromTS(event.endTS)
if (dayCode == endDayCode) {
event.copy().apply {
updateIsPastEvent()
color = event.color
events.add(this)
}
}
}
}
event.addIntervalTime(original)
}
return events
}
private fun getEventsRepeatingXTimes(fromTS: Long, toTS: Long, startTimes: LongSparseArray<Long>, event: Event): ArrayList<Event> {
val original = event.copy()
val events = ArrayList<Event>()
while (event.repeatLimit < 0 && event.startTS <= toTS) {
if (event.repeatInterval.isXWeeklyRepetition()) {
if (event.startTS.isTsOnProperDay(event)) {
if (event.isOnProperWeek(startTimes)) {
if (event.endTS >= fromTS) {
event.copy().apply {
updateIsPastEvent()
color = event.color
events.add(this)
}
}
event.repeatLimit++
}
}
} else {
if (event.endTS >= fromTS) {
event.copy().apply {
updateIsPastEvent()
color = event.color
events.add(this)
}
} else if (event.getIsAllDay()) {
val dayCode = Formatter.getDayCodeFromTS(fromTS)
val endDayCode = Formatter.getDayCodeFromTS(event.endTS)
if (dayCode == endDayCode) {
event.copy().apply {
updateIsPastEvent()
color = event.color
events.add(this)
}
}
}
event.repeatLimit++
}
event.addIntervalTime(original)
}
return events
}
fun getRunningEvents(): List<Event> {
val events = ArrayList<Event>()
val ts = getNowSeconds()
@ -191,23 +62,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
val cursor = getEventsCursor(selection, selectionArgs)
events.addAll(fillEvents(cursor))
events.addAll(getRepeatableEventsFor(ts, ts))
return events
}
private fun getEvents(selection: String): List<Event> {
val events = ArrayList<Event>()
var cursor: Cursor? = null
try {
cursor = getEventsCursor(selection)
if (cursor != null) {
val currEvents = fillEvents(cursor)
events.addAll(currEvents)
}
} finally {
cursor?.close()
}
//events.addAll(getRepeatableEventsFor(ts, ts))
return events
}

View File

@ -245,11 +245,7 @@ class EventsHelper(val context: Context) {
}
fun getEventsSync(fromTS: Long, toTS: Long, eventId: Long = -1L, applyTypeFilter: Boolean, callback: (events: ArrayList<Event>) -> Unit) {
var events: ArrayList<Event>
//var selection = "$COL_START_TS <= ? AND $COL_END_TS >= ? AND $COL_REPEAT_INTERVAL IS NULL AND $COL_START_TS != 0"
events = if (applyTypeFilter) {
var events = if (applyTypeFilter) {
val displayEventTypes = context.config.displayEventTypes
if (displayEventTypes.isEmpty()) {
callback(ArrayList())
@ -265,7 +261,7 @@ class EventsHelper(val context: Context) {
}
}
// events.addAll(getRepeatableEventsFor(fromTS, toTS, eventId, applyTypeFilter))
events.addAll(getRepeatableEventsFor(fromTS, toTS, eventId, applyTypeFilter))
events = events
.asSequence()
@ -285,4 +281,128 @@ class EventsHelper(val context: Context) {
callback(events)
}
fun getRepeatableEventsFor(fromTS: Long, toTS: Long, eventId: Long = -1L, applyTypeFilter: Boolean = false): List<Event> {
val events = if (applyTypeFilter) {
val displayEventTypes = context.config.displayEventTypes
if (displayEventTypes.isEmpty()) {
return ArrayList()
} else {
eventsDB.getRepeatableEventsFromToWithTypes(toTS, context.config.getDisplayEventTypessAsList()).toMutableList() as ArrayList<Event>
}
} else {
if (eventId == -1L) {
eventsDB.getRepeatableEventsFromTo(toTS).toMutableList() as ArrayList<Event>
} else {
eventsDB.getRepeatableEventFromToWithId(eventId, toTS).toMutableList() as ArrayList<Event>
}
}
val startTimes = LongSparseArray<Long>()
val newEvents = ArrayList<Event>()
events.forEach {
startTimes.put(it.id!!, it.startTS)
if (it.repeatLimit >= 0) {
newEvents.addAll(getEventsRepeatingTillDateOrForever(fromTS, toTS, startTimes, it))
} else {
newEvents.addAll(getEventsRepeatingXTimes(fromTS, toTS, startTimes, it))
}
}
return newEvents
}
private fun getEventsRepeatingXTimes(fromTS: Long, toTS: Long, startTimes: LongSparseArray<Long>, event: Event): ArrayList<Event> {
val original = event.copy()
val events = ArrayList<Event>()
while (event.repeatLimit < 0 && event.startTS <= toTS) {
if (event.repeatInterval.isXWeeklyRepetition()) {
if (event.startTS.isTsOnProperDay(event)) {
if (event.isOnProperWeek(startTimes)) {
if (event.endTS >= fromTS) {
event.copy().apply {
updateIsPastEvent()
color = event.color
events.add(this)
}
}
event.repeatLimit++
}
}
} else {
if (event.endTS >= fromTS) {
event.copy().apply {
updateIsPastEvent()
color = event.color
events.add(this)
}
} else if (event.getIsAllDay()) {
val dayCode = Formatter.getDayCodeFromTS(fromTS)
val endDayCode = Formatter.getDayCodeFromTS(event.endTS)
if (dayCode == endDayCode) {
event.copy().apply {
updateIsPastEvent()
color = event.color
events.add(this)
}
}
}
event.repeatLimit++
}
event.addIntervalTime(original)
}
return events
}
private fun getEventsRepeatingTillDateOrForever(fromTS: Long, toTS: Long, startTimes: LongSparseArray<Long>, event: Event): ArrayList<Event> {
val original = event.copy()
val events = ArrayList<Event>()
while (event.startTS <= toTS && (event.repeatLimit == 0L || event.repeatLimit >= event.startTS)) {
if (event.endTS >= fromTS) {
if (event.repeatInterval.isXWeeklyRepetition()) {
if (event.startTS.isTsOnProperDay(event)) {
if (event.isOnProperWeek(startTimes)) {
event.copy().apply {
updateIsPastEvent()
color = event.color
events.add(this)
}
}
}
} else {
event.copy().apply {
updateIsPastEvent()
color = event.color
events.add(this)
}
}
}
if (event.getIsAllDay()) {
if (event.repeatInterval.isXWeeklyRepetition()) {
if (event.endTS >= toTS && event.startTS.isTsOnProperDay(event)) {
if (event.isOnProperWeek(startTimes)) {
event.copy().apply {
updateIsPastEvent()
color = event.color
events.add(this)
}
}
}
} else {
val dayCode = Formatter.getDayCodeFromTS(fromTS)
val endDayCode = Formatter.getDayCodeFromTS(event.endTS)
if (dayCode == endDayCode) {
event.copy().apply {
updateIsPastEvent()
color = event.color
events.add(this)
}
}
}
}
event.addIntervalTime(original)
}
return events
}
}

View File

@ -26,6 +26,15 @@ interface EventsDao {
@Query("SELECT * FROM events WHERE start_ts <= :toTS AND end_ts >= :fromTS AND start_ts != 0 AND repeat_interval = 0 AND event_type IN (:eventTypeIds)")
fun getOneTimeEventsFromToWithTypes(toTS: Long, fromTS: Long, eventTypeIds: List<Long>): List<Event>
@Query("SELECT * FROM events WHERE start_ts <= :toTS AND repeat_interval != 0")
fun getRepeatableEventsFromTo(toTS: Long): List<Event>
@Query("SELECT * FROM events WHERE id = :id AND start_ts <= :toTS AND repeat_interval != 0")
fun getRepeatableEventFromToWithId(id: Long, toTS: Long): List<Event>
@Query("SELECT * FROM events WHERE start_ts <= :toTS AND start_ts != 0 AND repeat_interval != 0 AND event_type IN (:eventTypeIds)")
fun getRepeatableEventsFromToWithTypes(toTS: Long, eventTypeIds: List<Long>): List<Event>
@Query("SELECT * FROM events WHERE id IN (:ids) AND import_id != \"\"")
fun getEventsByIdsWithImportIds(ids: List<Long>): List<Event>