From f6dd3a63e687d225f60b9bf23b7fc0c5f7a33d89 Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Mon, 29 Jun 2020 10:53:33 -0500 Subject: [PATCH] Blocking daos delegate to suspending daos --- .../todoroo/astrid/service/TaskMoverTest.kt | 7 +- .../java/com/todoroo/astrid/dao/Database.kt | 32 +- .../com/todoroo/astrid/dao/TaskDaoBlocking.kt | 370 +++++++--------- .../java/org/tasks/data/AlarmDaoBlocking.kt | 44 +- .../java/org/tasks/data/CaldavDaoBlocking.kt | 418 ++++++++---------- .../tasks/data/ContentProviderDaoBlocking.kt | 73 ++- .../org/tasks/data/DeletionDaoBlocking.kt | 147 +++--- .../java/org/tasks/data/FilterDaoBlocking.kt | 74 ++-- .../org/tasks/data/GoogleTaskDaoBlocking.kt | 286 +++++------- .../tasks/data/GoogleTaskListDaoBlocking.kt | 108 +++-- .../org/tasks/data/LocationDaoBlocking.kt | 216 +++++---- .../java/org/tasks/data/TagDaoBlocking.kt | 65 ++- .../java/org/tasks/data/TagDataDaoBlocking.kt | 258 +++++------ .../tasks/data/TaskAttachmentDaoBlocking.kt | 46 +- .../tasks/data/TaskListMetadataDaoBlocking.kt | 34 +- .../org/tasks/data/UserActivityDaoBlocking.kt | 64 ++- .../org/tasks/injection/ApplicationModule.kt | 34 +- .../notifications/NotificationDaoBlocking.kt | 40 +- 18 files changed, 1061 insertions(+), 1255 deletions(-) diff --git a/app/src/androidTest/java/com/todoroo/astrid/service/TaskMoverTest.kt b/app/src/androidTest/java/com/todoroo/astrid/service/TaskMoverTest.kt index cb0726ece..09400691e 100644 --- a/app/src/androidTest/java/com/todoroo/astrid/service/TaskMoverTest.kt +++ b/app/src/androidTest/java/com/todoroo/astrid/service/TaskMoverTest.kt @@ -3,10 +3,12 @@ package com.todoroo.astrid.service import com.natpryce.makeiteasy.MakeItEasy.with import com.todoroo.astrid.api.CaldavFilter import com.todoroo.astrid.api.GtasksFilter +import com.todoroo.astrid.dao.TaskDao import com.todoroo.astrid.dao.TaskDaoBlocking import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.UninstallModules -import org.junit.Assert.* +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.tasks.data.CaldavCalendar @@ -34,6 +36,7 @@ import javax.inject.Inject @UninstallModules(ProductionModule::class) @HiltAndroidTest class TaskMoverTest : InjectingTestCase() { + @Inject lateinit var taskDaoAsync: TaskDao @Inject lateinit var taskDao: TaskDaoBlocking @Inject lateinit var googleTaskDao: GoogleTaskDaoBlocking @Inject lateinit var workManager: WorkManager @@ -43,7 +46,7 @@ class TaskMoverTest : InjectingTestCase() { @Before override fun setUp() { super.setUp() - taskDao.initialize(workManager) + taskDaoAsync.initialize(workManager) } @Test diff --git a/app/src/main/java/com/todoroo/astrid/dao/Database.kt b/app/src/main/java/com/todoroo/astrid/dao/Database.kt index dd38c7929..22b42a569 100644 --- a/app/src/main/java/com/todoroo/astrid/dao/Database.kt +++ b/app/src/main/java/com/todoroo/astrid/dao/Database.kt @@ -5,7 +5,7 @@ import androidx.room.RoomDatabase import com.todoroo.astrid.data.Task import org.tasks.data.* import org.tasks.notifications.Notification -import org.tasks.notifications.NotificationDaoBlocking +import org.tasks.notifications.NotificationDao @Database( entities = [ @@ -28,21 +28,21 @@ import org.tasks.notifications.NotificationDaoBlocking GoogleTaskAccount::class], version = 76) abstract class Database : RoomDatabase() { - abstract fun notificationDao(): NotificationDaoBlocking - abstract val tagDataDao: TagDataDaoBlocking - abstract val userActivityDao: UserActivityDaoBlocking - abstract val taskAttachmentDao: TaskAttachmentDaoBlocking - abstract val taskListMetadataDao: TaskListMetadataDaoBlocking - abstract val alarmDao: AlarmDaoBlocking - abstract val locationDao: LocationDaoBlocking - abstract val tagDao: TagDaoBlocking - abstract val googleTaskDao: GoogleTaskDaoBlocking - abstract val filterDao: FilterDaoBlocking - abstract val googleTaskListDao: GoogleTaskListDaoBlocking - abstract val taskDao: TaskDaoBlocking - abstract val caldavDao: CaldavDaoBlocking - abstract val deletionDao: DeletionDaoBlocking - abstract val contentProviderDao: ContentProviderDaoBlocking + abstract fun notificationDao(): NotificationDao + abstract val tagDataDao: TagDataDao + abstract val userActivityDao: UserActivityDao + abstract val taskAttachmentDao: TaskAttachmentDao + abstract val taskListMetadataDao: TaskListMetadataDao + abstract val alarmDao: AlarmDao + abstract val locationDao: LocationDao + abstract val tagDao: TagDao + abstract val googleTaskDao: GoogleTaskDao + abstract val filterDao: FilterDao + abstract val googleTaskListDao: GoogleTaskListDao + abstract val taskDao: TaskDao + abstract val caldavDao: CaldavDao + abstract val deletionDao: DeletionDao + abstract val contentProviderDao: ContentProviderDao /** @return human-readable database name for debugging */ diff --git a/app/src/main/java/com/todoroo/astrid/dao/TaskDaoBlocking.kt b/app/src/main/java/com/todoroo/astrid/dao/TaskDaoBlocking.kt index b66836b13..4cc3e03e0 100644 --- a/app/src/main/java/com/todoroo/astrid/dao/TaskDaoBlocking.kt +++ b/app/src/main/java/com/todoroo/astrid/dao/TaskDaoBlocking.kt @@ -6,275 +6,211 @@ package com.todoroo.astrid.dao import androidx.paging.DataSource -import androidx.room.* import androidx.sqlite.db.SimpleSQLiteQuery -import com.todoroo.andlib.sql.Field -import com.todoroo.andlib.utility.AndroidUtilities.assertNotMainThread -import com.todoroo.andlib.utility.DateUtilities import com.todoroo.astrid.api.Filter -import com.todoroo.astrid.dao.TaskDao.Companion.getQuery import com.todoroo.astrid.data.Task -import com.todoroo.astrid.data.Task.Companion.NO_ID -import com.todoroo.astrid.helper.UUIDHelper import kotlinx.coroutines.runBlocking -import org.tasks.BuildConfig -import org.tasks.data.Place import org.tasks.data.SubtaskInfo import org.tasks.data.TaskContainer -import org.tasks.data.TaskListQuery -import org.tasks.db.DbUtils.chunkedMap -import org.tasks.db.DbUtils.eachChunk -import org.tasks.jobs.WorkManager import org.tasks.preferences.Preferences import org.tasks.time.DateTimeUtils.currentTimeMillis -import timber.log.Timber +import javax.inject.Inject -@Dao -abstract class TaskDaoBlocking(private val database: Database) { - private lateinit var workManager: WorkManager +@Deprecated("use coroutines") +class TaskDaoBlocking @Inject constructor(private val dao: TaskDao) { + fun needsRefresh(): List = runBlocking { + dao.needsRefresh() + } - fun initialize(workManager: WorkManager) { - this.workManager = workManager + fun needsRefresh(now: Long): List = runBlocking { + dao.needsRefresh(now) } - fun needsRefresh(): List { - return needsRefresh(DateUtilities.now()) + fun fetchBlocking(id: Long) = runBlocking { + dao.fetchBlocking(id) } - @Query("SELECT * FROM tasks WHERE completed = 0 AND deleted = 0 AND (hideUntil > :now OR dueDate > :now)") - abstract fun needsRefresh(now: Long): List + fun fetch(id: Long): Task? = runBlocking { + dao.fetch(id) + } - fun fetchBlocking(id: Long) = runBlocking { - fetch(id) + fun fetch(ids: List): List = runBlocking { + dao.fetch(ids) + } + + internal fun fetchInternal(ids: List): List = runBlocking { + dao.fetchInternal(ids) + } + + fun activeTimers(): Int = runBlocking { + dao.activeTimers() + } + + fun activeNotifications(): List = runBlocking { + dao.activeNotifications() + } + + fun fetch(remoteId: String): Task? = runBlocking { + dao.fetch(remoteId) + } + + fun getActiveTasks(): List = runBlocking { + dao.getActiveTasks() + } + + fun getVisibleTasks(): List = runBlocking { + dao.getVisibleTasks() + } + + fun getRecurringTasks(remoteIds: List): List = runBlocking { + dao.getRecurringTasks(remoteIds) + } + + fun setCompletionDate(remoteId: String, completionDate: Long) = runBlocking { + dao.setCompletionDate(remoteId, completionDate) + } + + fun snooze(taskIds: List, millis: Long) = runBlocking { + dao.snooze(taskIds, millis) + } + + fun getGoogleTasksToPush(account: String): List = runBlocking { + dao.getGoogleTasksToPush(account) + } + + fun getCaldavTasksToPush(calendar: String): List = runBlocking { + dao.getCaldavTasksToPush(calendar) + } + + fun getTasksWithReminders(): List = runBlocking { + dao.getTasksWithReminders() } - @Query("SELECT * FROM tasks WHERE _id = :id LIMIT 1") - abstract suspend fun fetch(id: Long): Task? + fun getAll(): List = runBlocking { + dao.getAll() + } - fun fetch(ids: List): List = ids.chunkedMap(this::fetchInternal) + fun getAllCalendarEvents(): List = runBlocking { + dao.getAllCalendarEvents() + } - @Query("SELECT * FROM tasks WHERE _id IN (:ids)") - internal abstract fun fetchInternal(ids: List): List + fun clearAllCalendarEvents(): Int = runBlocking { + dao.clearAllCalendarEvents() + } - @Query("SELECT COUNT(1) FROM tasks WHERE timerStart > 0 AND deleted = 0") - abstract fun activeTimers(): Int + fun getCompletedCalendarEvents(): List = runBlocking { + dao.getCompletedCalendarEvents() + } - @Query("SELECT tasks.* FROM tasks INNER JOIN notification ON tasks._id = notification.task") - abstract fun activeNotifications(): List + fun clearCompletedCalendarEvents(): Int = runBlocking { + dao.clearCompletedCalendarEvents() + } - @Query("SELECT * FROM tasks WHERE remoteId = :remoteId") - abstract fun fetch(remoteId: String): Task? + fun fetchTasks(callback: (SubtaskInfo) -> List): List = runBlocking { + dao.fetchTasks(callback) + } - @Query("SELECT * FROM tasks WHERE completed = 0 AND deleted = 0") - abstract fun getActiveTasks(): List + fun fetchTasks(callback: (SubtaskInfo) -> List, subtasks: SubtaskInfo): List = runBlocking { + dao.fetchTasks(callback, subtasks) + } - @Query("SELECT * FROM tasks WHERE hideUntil < (strftime('%s','now')*1000)") - abstract fun getVisibleTasks(): List + fun fetchTasks(preferences: Preferences, filter: Filter): List = runBlocking { + dao.fetchTasks(preferences, filter) + } - @Query("SELECT * FROM tasks WHERE remoteId IN (:remoteIds) " - + "AND recurrence IS NOT NULL AND LENGTH(recurrence) > 0") - abstract fun getRecurringTasks(remoteIds: List): List + fun fetchTasks(query: SimpleSQLiteQuery): List = runBlocking { + dao.fetchTasks(query) + } - @Query("UPDATE tasks SET completed = :completionDate " + "WHERE remoteId = :remoteId") - abstract fun setCompletionDate(remoteId: String, completionDate: Long) + fun count(query: SimpleSQLiteQuery): Int = runBlocking { + dao.count(query) + } - @Query("UPDATE tasks SET snoozeTime = :millis WHERE _id in (:taskIds)") - abstract fun snooze(taskIds: List, millis: Long) + fun getSubtaskInfo(): SubtaskInfo = runBlocking { + dao.getSubtaskInfo() + } - @Query("SELECT tasks.* FROM tasks " - + "LEFT JOIN google_tasks ON tasks._id = google_tasks.gt_task " - + "WHERE gt_list_id IN (SELECT gtl_remote_id FROM google_task_lists WHERE gtl_account = :account)" - + "AND (tasks.modified > google_tasks.gt_last_sync OR google_tasks.gt_remote_id = '' OR google_tasks.gt_deleted > 0) " - + "ORDER BY CASE WHEN gt_parent = 0 THEN 0 ELSE 1 END, gt_order ASC") - abstract fun getGoogleTasksToPush(account: String): List + fun getTaskFactory(query: SimpleSQLiteQuery): DataSource.Factory { + return dao.getTaskFactory(query) + } - @Query(""" - SELECT tasks.* - FROM tasks - INNER JOIN caldav_tasks ON tasks._id = caldav_tasks.cd_task - WHERE caldav_tasks.cd_calendar = :calendar - AND (tasks.modified > caldav_tasks.cd_last_sync OR caldav_tasks.cd_last_sync = 0)""") - abstract fun getCaldavTasksToPush(calendar: String): List + fun touch(id: Long) = runBlocking { + dao.touch(id) + } - @Query("SELECT * FROM TASKS " - + "WHERE completed = 0 AND deleted = 0 AND (notificationFlags > 0 OR notifications > 0)") - abstract fun getTasksWithReminders(): List + fun touch(ids: List) = runBlocking { + dao.touch(ids) + } - // --- SQL clause generators - @Query("SELECT * FROM tasks") - abstract fun getAll(): List + fun touchInternal(ids: List, now: Long = currentTimeMillis()) = runBlocking { + dao.touchInternal(ids, now) + } - @Query("SELECT calendarUri FROM tasks " + "WHERE calendarUri IS NOT NULL AND calendarUri != ''") - abstract fun getAllCalendarEvents(): List + fun setParent(parent: Long, tasks: List) = runBlocking { + dao.setParent(parent, tasks) + } - @Query("UPDATE tasks SET calendarUri = '' " + "WHERE calendarUri IS NOT NULL AND calendarUri != ''") - abstract fun clearAllCalendarEvents(): Int + internal fun setParentInternal(parent: Long, children: List) = runBlocking { + dao.setParentInternal(parent, children) + } - @Query("SELECT calendarUri FROM tasks " - + "WHERE completed > 0 AND calendarUri IS NOT NULL AND calendarUri != ''") - abstract fun getCompletedCalendarEvents(): List + fun fetchChildren(id: Long): List = runBlocking { + dao.fetchChildren(id) + } - @Query("UPDATE tasks SET calendarUri = '' " - + "WHERE completed > 0 AND calendarUri IS NOT NULL AND calendarUri != ''") - abstract fun clearCompletedCalendarEvents(): Int + fun getChildren(id: Long): List = runBlocking { + dao.getChildren(id) + } - @Transaction - open fun fetchTasks(callback: (SubtaskInfo) -> List): List { - return runBlocking { - fetchTasks(callback, getSubtaskInfo()) - } + fun getChildren(ids: List): List = runBlocking { + dao.getChildren(ids) } - @Transaction - open fun fetchTasks(callback: (SubtaskInfo) -> List, subtasks: SubtaskInfo): List { - assertNotMainThread() + fun setCollapsed(id: Long, collapsed: Boolean) = runBlocking { + dao.setCollapsed(id, collapsed) + } - val start = if (BuildConfig.DEBUG) DateUtilities.now() else 0 - val queries = callback.invoke(subtasks) - val db = database.openHelper.writableDatabase - val last = queries.size - 1 - for (i in 0 until last) { - db.execSQL(queries[i]) - } - val result = fetchTasks(SimpleSQLiteQuery(queries[last])) - Timber.v("%sms: %s", DateUtilities.now() - start, queries.joinToString(";\n")) - return result + fun setCollapsed(preferences: Preferences, filter: Filter, collapsed: Boolean) = runBlocking { + dao.setCollapsed(preferences, filter, collapsed) } - fun fetchTasks(preferences: Preferences, filter: Filter): List { - return fetchTasks { - TaskListQuery.getQuery(preferences, filter, it) - } + fun collapse(ids: List, collapsed: Boolean) = runBlocking { + dao.collapse(ids, collapsed) } - @RawQuery - abstract fun fetchTasks(query: SimpleSQLiteQuery): List - - @RawQuery - abstract fun count(query: SimpleSQLiteQuery): Int - - @Query(""" -SELECT EXISTS(SELECT 1 FROM tasks WHERE parent > 0 AND deleted = 0) AS hasSubtasks, - EXISTS(SELECT 1 - FROM google_tasks - INNER JOIN tasks ON gt_task = _id - WHERE deleted = 0 - AND gt_parent > 0 - AND gt_deleted = 0) AS hasGoogleSubtasks - """) - abstract suspend fun getSubtaskInfo(): SubtaskInfo - - @RawQuery(observedEntities = [Place::class]) - abstract fun getTaskFactory( - query: SimpleSQLiteQuery): DataSource.Factory - - fun touch(id: Long) = touch(listOf(id)) - - fun touch(ids: List) { - ids.eachChunk { touchInternal(it) } - workManager.sync(false) - } - - @Query("UPDATE tasks SET modified = :now WHERE _id in (:ids)") - abstract fun touchInternal(ids: List, now: Long = currentTimeMillis()) - - fun setParent(parent: Long, tasks: List) = - tasks.eachChunk { setParentInternal(parent, it) } - - @Query("UPDATE tasks SET parent = :parent WHERE _id IN (:children)") - internal abstract fun setParentInternal(parent: Long, children: List) - - @Transaction - open fun fetchChildren(id: Long): List { - return fetch(getChildren(id)) - } - - fun getChildren(id: Long): List { - return getChildren(listOf(id)) - } - - @Query("WITH RECURSIVE " - + " recursive_tasks (task) AS ( " - + " SELECT _id " - + " FROM tasks " - + "WHERE parent IN (:ids)" - + "UNION ALL " - + " SELECT _id " - + " FROM tasks " - + " INNER JOIN recursive_tasks " - + " ON recursive_tasks.task = tasks.parent" - + " WHERE tasks.deleted = 0)" - + "SELECT task FROM recursive_tasks") - abstract fun getChildren(ids: List): List + fun save(task: Task) = runBlocking { + dao.save(task) + } + + fun save(task: Task, original: Task? = fetchBlocking(task.id)) = runBlocking { + dao.save(task, original) + } - @Query("UPDATE tasks SET collapsed = :collapsed WHERE _id = :id") - abstract fun setCollapsed(id: Long, collapsed: Boolean) - - @Transaction - open fun setCollapsed(preferences: Preferences, filter: Filter, collapsed: Boolean) { - fetchTasks(preferences, filter) - .filter(TaskContainer::hasChildren) - .map(TaskContainer::getId) - .eachChunk { collapse(it, collapsed) } - } - - @Query("UPDATE tasks SET collapsed = :collapsed WHERE _id IN (:ids)") - abstract fun collapse(ids: List, collapsed: Boolean) - - // --- save - // TODO: get rid of this super-hack - /** - * Saves the given task to the database.getDatabase(). Task must already exist. Returns true on - * success. - */ - @JvmOverloads - fun save(task: Task, original: Task? = fetchBlocking(task.id)) { - if (!task.insignificantChange(original)) { - task.modificationDate = DateUtilities.now() - } - if (update(task) == 1) { - workManager.afterSave(task, original) - } + fun insert(task: Task): Long = runBlocking { + dao.insert(task) } - @Insert - abstract fun insert(task: Task): Long + fun update(task: Task): Int = runBlocking { + dao.update(task) + } - @Update - abstract fun update(task: Task): Int + fun createNew(task: Task) = runBlocking { + dao.createNew(task) + } - fun createNew(task: Task) { - task.id = NO_ID - if (task.creationDate == 0L) { - task.creationDate = DateUtilities.now() - } - if (Task.isUuidEmpty(task.remoteId)) { - task.remoteId = UUIDHelper.newUUID() - } - val insert = insert(task) - task.id = insert - } - - fun count(filter: Filter): Int { - val query = getQuery(filter.sqlQuery, Field.COUNT) - val start = if (BuildConfig.DEBUG) DateUtilities.now() else 0 - val count = count(query) - Timber.v("%sms: %s", DateUtilities.now() - start, query.sql) - return count + fun count(filter: Filter): Int = runBlocking { + dao.count(filter) } - fun fetchFiltered(filter: Filter): List { - return fetchFiltered(filter.getSqlQuery()) + fun fetchFiltered(filter: Filter): List = runBlocking { + dao.fetchFiltered(filter) } - fun fetchFiltered(queryTemplate: String): List { - val query = getQuery(queryTemplate, Task.FIELDS) - val start = if (BuildConfig.DEBUG) DateUtilities.now() else 0 - val tasks = fetchTasks(query) - Timber.v("%sms: %s", DateUtilities.now() - start, query.sql) - return tasks.map(TaskContainer::getTask) + fun fetchFiltered(queryTemplate: String): List = runBlocking { + dao.fetchFiltered(queryTemplate) } - @Query("SELECT _id FROM tasks LEFT JOIN google_tasks ON _id = gt_task AND gt_deleted = 0 LEFT JOIN caldav_tasks ON _id = cd_task AND cd_deleted = 0 WHERE gt_id IS NULL AND cd_id IS NULL AND parent = 0") - abstract fun getLocalTasks(): List + fun getLocalTasks(): List = runBlocking { + dao.getLocalTasks() + } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/data/AlarmDaoBlocking.kt b/app/src/main/java/org/tasks/data/AlarmDaoBlocking.kt index 2158a3397..f3e242bad 100644 --- a/app/src/main/java/org/tasks/data/AlarmDaoBlocking.kt +++ b/app/src/main/java/org/tasks/data/AlarmDaoBlocking.kt @@ -1,31 +1,31 @@ package org.tasks.data -import androidx.room.Dao -import androidx.room.Delete -import androidx.room.Insert -import androidx.room.Query +import kotlinx.coroutines.runBlocking +import javax.inject.Inject -@Dao -interface AlarmDaoBlocking { - @Query("SELECT alarms.* FROM alarms INNER JOIN tasks ON tasks._id = alarms.task " - + "WHERE tasks.completed = 0 AND tasks.deleted = 0 AND tasks.lastNotified < alarms.time " - + "ORDER BY time ASC") - fun getActiveAlarms(): List +@Deprecated("use coroutines") +class AlarmDaoBlocking @Inject constructor(private val dao: AlarmDao) { + fun getActiveAlarms(): List = runBlocking { + dao.getActiveAlarms() + } - @Query("SELECT alarms.* FROM alarms INNER JOIN tasks ON tasks._id = alarms.task " - + "WHERE tasks._id = :taskId AND tasks.completed = 0 AND tasks.deleted = 0 AND tasks.lastNotified < alarms.time " - + "ORDER BY time ASC") - fun getActiveAlarms(taskId: Long): List + fun getActiveAlarms(taskId: Long): List = runBlocking { + dao.getActiveAlarms(taskId) + } - @Query("SELECT * FROM alarms WHERE task = :taskId ORDER BY time ASC") - fun getAlarms(taskId: Long): List + fun getAlarms(taskId: Long): List = runBlocking { + dao.getAlarms(taskId) + } - @Delete - fun delete(alarm: Alarm) + fun delete(alarm: Alarm) = runBlocking { + dao.delete(alarm) + } - @Insert - fun insert(alarm: Alarm): Long + fun insert(alarm: Alarm): Long = runBlocking { + dao.insert(alarm) + } - @Insert - fun insert(alarms: Iterable) + fun insert(alarms: Iterable) = runBlocking { + dao.insert(alarms) + } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/data/CaldavDaoBlocking.kt b/app/src/main/java/org/tasks/data/CaldavDaoBlocking.kt index d96948426..8f58b40fe 100644 --- a/app/src/main/java/org/tasks/data/CaldavDaoBlocking.kt +++ b/app/src/main/java/org/tasks/data/CaldavDaoBlocking.kt @@ -2,274 +2,232 @@ package org.tasks.data import android.content.Context import androidx.lifecycle.LiveData -import androidx.room.* import com.todoroo.andlib.utility.DateUtilities.now -import com.todoroo.astrid.api.FilterListItem.NO_ORDER -import com.todoroo.astrid.core.SortHelper.APPLE_EPOCH import com.todoroo.astrid.data.Task -import com.todoroo.astrid.helper.UUIDHelper -import org.tasks.R -import org.tasks.data.CaldavDao.Companion.LOCAL -import org.tasks.date.DateTimeUtils.toAppleEpoch -import org.tasks.db.DbUtils.chunkedMap +import kotlinx.coroutines.runBlocking import org.tasks.filters.CaldavFilters import org.tasks.time.DateTimeUtils.currentTimeMillis +import javax.inject.Inject -@Dao -abstract class CaldavDaoBlocking { - @Query("SELECT * FROM caldav_lists") - abstract fun subscribeToCalendars(): LiveData> +@Deprecated("use coroutines") +class CaldavDaoBlocking @Inject constructor(private val dao: CaldavDao) { + fun subscribeToCalendars(): LiveData> { + return dao.subscribeToCalendars() + } + + fun getCalendarByUuid(uuid: String): CaldavCalendar? = runBlocking { + dao.getCalendarByUuid(uuid) + } + + fun getCalendarsByAccount(uuid: String): List = runBlocking { + dao.getCalendarsByAccount(uuid) + } + + fun getAccountByUuid(uuid: String): CaldavAccount? = runBlocking { + dao.getAccountByUuid(uuid) + } + + fun accountCount(): Int = runBlocking { + dao.accountCount() + } + + fun getAccounts(): List = runBlocking { + dao.getAccounts() + } + + fun setCollapsed(id: Long, collapsed: Boolean) = runBlocking { + dao.setCollapsed(id, collapsed) + } + + fun insert(caldavAccount: CaldavAccount): Long = runBlocking { + dao.insert(caldavAccount) + } + + fun update(caldavAccount: CaldavAccount) = runBlocking { + dao.update(caldavAccount) + } + + fun insert(caldavCalendar: CaldavCalendar) = runBlocking { + dao.insert(caldavCalendar) + } + + fun insertInternal(caldavCalendar: CaldavCalendar): Long = runBlocking { + dao.insertInternal(caldavCalendar) + } + + fun update(caldavCalendar: CaldavCalendar) = runBlocking { + dao.update(caldavCalendar) + } + + fun insert(task: Task, caldavTask: CaldavTask, addToTop: Boolean): Long = runBlocking { + dao.insert(task, caldavTask, addToTop) + } + + internal fun findFirstTask(calendar: String, parent: Long): Long? = runBlocking { + dao.findFirstTask(calendar, parent) + } + + internal fun findLastTask(calendar: String, parent: Long): Long? = runBlocking { + dao.findLastTask(calendar, parent) + } + + fun insert(caldavTask: CaldavTask): Long = runBlocking { + dao.insert(caldavTask) + } + + fun insert(tasks: Iterable) = runBlocking { + dao.insert(tasks) + } + + fun update(caldavTask: CaldavTask) = runBlocking { + dao.update(caldavTask) + } + + fun update(caldavTask: SubsetCaldav) = runBlocking { + dao.update(caldavTask) + } - @Query("SELECT * FROM caldav_lists WHERE cdl_uuid = :uuid LIMIT 1") - abstract fun getCalendarByUuid(uuid: String): CaldavCalendar? + internal fun update(id: Long, position: Long?, parent: String?) = runBlocking { + dao.update(id, position, parent) + } - @Query("SELECT * FROM caldav_lists WHERE cdl_account = :uuid") - abstract fun getCalendarsByAccount(uuid: String): List + internal fun update(id: Long, position: Long?) = runBlocking { + dao.update(id, position) + } - @Query("SELECT * FROM caldav_accounts WHERE cda_uuid = :uuid LIMIT 1") - abstract fun getAccountByUuid(uuid: String): CaldavAccount? + internal fun update(id: Long, remoteParent: String?) = runBlocking { + dao.update(id, remoteParent) + } - @Query("SELECT COUNT(*) FROM caldav_accounts WHERE cda_account_type != 2") - abstract fun accountCount(): Int + fun update(tasks: Iterable) = runBlocking { + dao.update(tasks) + } - @Query("SELECT * FROM caldav_accounts ORDER BY cda_account_type, UPPER(cda_name)") - abstract fun getAccounts(): List + fun delete(caldavTask: CaldavTask) = runBlocking { + dao.delete(caldavTask) + } - @Query("UPDATE caldav_accounts SET cda_collapsed = :collapsed WHERE cda_id = :id") - abstract fun setCollapsed(id: Long, collapsed: Boolean) + fun getDeleted(calendar: String): List = runBlocking { + dao.getDeleted(calendar) + } - @Insert - abstract fun insert(caldavAccount: CaldavAccount): Long + fun markDeleted(tasks: List, now: Long = currentTimeMillis()) = runBlocking { + dao.markDeleted(tasks, now) + } - @Update - abstract fun update(caldavAccount: CaldavAccount) + fun getTask(taskId: Long): CaldavTask? = runBlocking { + dao.getTask(taskId) + } - fun insert(caldavCalendar: CaldavCalendar) { - caldavCalendar.id = insertInternal(caldavCalendar) + fun getRemoteIdForTask(taskId: Long): String? = runBlocking { + dao.getRemoteIdForTask(taskId) } - @Insert - abstract fun insertInternal(caldavCalendar: CaldavCalendar): Long + fun getTask(calendar: String, obj: String): CaldavTask? = runBlocking { + dao.getTask(calendar, obj) + } - @Update - abstract fun update(caldavCalendar: CaldavCalendar) + fun getTaskByRemoteId(calendar: String, remoteId: String): CaldavTask? = runBlocking { + dao.getTaskByRemoteId(calendar, remoteId) + } - @Transaction - open fun insert(task: Task, caldavTask: CaldavTask, addToTop: Boolean): Long { - if (caldavTask.order != null) { - return insert(caldavTask) - } - if (addToTop) { - caldavTask.order = findFirstTask(caldavTask.calendar!!, task.parent) - ?.takeIf { task.creationDate.toAppleEpoch() >= it } - ?.minus(1) - } else { - caldavTask.order = findLastTask(caldavTask.calendar!!, task.parent) - ?.takeIf { task.creationDate.toAppleEpoch() <= it } - ?.plus(1) - } - return insert(caldavTask) + fun getTasks(taskId: Long): List = runBlocking { + dao.getTasks(taskId) } - @Query("SELECT MIN(IFNULL(cd_order, (created - $APPLE_EPOCH) / 1000)) FROM caldav_tasks INNER JOIN tasks ON _id = cd_task WHERE cd_calendar = :calendar AND cd_deleted = 0 AND deleted = 0 AND parent = :parent") - internal abstract fun findFirstTask(calendar: String, parent: Long): Long? + fun getTasks(taskIds: List): List = runBlocking { + dao.getTasks(taskIds) + } - @Query("SELECT MAX(IFNULL(cd_order, (created - $APPLE_EPOCH) / 1000)) FROM caldav_tasks INNER JOIN tasks ON _id = cd_task WHERE cd_calendar = :calendar AND cd_deleted = 0 AND deleted = 0 AND parent = :parent") - internal abstract fun findLastTask(calendar: String, parent: Long): Long? + fun getTasks(): List = runBlocking { + dao.getTasks() + } - @Insert - abstract fun insert(caldavTask: CaldavTask): Long + fun getCaldavTasksToPush(calendar: String): List = runBlocking { + dao.getCaldavTasksToPush(calendar) + } - @Insert - abstract fun insert(tasks: Iterable) + fun getCalendars(): List = runBlocking { + dao.getCalendars() + } - @Update - abstract fun update(caldavTask: CaldavTask) + fun getCalendar(uuid: String): CaldavCalendar? = runBlocking { + dao.getCalendar(uuid) + } - fun update(caldavTask: SubsetCaldav) { - update(caldavTask.cd_id, caldavTask.cd_order, caldavTask.cd_remote_parent) + fun getObjects(calendar: String): List = runBlocking { + dao.getObjects(calendar) } - @Query("UPDATE caldav_tasks SET cd_order = :position, cd_remote_parent = :parent WHERE cd_id = :id") - internal abstract fun update(id: Long, position: Long?, parent: String?) + fun getTasks(calendar: String, objects: List): List = runBlocking { + dao.getTasks(calendar, objects) + } - @Query("UPDATE caldav_tasks SET cd_order = :position WHERE cd_id = :id") - internal abstract fun update(id: Long, position: Long?) + fun getTasksInternal(calendar: String, objects: List): List = runBlocking { + dao.getTasksInternal(calendar, objects) + } - @Query("UPDATE caldav_tasks SET cd_remote_parent = :remoteParent WHERE cd_id = :id") - internal abstract fun update(id: Long, remoteParent: String?) + fun findDeletedCalendars(account: String, urls: List): List = runBlocking { + dao.findDeletedCalendars(account, urls) + } - @Update - abstract fun update(tasks: Iterable) + fun getCalendarByUrl(account: String, url: String): CaldavCalendar? = runBlocking { + dao.getCalendarByUrl(account, url) + } - @Delete - abstract fun delete(caldavTask: CaldavTask) + fun getAccountForTask(task: Long): CaldavAccount? = runBlocking { + dao.getAccountForTask(task) + } + + fun getCalendars(tasks: List): List = runBlocking { + dao.getCalendars(tasks) + } + + fun getCaldavFilters(uuid: String, now: Long = currentTimeMillis()): List = runBlocking { + dao.getCaldavFilters(uuid, now) + } + + fun getTasksWithTags(): List = runBlocking { + dao.getTasksWithTags() + } + + fun updateParents() = runBlocking { + dao.updateParents() + } - @Query("SELECT * FROM caldav_tasks WHERE cd_deleted > 0 AND cd_calendar = :calendar") - abstract fun getDeleted(calendar: String): List + fun updateParents(calendar: String) = runBlocking { + dao.updateParents(calendar) + } - @Query("UPDATE caldav_tasks SET cd_deleted = :now WHERE cd_task IN (:tasks)") - abstract fun markDeleted(tasks: List, now: Long = currentTimeMillis()) + fun move(task: TaskContainer, newParent: Long, newPosition: Long?) = runBlocking { + dao.move(task, newParent, newPosition) + } - @Query("SELECT * FROM caldav_tasks WHERE cd_task = :taskId AND cd_deleted = 0 LIMIT 1") - abstract fun getTask(taskId: Long): CaldavTask? + fun shiftDown(calendar: String, parent: Long, from: Long, to: Long? = null) = runBlocking { + dao.shiftDown(calendar, parent, from, to) + } - @Query("SELECT cd_remote_id FROM caldav_tasks WHERE cd_task = :taskId AND cd_deleted = 0") - abstract fun getRemoteIdForTask(taskId: Long): String? + internal fun touchInternal(ids: List, modificationTime: Long = now()) = runBlocking { + dao.touchInternal(ids, modificationTime) + } - @Query("SELECT * FROM caldav_tasks WHERE cd_calendar = :calendar AND cd_object = :obj LIMIT 1") - abstract fun getTask(calendar: String, obj: String): CaldavTask? + internal fun getTasksToShift(calendar: String, parent: Long, from: Long, to: Long?): List = runBlocking { + dao.getTasksToShift(calendar, parent, from, to) + } - @Query("SELECT * FROM caldav_tasks WHERE cd_calendar = :calendar AND cd_remote_id = :remoteId") - abstract fun getTaskByRemoteId(calendar: String, remoteId: String): CaldavTask? + fun resetOrders() = runBlocking { + dao.resetOrders() + } - @Query("SELECT * FROM caldav_tasks WHERE cd_task = :taskId") - abstract fun getTasks(taskId: Long): List + fun setOrder(id: Long, order: Int) = runBlocking { + dao.setOrder(id, order) + } - @Query("SELECT * FROM caldav_tasks WHERE cd_task in (:taskIds) AND cd_deleted = 0") - abstract fun getTasks(taskIds: List): List - - @Query("SELECT task.*, caldav_task.* FROM tasks AS task " - + "INNER JOIN caldav_tasks AS caldav_task ON _id = cd_task " - + "WHERE cd_deleted = 0 AND cd_vtodo IS NOT NULL AND cd_vtodo != ''") - abstract fun getTasks(): List - - @Query("SELECT task.*, caldav_task.* FROM tasks AS task " - + "INNER JOIN caldav_tasks AS caldav_task ON _id = cd_task " - + "WHERE cd_calendar = :calendar " - + "AND modified > cd_last_sync " - + "AND cd_deleted = 0") - abstract fun getCaldavTasksToPush(calendar: String): List - - @Query("SELECT * FROM caldav_lists ORDER BY cdl_name COLLATE NOCASE") - abstract fun getCalendars(): List - - @Query("SELECT * FROM caldav_lists WHERE cdl_uuid = :uuid LIMIT 1") - abstract fun getCalendar(uuid: String): CaldavCalendar? - - @Query("SELECT cd_object FROM caldav_tasks WHERE cd_calendar = :calendar") - abstract fun getObjects(calendar: String): List - - fun getTasks(calendar: String, objects: List): List = - objects.chunkedMap { getTasksInternal(calendar, it) } - - @Query("SELECT cd_task FROM caldav_tasks WHERE cd_calendar = :calendar AND cd_object IN (:objects)") - abstract fun getTasksInternal(calendar: String, objects: List): List - - @Query("SELECT * FROM caldav_lists WHERE cdl_account = :account AND cdl_url NOT IN (:urls)") - abstract fun findDeletedCalendars(account: String, urls: List): List - - @Query("SELECT * FROM caldav_lists WHERE cdl_account = :account AND cdl_url = :url LIMIT 1") - abstract fun getCalendarByUrl(account: String, url: String): CaldavCalendar? - - @Query("SELECT caldav_accounts.* from caldav_accounts" - + " INNER JOIN caldav_tasks ON cd_task = :task" - + " INNER JOIN caldav_lists ON cd_calendar = cdl_uuid" - + " WHERE cdl_account = cda_uuid") - abstract fun getAccountForTask(task: Long): CaldavAccount? + fun setupLocalAccount(context: Context): CaldavAccount = runBlocking { + dao.setupLocalAccount(context) + } - @Query("SELECT DISTINCT cd_calendar FROM caldav_tasks WHERE cd_deleted = 0 AND cd_task IN (:tasks)") - abstract fun getCalendars(tasks: List): List - - @Query("SELECT caldav_lists.*, COUNT(tasks._id) AS count" - + " FROM caldav_lists" - + " LEFT JOIN caldav_tasks ON caldav_tasks.cd_calendar = caldav_lists.cdl_uuid" - + " LEFT JOIN tasks ON caldav_tasks.cd_task = tasks._id AND tasks.deleted = 0 AND tasks.completed = 0 AND tasks.hideUntil < :now AND cd_deleted = 0" - + " WHERE caldav_lists.cdl_account = :uuid" - + " GROUP BY caldav_lists.cdl_uuid") - abstract fun getCaldavFilters(uuid: String, now: Long = currentTimeMillis()): List - - @Query("SELECT tasks._id FROM tasks " - + "INNER JOIN tags ON tags.task = tasks._id " - + "INNER JOIN caldav_tasks ON cd_task = tasks._id " - + "GROUP BY tasks._id") - abstract fun getTasksWithTags(): List - - @Query("UPDATE tasks SET parent = IFNULL((" - + " SELECT p.cd_task FROM caldav_tasks AS p" - + " INNER JOIN caldav_tasks ON caldav_tasks.cd_task = tasks._id" - + " WHERE p.cd_remote_id = caldav_tasks.cd_remote_parent" - + " AND p.cd_calendar = caldav_tasks.cd_calendar" - + " AND p.cd_deleted = 0), 0)" - + "WHERE _id IN (SELECT _id FROM tasks INNER JOIN caldav_tasks ON _id = cd_task WHERE cd_deleted = 0)") - abstract fun updateParents() - - @Query("UPDATE tasks SET parent = IFNULL((" - + " SELECT p.cd_task FROM caldav_tasks AS p" - + " INNER JOIN caldav_tasks " - + " ON caldav_tasks.cd_task = tasks._id" - + " AND caldav_tasks.cd_calendar = :calendar" - + " WHERE p.cd_remote_id = caldav_tasks.cd_remote_parent" - + " AND p.cd_calendar = caldav_tasks.cd_calendar" - + " AND caldav_tasks.cd_deleted = 0), 0)" - + "WHERE _id IN (SELECT _id FROM tasks INNER JOIN caldav_tasks ON _id = cd_task WHERE cd_deleted = 0 AND cd_calendar = :calendar)") - abstract fun updateParents(calendar: String) - - @Transaction - open fun move(task: TaskContainer, newParent: Long, newPosition: Long?) { - val previousParent = task.parent - val caldavTask = task.caldavTask - val previousPosition = task.caldavSortOrder - if (newPosition != null) { - if (newParent == previousParent && newPosition < previousPosition) { - shiftDown(task.caldav!!, newParent, newPosition, previousPosition) - } else { - shiftDown(task.caldav!!, newParent, newPosition) - } - } - caldavTask.cd_order = newPosition - update(caldavTask.cd_id, caldavTask.cd_order) - } - - @Transaction - open fun shiftDown(calendar: String, parent: Long, from: Long, to: Long? = null) { - val updated = ArrayList() - val tasks = getTasksToShift(calendar, parent, from, to) - for (i in tasks.indices) { - val task = tasks[i] - val current = from + i - if (task.sortOrder == current) { - val caldavTask = task.caldavTask - caldavTask.order = current + 1 - updated.add(caldavTask) - } else if (task.sortOrder > current) { - break - } - } - update(updated) - touchInternal(updated.map(CaldavTask::task)) - } - - @Query("UPDATE tasks SET modified = :modificationTime WHERE _id in (:ids)") - internal abstract fun touchInternal(ids: List, modificationTime: Long = now()) - - @Query("SELECT task.*, caldav_task.*, IFNULL(cd_order, (created - $APPLE_EPOCH) / 1000) AS primary_sort FROM caldav_tasks AS caldav_task INNER JOIN tasks AS task ON _id = cd_task WHERE cd_calendar = :calendar AND parent = :parent AND cd_deleted = 0 AND deleted = 0 AND primary_sort >= :from AND primary_sort < IFNULL(:to, ${Long.MAX_VALUE}) ORDER BY primary_sort") - internal abstract fun getTasksToShift(calendar: String, parent: Long, from: Long, to: Long?): List - - @Query("UPDATE caldav_lists SET cdl_order = $NO_ORDER") - abstract fun resetOrders() - - @Query("UPDATE caldav_lists SET cdl_order = :order WHERE cdl_id = :id") - abstract fun setOrder(id: Long, order: Int) - - fun setupLocalAccount(context: Context): CaldavAccount { - val account = getLocalAccount() - getLocalList(context, account) - return account - } - - fun getLocalList(context: Context) = getLocalList(context, getLocalAccount()) - - private fun getLocalAccount() = getAccountByUuid(LOCAL) ?: CaldavAccount().apply { - accountType = CaldavAccount.TYPE_LOCAL - uuid = LOCAL - id = insert(this) - } - - private fun getLocalList(context: Context, account: CaldavAccount): CaldavCalendar = - getCalendarsByAccount(account.uuid!!).getOrNull(0) - ?: CaldavCalendar(context.getString(R.string.default_list), UUIDHelper.newUUID()).apply { - this.account = account.uuid - insert(this) - } + fun getLocalList(context: Context) = runBlocking { + dao.getLocalList(context) + } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/data/ContentProviderDaoBlocking.kt b/app/src/main/java/org/tasks/data/ContentProviderDaoBlocking.kt index 5407fc46b..0e6e6a28c 100644 --- a/app/src/main/java/org/tasks/data/ContentProviderDaoBlocking.kt +++ b/app/src/main/java/org/tasks/data/ContentProviderDaoBlocking.kt @@ -1,47 +1,38 @@ package org.tasks.data import android.database.Cursor -import androidx.room.Dao -import androidx.room.Query -import androidx.room.RawQuery import androidx.sqlite.db.SupportSQLiteQuery import com.todoroo.astrid.data.Task - -@Dao -interface ContentProviderDaoBlocking { - @Query("SELECT name FROM tags WHERE task = :taskId ORDER BY UPPER(name) ASC") - fun getTagNames(taskId: Long): List - - @Query(""" - SELECT * - FROM tasks - WHERE completed = 0 - AND deleted = 0 - AND hideUntil < (strftime('%s', 'now') * 1000) - ORDER BY (CASE - WHEN (dueDate = 0) THEN - (strftime('%s', 'now') * 1000) * 2 - ELSE ((CASE WHEN (dueDate / 1000) % 60 > 0 THEN dueDate ELSE (dueDate + 43140000) END)) END) + - 172800000 * importance - ASC - LIMIT 100""") - fun getAstrid2TaskProviderTasks(): List - - @Query("SELECT * FROM tagdata WHERE name IS NOT NULL AND name != '' ORDER BY UPPER(name) ASC") - fun tagDataOrderedByName(): List - - @Query("SELECT * FROM tasks") - fun getTasks(): Cursor - - @Query(""" - SELECT caldav_lists.*, caldav_accounts.cda_name - FROM caldav_lists - INNER JOIN caldav_accounts ON cdl_account = cda_uuid""") - fun getLists(): Cursor - - @Query("SELECT * FROM google_task_lists") - fun getGoogleTaskLists(): Cursor - - @RawQuery - fun rawQuery(query: SupportSQLiteQuery): Cursor +import kotlinx.coroutines.runBlocking +import javax.inject.Inject + +@Deprecated("use coroutines") +class ContentProviderDaoBlocking @Inject constructor(private val dao: ContentProviderDao) { + fun getTagNames(taskId: Long): List = runBlocking { + dao.getTagNames(taskId) + } + + fun getAstrid2TaskProviderTasks(): List = runBlocking { + dao.getAstrid2TaskProviderTasks() + } + + fun tagDataOrderedByName(): List = runBlocking { + dao.tagDataOrderedByName() + } + + fun getTasks(): Cursor { + return dao.getTasks() + } + + fun getLists(): Cursor { + return dao.getLists() + } + + fun getGoogleTaskLists(): Cursor { + return dao.getGoogleTaskLists() + } + + fun rawQuery(query: SupportSQLiteQuery): Cursor { + return dao.rawQuery(query) + } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/data/DeletionDaoBlocking.kt b/app/src/main/java/org/tasks/data/DeletionDaoBlocking.kt index 2ab6e89a4..a89b1a862 100644 --- a/app/src/main/java/org/tasks/data/DeletionDaoBlocking.kt +++ b/app/src/main/java/org/tasks/data/DeletionDaoBlocking.kt @@ -1,114 +1,95 @@ package org.tasks.data -import androidx.room.Dao -import androidx.room.Delete -import androidx.room.Query -import androidx.room.Transaction -import org.tasks.data.CaldavDao.Companion.LOCAL -import org.tasks.db.DbUtils.eachChunk -import java.util.* +import kotlinx.coroutines.runBlocking +import javax.inject.Inject -@Dao -abstract class DeletionDaoBlocking { - @Query("DELETE FROM caldav_tasks WHERE cd_task IN(:ids)") - abstract fun deleteCaldavTasks(ids: List) +@Deprecated("use coroutines") +class DeletionDaoBlocking @Inject constructor(private val dao: DeletionDao) { + fun deleteCaldavTasks(ids: List) = runBlocking { + dao.deleteCaldavTasks(ids) + } - @Query("DELETE FROM google_tasks WHERE gt_task IN(:ids)") - abstract fun deleteGoogleTasks(ids: List) + fun deleteGoogleTasks(ids: List) = runBlocking { + dao.deleteGoogleTasks(ids) + } - @Query("DELETE FROM tags WHERE task IN(:ids)") - abstract fun deleteTags(ids: List) + fun deleteTags(ids: List) = runBlocking { + dao.deleteTags(ids) + } - @Query("DELETE FROM geofences WHERE task IN(:ids)") - abstract fun deleteGeofences(ids: List) + fun deleteGeofences(ids: List) = runBlocking { + dao.deleteGeofences(ids) + } - @Query("DELETE FROM alarms WHERE task IN(:ids)") - abstract fun deleteAlarms(ids: List) + fun deleteAlarms(ids: List) = runBlocking { + dao.deleteAlarms(ids) + } - @Query("DELETE FROM tasks WHERE _id IN(:ids)") - abstract fun deleteTasks(ids: List) + fun deleteTasks(ids: List) = runBlocking { + dao.deleteTasks(ids) + } - @Transaction - open fun delete(ids: List) { - ids.eachChunk { - deleteAlarms(it) - deleteGeofences(it) - deleteTags(it) - deleteGoogleTasks(it) - deleteCaldavTasks(it) - deleteTasks(it) - } + fun delete(ids: List) = runBlocking { + dao.delete(ids) } - @Query("UPDATE tasks " - + "SET modified = (strftime('%s','now')*1000), deleted = (strftime('%s','now')*1000)" - + "WHERE _id IN(:ids)") - abstract fun markDeletedInternal(ids: List) + fun markDeletedInternal(ids: List) = runBlocking { + dao.markDeletedInternal(ids) + } - fun markDeleted(ids: Iterable) { - ids.eachChunk(this::markDeletedInternal) + fun markDeleted(ids: Iterable) = runBlocking { + dao.markDeleted(ids) } - @Query("SELECT gt_task FROM google_tasks WHERE gt_deleted = 0 AND gt_list_id = :listId") - abstract fun getActiveGoogleTasks(listId: String): List + fun getActiveGoogleTasks(listId: String): List = runBlocking { + dao.getActiveGoogleTasks(listId) + } - @Delete - abstract fun deleteGoogleTaskList(googleTaskList: GoogleTaskList) + fun deleteGoogleTaskList(googleTaskList: GoogleTaskList) = runBlocking { + dao.deleteGoogleTaskList(googleTaskList) + } - @Transaction - open fun delete(googleTaskList: GoogleTaskList): List { - val tasks = getActiveGoogleTasks(googleTaskList.remoteId!!) - delete(tasks) - deleteGoogleTaskList(googleTaskList) - return tasks + fun delete(googleTaskList: GoogleTaskList): List = runBlocking { + dao.delete(googleTaskList) } - @Delete - abstract fun deleteGoogleTaskAccount(googleTaskAccount: GoogleTaskAccount) + fun deleteGoogleTaskAccount(googleTaskAccount: GoogleTaskAccount) = runBlocking { + dao.deleteGoogleTaskAccount(googleTaskAccount) + } - @Query("SELECT * FROM google_task_lists WHERE gtl_account = :account ORDER BY gtl_title ASC") - abstract fun getLists(account: String): List + fun getLists(account: String): List = runBlocking { + dao.getLists(account) + } - @Transaction - open fun delete(googleTaskAccount: GoogleTaskAccount): List { - val deleted = ArrayList() - for (list in getLists(googleTaskAccount.account!!)) { - deleted.addAll(delete(list)) - } - deleteGoogleTaskAccount(googleTaskAccount) - return deleted + fun delete(googleTaskAccount: GoogleTaskAccount): List = runBlocking { + dao.delete(googleTaskAccount) } - @Query("SELECT cd_task FROM caldav_tasks WHERE cd_calendar = :calendar AND cd_deleted = 0") - abstract fun getActiveCaldavTasks(calendar: String): List + fun getActiveCaldavTasks(calendar: String): List = runBlocking { + dao.getActiveCaldavTasks(calendar) + } - @Delete - abstract fun deleteCaldavCalendar(caldavCalendar: CaldavCalendar) + fun deleteCaldavCalendar(caldavCalendar: CaldavCalendar) = runBlocking { + dao.deleteCaldavCalendar(caldavCalendar) + } - @Transaction - open fun delete(caldavCalendar: CaldavCalendar): List { - val tasks = getActiveCaldavTasks(caldavCalendar.uuid!!) - delete(tasks) - deleteCaldavCalendar(caldavCalendar) - return tasks + fun delete(caldavCalendar: CaldavCalendar): List = runBlocking { + dao.delete(caldavCalendar) } - @Query("SELECT * FROM caldav_lists WHERE cdl_account = :account") - abstract fun getCalendars(account: String): List + fun getCalendars(account: String): List = runBlocking { + dao.getCalendars(account) + } - @Delete - abstract fun deleteCaldavAccount(caldavAccount: CaldavAccount) + fun deleteCaldavAccount(caldavAccount: CaldavAccount) = runBlocking { + dao.deleteCaldavAccount(caldavAccount) + } - @Query("DELETE FROM tasks WHERE _id IN (SELECT _id FROM tasks INNER JOIN caldav_tasks ON _id = cd_task INNER JOIN caldav_lists ON cdl_uuid = cd_calendar WHERE cdl_account = '$LOCAL' AND deleted > 0)") - abstract fun purgeDeleted() + fun purgeDeleted() = runBlocking { + dao.purgeDeleted() + } - @Transaction - open fun delete(caldavAccount: CaldavAccount): List { - val deleted = ArrayList() - for (calendar in getCalendars(caldavAccount.uuid!!)) { - deleted.addAll(delete(calendar)) - } - deleteCaldavAccount(caldavAccount) - return deleted + fun delete(caldavAccount: CaldavAccount): List = runBlocking { + dao.delete(caldavAccount) } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/data/FilterDaoBlocking.kt b/app/src/main/java/org/tasks/data/FilterDaoBlocking.kt index 4e6d027b2..0568e8a3d 100644 --- a/app/src/main/java/org/tasks/data/FilterDaoBlocking.kt +++ b/app/src/main/java/org/tasks/data/FilterDaoBlocking.kt @@ -1,37 +1,43 @@ package org.tasks.data -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.Query -import androidx.room.Update -import com.todoroo.astrid.api.FilterListItem.NO_ORDER - -@Dao -interface FilterDaoBlocking { - @Update - fun update(filter: Filter) - - @Query("DELETE FROM filters WHERE _id = :id") - fun delete(id: Long) - - @Query("SELECT * FROM filters WHERE title = :title COLLATE NOCASE LIMIT 1") - fun getByName(title: String): Filter? - - @Insert - fun insert(filter: Filter): Long - - @Query("SELECT * FROM filters") - fun getFilters(): List - - @Query("SELECT * FROM filters WHERE _id = :id LIMIT 1") - fun getById(id: Long): Filter? - - @Query("SELECT * FROM filters") - fun getAll(): List - - @Query("UPDATE filters SET f_order = $NO_ORDER") - fun resetOrders() - - @Query("UPDATE filters SET f_order = :order WHERE _id = :id") - fun setOrder(id: Long, order: Int) +import kotlinx.coroutines.runBlocking +import javax.inject.Inject + +@Deprecated("use coroutines") +class FilterDaoBlocking @Inject constructor(private val dao: FilterDao) { + fun update(filter: Filter) = runBlocking { + dao.update(filter) + } + + fun delete(id: Long) = runBlocking { + dao.delete(id) + } + + fun getByName(title: String): Filter? = runBlocking { + dao.getByName(title) + } + + fun insert(filter: Filter): Long = runBlocking { + dao.insert(filter) + } + + fun getFilters(): List = runBlocking { + dao.getFilters() + } + + fun getById(id: Long): Filter? = runBlocking { + dao.getById(id) + } + + fun getAll(): List = runBlocking { + dao.getAll() + } + + fun resetOrders() = runBlocking { + dao.resetOrders() + } + + fun setOrder(id: Long, order: Int) = runBlocking { + dao.setOrder(id, order) + } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/data/GoogleTaskDaoBlocking.kt b/app/src/main/java/org/tasks/data/GoogleTaskDaoBlocking.kt index 7f833e580..c90f587b4 100644 --- a/app/src/main/java/org/tasks/data/GoogleTaskDaoBlocking.kt +++ b/app/src/main/java/org/tasks/data/GoogleTaskDaoBlocking.kt @@ -1,179 +1,137 @@ package org.tasks.data -import androidx.room.* import com.todoroo.astrid.data.Task +import kotlinx.coroutines.runBlocking import org.tasks.time.DateTimeUtils.currentTimeMillis +import javax.inject.Inject -@Dao -abstract class GoogleTaskDaoBlocking { - @Insert - abstract fun insert(task: GoogleTask): Long +@Deprecated("use coroutines") +class GoogleTaskDaoBlocking @Inject constructor(private val dao: GoogleTaskDao) { + fun insert(task: GoogleTask): Long = runBlocking { + dao.insert(task) + } + + fun insert(tasks: Iterable) = runBlocking { + dao.insert(tasks) + } + + fun insertAndShift(task: GoogleTask, top: Boolean) = runBlocking { + dao.insertAndShift(task, top) + } + + fun shiftDown(listId: String, parent: Long, position: Long) = runBlocking { + dao.shiftDown(listId, parent, position) + } + + fun shiftUp(listId: String, parent: Long, from: Long, to: Long) = runBlocking { + dao.shiftUp(listId, parent, from, to) + } + + fun shiftDown(listId: String, parent: Long, from: Long, to: Long) = runBlocking { + dao.shiftDown(listId, parent, from, to) + } + + fun shiftUp(listId: String, parent: Long, position: Long) = runBlocking { + dao.shiftUp(listId, parent, position) + } + + fun move(task: SubsetGoogleTask, newParent: Long, newPosition: Long) = runBlocking { + dao.move(task, newParent, newPosition) + } + + fun setCollapsed(id: Long, collapsed: Boolean) = runBlocking { + dao.setCollapsed(id, collapsed) + } + + fun getByTaskId(taskId: Long): GoogleTask? = runBlocking { + dao.getByTaskId(taskId) + } + + fun update(googleTask: GoogleTask) = runBlocking { + dao.update(googleTask) + } + + fun update(id: Long, parent: Long, order: Long) = runBlocking { + dao.update(id, parent, order) + } + + fun markDeleted(task: Long, now: Long = currentTimeMillis()) = runBlocking { + dao.markDeleted(task, now) + } + + fun delete(deleted: GoogleTask) = runBlocking { + dao.delete(deleted) + } - @Insert - abstract fun insert(tasks: Iterable) + fun getByRemoteId(remoteId: String): GoogleTask? = runBlocking { + dao.getByRemoteId(remoteId) + } + + fun getDeletedByTaskId(taskId: Long): List = runBlocking { + dao.getDeletedByTaskId(taskId) + } + + fun getAllByTaskId(taskId: Long): List = runBlocking { + dao.getAllByTaskId(taskId) + } + + fun getLists(tasks: List): List = runBlocking { + dao.getLists(tasks) + } - @Transaction - open fun insertAndShift(task: GoogleTask, top: Boolean) { - if (top) { - task.order = 0 - shiftDown(task.listId!!, task.parent, 0) - } else { - task.order = getBottom(task.listId!!, task.parent) - } - task.id = insert(task) + fun getChildren(ids: List): List = runBlocking { + dao.getChildren(ids) } - @Query("UPDATE google_tasks SET gt_order = gt_order + 1 WHERE gt_list_id = :listId AND gt_parent = :parent AND gt_order >= :position") - abstract fun shiftDown(listId: String, parent: Long, position: Long) + fun getChildTasks(taskId: Long): List = runBlocking { + dao.getChildTasks(taskId) + } + + fun getChildren(id: Long): List = runBlocking { + dao.getChildren(id) + } - @Query("UPDATE google_tasks SET gt_order = gt_order - 1 WHERE gt_list_id = :listId AND gt_parent = :parent AND gt_order > :from AND gt_order <= :to") - abstract fun shiftUp(listId: String, parent: Long, from: Long, to: Long) + fun getBottom(listId: String, parent: Long): Long = runBlocking { + dao.getBottom(listId, parent) + } - @Query("UPDATE google_tasks SET gt_order = gt_order + 1 WHERE gt_list_id = :listId AND gt_parent = :parent AND gt_order < :from AND gt_order >= :to") - abstract fun shiftDown(listId: String, parent: Long, from: Long, to: Long) + fun getPrevious(listId: String, parent: Long, order: Long): String? = runBlocking { + dao.getPrevious(listId, parent, order) + } + + fun getRemoteId(task: Long): String? = runBlocking { + dao.getRemoteId(task) + } - @Query("UPDATE google_tasks SET gt_order = gt_order - 1 WHERE gt_list_id = :listId AND gt_parent = :parent AND gt_order >= :position") - abstract fun shiftUp(listId: String, parent: Long, position: Long) + fun getTask(remoteId: String): Long = runBlocking { + dao.getTask(remoteId) + } + + fun getByLocalOrder(listId: String): List = runBlocking { + dao.getByLocalOrder(listId) + } + + fun getByRemoteOrder(listId: String): List = runBlocking { + dao.getByRemoteOrder(listId) + } + + fun updateParents() = runBlocking { + dao.updateParents() + } + + fun updateParents(listId: String) = runBlocking { + dao.updateParents(listId) + } + + fun updatePosition(id: String, parent: String, position: String) = runBlocking { + dao.updatePosition(id, parent, position) + } + + fun reposition(listId: String) = runBlocking { + dao.reposition(listId) + } - @Transaction - open fun move(task: SubsetGoogleTask, newParent: Long, newPosition: Long) { - val previousParent = task.parent - val previousPosition = task.order - if (newParent == previousParent) { - if (previousPosition < newPosition) { - shiftUp(task.listId, newParent, previousPosition, newPosition) - } else { - shiftDown(task.listId, newParent, previousPosition, newPosition) - } - } else { - shiftUp(task.listId, previousParent, previousPosition) - shiftDown(task.listId, newParent, newPosition) - } - task.parent = newParent - task.order = newPosition - update(task) - } - - @Query("UPDATE google_task_accounts SET gta_collapsed = :collapsed WHERE gta_id = :id") - abstract fun setCollapsed(id: Long, collapsed: Boolean) - - @Query("SELECT * FROM google_tasks WHERE gt_task = :taskId AND gt_deleted = 0 LIMIT 1") - abstract fun getByTaskId(taskId: Long): GoogleTask? - - @Update - abstract fun update(googleTask: GoogleTask) - - private fun update(googleTask: SubsetGoogleTask) { - update(googleTask.id, googleTask.parent, googleTask.order) - } - - @Query("UPDATE google_tasks SET gt_order = :order, gt_parent = :parent, gt_moved = 1 WHERE gt_id = :id") - abstract fun update(id: Long, parent: Long, order: Long) - - @Query("UPDATE google_tasks SET gt_deleted = :now WHERE gt_task = :task OR gt_parent = :task") - abstract fun markDeleted(task: Long, now: Long = currentTimeMillis()) - - @Delete - abstract fun delete(deleted: GoogleTask) - - @Query("SELECT * FROM google_tasks WHERE gt_remote_id = :remoteId LIMIT 1") - abstract fun getByRemoteId(remoteId: String): GoogleTask? - - @Query("SELECT * FROM google_tasks WHERE gt_task = :taskId AND gt_deleted > 0") - abstract fun getDeletedByTaskId(taskId: Long): List - - @Query("SELECT * FROM google_tasks WHERE gt_task = :taskId") - abstract fun getAllByTaskId(taskId: Long): List - - @Query("SELECT DISTINCT gt_list_id FROM google_tasks WHERE gt_deleted = 0 AND gt_task IN (:tasks)") - abstract fun getLists(tasks: List): List - - @Query("SELECT gt_task FROM google_tasks WHERE gt_parent IN (:ids) AND gt_deleted = 0") - abstract fun getChildren(ids: List): List - - @Query("SELECT tasks.* FROM tasks JOIN google_tasks ON tasks._id = gt_task WHERE gt_parent = :taskId") - abstract fun getChildTasks(taskId: Long): List - - @Query("SELECT * FROM google_tasks WHERE gt_parent = :id AND gt_deleted = 0") - abstract fun getChildren(id: Long): List - - @Query("SELECT IFNULL(MAX(gt_order), -1) + 1 FROM google_tasks WHERE gt_list_id = :listId AND gt_parent = :parent") - abstract fun getBottom(listId: String, parent: Long): Long - - @Query("SELECT gt_remote_id FROM google_tasks JOIN tasks ON tasks._id = gt_task WHERE deleted = 0 AND gt_list_id = :listId AND gt_parent = :parent AND gt_order < :order AND gt_remote_id IS NOT NULL AND gt_remote_id != '' ORDER BY gt_order DESC") - abstract fun getPrevious(listId: String, parent: Long, order: Long): String? - - @Query("SELECT gt_remote_id FROM google_tasks WHERE gt_task = :task") - abstract fun getRemoteId(task: Long): String? - - @Query("SELECT gt_task FROM google_tasks WHERE gt_remote_id = :remoteId") - abstract fun getTask(remoteId: String): Long - - @SuppressWarnings(RoomWarnings.CURSOR_MISMATCH) - @Query("SELECT google_tasks.*, gt_order AS primary_sort, NULL AS secondary_sort FROM google_tasks JOIN tasks ON tasks._id = gt_task WHERE gt_parent = 0 AND gt_list_id = :listId AND tasks.deleted = 0 UNION SELECT c.*, p.gt_order AS primary_sort, c.gt_order AS secondary_sort FROM google_tasks AS c LEFT JOIN google_tasks AS p ON c.gt_parent = p.gt_task JOIN tasks ON tasks._id = c.gt_task WHERE c.gt_parent > 0 AND c.gt_list_id = :listId AND tasks.deleted = 0 ORDER BY primary_sort ASC, secondary_sort ASC") - abstract fun getByLocalOrder(listId: String): List - - @SuppressWarnings(RoomWarnings.CURSOR_MISMATCH) - @Query("SELECT google_tasks.*, gt_remote_order AS primary_sort, NULL AS secondary_sort FROM google_tasks JOIN tasks ON tasks._id = gt_task WHERE gt_parent = 0 AND gt_list_id = :listId AND tasks.deleted = 0 UNION SELECT c.*, p.gt_remote_order AS primary_sort, c.gt_remote_order AS secondary_sort FROM google_tasks AS c LEFT JOIN google_tasks AS p ON c.gt_parent = p.gt_task JOIN tasks ON tasks._id = c.gt_task WHERE c.gt_parent > 0 AND c.gt_list_id = :listId AND tasks.deleted = 0 ORDER BY primary_sort ASC, secondary_sort ASC") - abstract fun getByRemoteOrder(listId: String): List - - @Query("UPDATE google_tasks" - + " SET gt_parent = IFNULL((" - + " SELECT gt_task FROM google_tasks AS p" - + " WHERE p.gt_remote_id = google_tasks.gt_remote_parent" - + " AND p.gt_list_id = google_tasks.gt_list_id " - + " AND p.gt_deleted = 0)," - + " 0)" - + " WHERE gt_moved = 0") - abstract fun updateParents() - - @Query("UPDATE google_tasks SET gt_parent = IFNULL((SELECT gt_task FROM google_tasks AS p WHERE p.gt_remote_id = google_tasks.gt_remote_parent), 0) WHERE gt_list_id = :listId AND gt_moved = 0") - abstract fun updateParents(listId: String) - - @Query("UPDATE google_tasks SET gt_remote_parent = :parent, gt_remote_order = :position WHERE gt_remote_id = :id") - abstract fun updatePosition(id: String, parent: String, position: String) - - @Transaction - open fun reposition(listId: String) { - updateParents(listId) - val orderedTasks = getByRemoteOrder(listId) - var subtasks = 0L - var parent = 0L - for (task in orderedTasks) { - if (task.parent > 0) { - if (task.order != subtasks && !task.isMoved) { - task.order = subtasks - update(task) - } - subtasks++ - } else { - subtasks = 0 - if (task.order != parent && !task.isMoved) { - task.order = parent - update(task) - } - parent++ - } - } - } - - fun validateSorting(listId: String) { - val orderedTasks = getByLocalOrder(listId) - var subtasks = 0L - var parent = 0L - for (task in orderedTasks) { - if (task.parent > 0) { - if (task.order != subtasks) { - throw IllegalStateException("Subtask violation, expected $subtasks but was ${task.order}") - } - subtasks++ - } else { - subtasks = 0 - if (task.order != parent) { - throw IllegalStateException("Parent violation, expected $parent but was ${task.order}") - } - parent++ - } - } + fun validateSorting(listId: String) = runBlocking { + dao.validateSorting(listId) } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/data/GoogleTaskListDaoBlocking.kt b/app/src/main/java/org/tasks/data/GoogleTaskListDaoBlocking.kt index 359da9337..850ab1684 100644 --- a/app/src/main/java/org/tasks/data/GoogleTaskListDaoBlocking.kt +++ b/app/src/main/java/org/tasks/data/GoogleTaskListDaoBlocking.kt @@ -1,72 +1,86 @@ package org.tasks.data import androidx.lifecycle.LiveData -import androidx.room.* -import com.todoroo.astrid.api.FilterListItem.NO_ORDER +import kotlinx.coroutines.runBlocking import org.tasks.filters.GoogleTaskFilters import org.tasks.time.DateTimeUtils.currentTimeMillis +import javax.inject.Inject -@Dao -interface GoogleTaskListDaoBlocking { - @Query("SELECT COUNT(*) FROM google_task_accounts") - fun accountCount(): Int +@Deprecated("use coroutines") +class GoogleTaskListDaoBlocking @Inject constructor(private val dao: GoogleTaskListDao) { + fun accountCount(): Int = runBlocking { + dao.accountCount() + } - @Query("SELECT * FROM google_task_accounts") - fun getAccounts(): List + fun getAccounts(): List = runBlocking { + dao.getAccounts() + } - @Query("SELECT * FROM google_task_accounts WHERE gta_account = :account COLLATE NOCASE LIMIT 1") - fun getAccount(account: String): GoogleTaskAccount? + fun getAccount(account: String): GoogleTaskAccount? = runBlocking { + dao.getAccount(account) + } - @Query("SELECT * FROM google_task_lists WHERE gtl_id = :id") - fun getById(id: Long): GoogleTaskList? + fun getById(id: Long): GoogleTaskList? = runBlocking { + dao.getById(id) + } - @Query("SELECT * FROM google_task_lists WHERE gtl_account = :account ORDER BY gtl_title ASC") - fun getLists(account: String): List + fun getLists(account: String): List = runBlocking { + dao.getLists(account) + } - @Query("SELECT * FROM google_task_lists WHERE gtl_remote_id = :remoteId LIMIT 1") - fun getByRemoteId(remoteId: String): GoogleTaskList? + fun getByRemoteId(remoteId: String): GoogleTaskList? = runBlocking { + dao.getByRemoteId(remoteId) + } - @Query("SELECT * FROM google_task_lists WHERE gtl_remote_id IN (:remoteIds)") - fun getByRemoteId(remoteIds: List): List + fun getByRemoteId(remoteIds: List): List = runBlocking { + dao.getByRemoteId(remoteIds) + } - @Query("SELECT * FROM google_task_lists") - fun subscribeToLists(): LiveData> + fun subscribeToLists(): LiveData> { + return dao.subscribeToLists() + } - @Query("SELECT * FROM google_task_lists WHERE gtl_remote_id = :remoteId AND IFNULL(gtl_account, '') = ''") - fun findExistingList(remoteId: String): GoogleTaskList? + fun findExistingList(remoteId: String): GoogleTaskList? = runBlocking { + dao.findExistingList(remoteId) + } - @Query("SELECT * FROM google_task_lists") - fun getAllLists(): List + fun getAllLists(): List = runBlocking { + dao.getAllLists() + } - @Query("UPDATE google_task_lists SET gtl_last_sync = 0 WHERE gtl_account = :account") - fun resetLastSync(account: String) + fun resetLastSync(account: String) = runBlocking { + dao.resetLastSync(account) + } - @Insert(onConflict = OnConflictStrategy.REPLACE) - fun insertOrReplace(googleTaskList: GoogleTaskList): Long + fun insertOrReplace(googleTaskList: GoogleTaskList): Long = runBlocking { + dao.insertOrReplace(googleTaskList) + } - @Insert - fun insert(googleTaskList: GoogleTaskList): Long + fun insert(googleTaskList: GoogleTaskList): Long = runBlocking { + dao.insert(googleTaskList) + } - @Insert - fun insert(googleTaskAccount: GoogleTaskAccount) + fun insert(googleTaskAccount: GoogleTaskAccount) = runBlocking { + dao.insert(googleTaskAccount) + } - @Update - fun update(account: GoogleTaskAccount) + fun update(account: GoogleTaskAccount) = runBlocking { + dao.update(account) + } - @Update - fun update(list: GoogleTaskList) + fun update(list: GoogleTaskList) = runBlocking { + dao.update(list) + } - @Query("SELECT google_task_lists.*, COUNT(tasks._id) AS count" - + " FROM google_task_lists " - + " LEFT JOIN google_tasks ON google_tasks.gt_list_id = google_task_lists.gtl_remote_id" - + " LEFT JOIN tasks ON google_tasks.gt_task = tasks._id AND tasks.deleted = 0 AND tasks.completed = 0 AND tasks.hideUntil < :now AND gt_deleted = 0" - + " WHERE google_task_lists.gtl_account = :account" - + " GROUP BY google_task_lists.gtl_remote_id") - fun getGoogleTaskFilters(account: String, now: Long = currentTimeMillis()): List + fun getGoogleTaskFilters(account: String, now: Long = currentTimeMillis()): List = runBlocking { + dao.getGoogleTaskFilters(account, now) + } - @Query("UPDATE google_task_lists SET gtl_remote_order = $NO_ORDER") - fun resetOrders() + fun resetOrders() = runBlocking { + dao.resetOrders() + } - @Query("UPDATE google_task_lists SET gtl_remote_order = :order WHERE gtl_id = :id") - fun setOrder(id: Long, order: Int) + fun setOrder(id: Long, order: Int) = runBlocking { + dao.setOrder(id, order) + } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/data/LocationDaoBlocking.kt b/app/src/main/java/org/tasks/data/LocationDaoBlocking.kt index fe0fa514d..d895862fa 100644 --- a/app/src/main/java/org/tasks/data/LocationDaoBlocking.kt +++ b/app/src/main/java/org/tasks/data/LocationDaoBlocking.kt @@ -1,118 +1,114 @@ package org.tasks.data import androidx.lifecycle.LiveData -import androidx.room.* -import com.todoroo.astrid.api.FilterListItem.NO_ORDER +import kotlinx.coroutines.runBlocking import org.tasks.filters.LocationFilters import org.tasks.time.DateTimeUtils.currentTimeMillis +import javax.inject.Inject -@Dao -interface LocationDaoBlocking { - @Query("SELECT places.*" - + " FROM places" - + " INNER JOIN geofences ON geofences.place = places.uid" - + " INNER JOIN tasks ON geofences.task = tasks._id" - + " WHERE tasks.completed = 0 AND tasks.deleted = 0" - + " AND (geofences.arrival > 0 OR geofences.departure > 0)" - + " GROUP BY places.uid") - fun getPlacesWithGeofences(): List - - @Query("SELECT places.*," - + " max(geofences.arrival) as arrival," - + " max(geofences.departure) as departure," - + " min(geofences.radius) as radius" - + " FROM places" - + " INNER JOIN geofences ON geofences.place = places.uid" - + " INNER JOIN tasks ON tasks._id = geofences.task" - + " WHERE place = :uid AND tasks.completed = 0 AND tasks.deleted = 0" - + " AND (geofences.arrival > 0 OR geofences.departure > 0)" - + " GROUP BY places.uid") - fun getGeofencesByPlace(uid: String): MergedGeofence? - - @Query("DELETE FROM geofences WHERE place = :place") - fun deleteGeofencesByPlace(place: String) - - @Query("SELECT geofences.* FROM geofences" - + " INNER JOIN tasks ON tasks._id = geofences.task" - + " WHERE place = :place AND arrival = 1 AND tasks.completed = 0" - + " AND tasks.deleted = 0 AND tasks.snoozeTime < :now AND tasks.hideUntil < :now") - fun getArrivalGeofences(place: String, now: Long): List - - @Query("SELECT geofences.* FROM geofences" - + " INNER JOIN tasks ON tasks._id = geofences.task" - + " WHERE place = :place AND departure = 1 AND tasks.completed = 0" - + " AND tasks.deleted = 0 AND tasks.snoozeTime < :now AND tasks.hideUntil < :now") - fun getDepartureGeofences(place: String, now: Long): List - - @Query("SELECT * FROM geofences" - + " INNER JOIN places ON geofences.place = places.uid" - + " WHERE task = :taskId ORDER BY name ASC LIMIT 1") - fun getGeofences(taskId: Long): Location? - - @Query("SELECT geofences.*, places.* FROM geofences INNER JOIN places ON geofences.place = places.uid INNER JOIN tasks ON tasks._id = geofences.task WHERE tasks._id = :taskId AND tasks.deleted = 0 AND tasks.completed = 0") - fun getActiveGeofences(taskId: Long): List - - @Query("SELECT places.*" - + " FROM places" - + " INNER JOIN geofences ON geofences.place = places.uid" - + " WHERE geofences.task = :taskId") - fun getPlaceForTask(taskId: Long): Place? - - @Query("SELECT geofences.*, places.* FROM geofences INNER JOIN places ON geofences.place = places.uid INNER JOIN tasks ON tasks._id = geofences.task WHERE tasks.deleted = 0 AND tasks.completed = 0") - fun getActiveGeofences(): List - - @Query("SELECT COUNT(*) FROM geofences") - suspend fun geofenceCount(): Int - - @Delete - fun delete(location: Geofence) - - @Delete - fun delete(place: Place) - - @Insert - fun insert(location: Geofence): Long - - @Insert(onConflict = OnConflictStrategy.IGNORE) - fun insert(place: Place): Long - - @Update - fun update(place: Place) - - @Update - fun update(geofence: Geofence) - - @Query("SELECT * FROM places WHERE uid = :uid LIMIT 1") - fun getByUid(uid: String): Place? - - @Query("SELECT * FROM geofences WHERE task = :taskId") - fun getGeofencesForTask(taskId: Long): List - - @Query("SELECT * FROM places") - fun getPlaces(): List - - @Query("SELECT * FROM places WHERE place_id = :id") - fun getPlace(id: Long): Place? - - @Query("SELECT * FROM places WHERE uid = :uid") - fun getPlace(uid: String): Place? - - @Query("SELECT places.*, IFNULL(COUNT(geofence_id),0) AS count FROM places LEFT OUTER JOIN geofences ON geofences.place = places.uid GROUP BY uid ORDER BY COUNT(geofence_id) DESC") - fun getPlaceUsage(): LiveData> - - @Query("SELECT * FROM places WHERE latitude LIKE :latitude AND longitude LIKE :longitude") - fun findPlace(latitude: String, longitude: String): Place? - - @Query("SELECT places.*, COUNT(tasks._id) AS count FROM places " - + " LEFT JOIN geofences ON geofences.place = places.uid " - + " LEFT JOIN tasks ON geofences.task = tasks._id AND tasks.completed = 0 AND tasks.deleted = 0 AND tasks.hideUntil < :now" - + " GROUP BY places.uid" - + " ORDER BY name COLLATE NOCASE ASC") - fun getPlaceFilters(now: Long = currentTimeMillis()): List - - @Query("UPDATE places SET place_order = $NO_ORDER") - fun resetOrders() +@Deprecated("use coroutines") +class LocationDaoBlocking @Inject constructor(private val dao: LocationDao) { + fun getPlacesWithGeofences(): List = runBlocking { + dao.getPlacesWithGeofences() + } - @Query("UPDATE places SET place_order = :order WHERE place_id = :id") - fun setOrder(id: Long, order: Int) + fun getGeofencesByPlace(uid: String): MergedGeofence? = runBlocking { + dao.getGeofencesByPlace(uid) + } + + fun deleteGeofencesByPlace(place: String) = runBlocking { + dao.deleteGeofencesByPlace(place) + } + + fun getArrivalGeofences(place: String, now: Long): List = runBlocking { + dao.getArrivalGeofences(place, now) + } + + fun getDepartureGeofences(place: String, now: Long): List = runBlocking { + dao.getDepartureGeofences(place, now) + } + + fun getGeofences(taskId: Long): Location? = runBlocking { + dao.getGeofences(taskId) + } + + fun getActiveGeofences(taskId: Long): List = runBlocking { + dao.getActiveGeofences(taskId) + } + + fun getPlaceForTask(taskId: Long): Place? = runBlocking { + dao.getPlaceForTask(taskId) + } + + fun getActiveGeofences(): List = runBlocking { + dao.getActiveGeofences() + } + + suspend fun geofenceCount(): Int { + return dao.geofenceCount() + } + + fun delete(location: Geofence) = runBlocking { + dao.delete(location) + } + + fun delete(place: Place) = runBlocking { + dao.delete(place) + } + + fun insert(location: Geofence): Long = runBlocking { + dao.insert(location) + } + + fun insert(place: Place): Long = runBlocking { + dao.insert(place) + } + + fun update(place: Place) = runBlocking { + dao.update(place) + } + + fun update(geofence: Geofence) = runBlocking { + dao.update(geofence) + } + + fun getByUid(uid: String): Place? = runBlocking { + dao.getByUid(uid) + } + + fun getGeofencesForTask(taskId: Long): List = runBlocking { + dao.getGeofencesForTask(taskId) + } + + fun getPlaces(): List = runBlocking { + dao.getPlaces() + } + + fun getPlace(id: Long): Place? = runBlocking { + dao.getPlace(id) + } + + fun getPlace(uid: String): Place? = runBlocking { + dao.getPlace(uid) + } + + fun getPlaceUsage(): LiveData> { + return dao.getPlaceUsage() + } + + fun findPlace(latitude: String, longitude: String): Place? = runBlocking { + dao.findPlace(latitude, longitude) + } + + fun getPlaceFilters(now: Long = currentTimeMillis()): List = runBlocking { + dao.getPlaceFilters(now) + } + + fun resetOrders() = runBlocking { + dao.resetOrders() + } + + fun setOrder(id: Long, order: Int) = runBlocking { + dao.setOrder(id, order) + } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/data/TagDaoBlocking.kt b/app/src/main/java/org/tasks/data/TagDaoBlocking.kt index 4f051f62a..abac3112a 100644 --- a/app/src/main/java/org/tasks/data/TagDaoBlocking.kt +++ b/app/src/main/java/org/tasks/data/TagDaoBlocking.kt @@ -1,49 +1,48 @@ package org.tasks.data -import androidx.room.* import com.todoroo.astrid.data.Task +import kotlinx.coroutines.runBlocking +import javax.inject.Inject -@Dao -abstract class TagDaoBlocking { - @Query("UPDATE tags SET name = :name WHERE tag_uid = :tagUid") - abstract fun rename(tagUid: String, name: String) +@Deprecated("use coroutines") +class TagDaoBlocking @Inject constructor(private val dao: TagDao) { + fun rename(tagUid: String, name: String) = runBlocking { + dao.rename(tagUid, name) + } - @Insert - abstract fun insert(tag: Tag) + fun insert(tag: Tag) = runBlocking { + dao.insert(tag) + } - @Insert - abstract fun insert(tags: Iterable) + fun insert(tags: Iterable) = runBlocking { + dao.insert(tags) + } - @Query("DELETE FROM tags WHERE task = :taskId AND tag_uid in (:tagUids)") - abstract fun deleteTags(taskId: Long, tagUids: List) + fun deleteTags(taskId: Long, tagUids: List) = runBlocking { + dao.deleteTags(taskId, tagUids) + } - @Query("SELECT * FROM tags WHERE tag_uid = :tagUid") - abstract fun getByTagUid(tagUid: String): List + fun getByTagUid(tagUid: String): List = runBlocking { + dao.getByTagUid(tagUid) + } - @Query("SELECT * FROM tags WHERE task = :taskId") - abstract fun getTagsForTask(taskId: Long): List + fun getTagsForTask(taskId: Long): List = runBlocking { + dao.getTagsForTask(taskId) + } - @Query("SELECT * FROM tags WHERE task = :taskId AND tag_uid = :tagUid") - abstract fun getTagByTaskAndTagUid(taskId: Long, tagUid: String): Tag? + fun getTagByTaskAndTagUid(taskId: Long, tagUid: String): Tag? = runBlocking { + dao.getTagByTaskAndTagUid(taskId, tagUid) + } - @Delete - abstract fun delete(tags: List) + fun delete(tags: List) = runBlocking { + dao.delete(tags) + } - @Transaction - open fun applyTags(task: Task, tagDataDao: TagDataDaoBlocking, current: List): Boolean { - val taskId = task.id - val existing = HashSet(tagDataDao.getTagDataForTask(taskId)) - val selected = HashSet(current) - val added = selected subtract existing - val removed = existing subtract selected - deleteTags(taskId, removed.map { td -> td.remoteId!! }) - insert(task, added) - return removed.isNotEmpty() || added.isNotEmpty() + fun applyTags(task: Task, tagDataDao: TagDataDaoBlocking, current: List): Boolean = runBlocking { + dao.applyTags(task, tagDataDao, current) } - fun insert(task: Task, tags: Collection) { - if (!tags.isEmpty()) { - insert(tags.map { Tag(task, it) }) - } + fun insert(task: Task, tags: Collection) = runBlocking { + dao.insert(task, tags) } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/data/TagDataDaoBlocking.kt b/app/src/main/java/org/tasks/data/TagDataDaoBlocking.kt index 61ceb6651..2258332d4 100644 --- a/app/src/main/java/org/tasks/data/TagDataDaoBlocking.kt +++ b/app/src/main/java/org/tasks/data/TagDataDaoBlocking.kt @@ -2,157 +2,115 @@ package org.tasks.data import androidx.core.util.Pair import androidx.lifecycle.LiveData -import androidx.room.* -import com.todoroo.astrid.api.FilterListItem.NO_ORDER import com.todoroo.astrid.data.Task -import com.todoroo.astrid.helper.UUIDHelper -import org.tasks.db.DbUtils -import org.tasks.filters.AlphanumComparator +import kotlinx.coroutines.runBlocking import org.tasks.filters.TagFilters import org.tasks.time.DateTimeUtils.currentTimeMillis -import java.util.* -import kotlin.collections.HashSet - -@Dao -abstract class TagDataDaoBlocking { - @Query("SELECT * FROM tagdata") - abstract fun subscribeToTags(): LiveData> - - @Query("SELECT * FROM tagdata WHERE name = :name COLLATE NOCASE LIMIT 1") - abstract fun getTagByName(name: String): TagData? - - /** - * If a tag already exists in the database that case insensitively matches the given tag, return - * that. Otherwise, return the argument - */ - fun getTagWithCase(tag: String): String? { - return getTagByName(tag)?.name ?: tag - } - - fun searchTags(query: String): List { - return searchTagsInternal("%$query%") - .sortedWith(AlphanumComparator(TagData::name)) - .toMutableList() - } - - @Query("SELECT * FROM tagdata WHERE name LIKE :query AND name NOT NULL AND name != ''") - protected abstract fun searchTagsInternal(query: String): List - - @Query("SELECT * FROM tagdata") - abstract fun getAll(): List - - @Query("SELECT * FROM tagdata WHERE remoteId = :uuid LIMIT 1") - abstract fun getByUuid(uuid: String): TagData? - - @Query("SELECT * FROM tagdata WHERE remoteId IN (:uuids)") - abstract fun getByUuid(uuids: Collection): List - - @Query("SELECT * FROM tagdata WHERE name IS NOT NULL AND name != '' ORDER BY UPPER(name) ASC") - abstract fun tagDataOrderedByName(): List - - @Delete - abstract fun deleteTagData(tagData: TagData) - - @Query("DELETE FROM tags WHERE tag_uid = :tagUid") - abstract fun deleteTags(tagUid: String) - - @Query("SELECT * FROM tags WHERE task IN (:tasks) AND tag_uid NOT IN (:tagsToKeep)") - abstract fun tagsToDelete(tasks: List, tagsToKeep: List): List - - fun getTagSelections(tasks: List): Pair, Set> { - val allTags = getAllTags(tasks) - val tags = allTags.map { t: String? -> HashSet(t?.split(",") ?: emptySet()) } - val partialTags = tags.flatten().toMutableSet() - var commonTags: MutableSet? = null - if (tags.isEmpty()) { - commonTags = HashSet() - } else { - for (s in tags) { - if (commonTags == null) { - commonTags = s.toMutableSet() - } else { - commonTags.retainAll(s) - } - } - } - partialTags.removeAll(commonTags!!) - return Pair(partialTags, commonTags) - } - - @Query("SELECT GROUP_CONCAT(DISTINCT(tag_uid)) FROM tasks" - + " LEFT JOIN tags ON tags.task = tasks._id" - + " WHERE tasks._id IN (:tasks)" - + " GROUP BY tasks._id") - abstract fun getAllTags(tasks: List): List - - @Transaction - open fun applyTags( - tasks: List, partiallySelected: List, selected: List): List { - val modified = HashSet() - val keep = partiallySelected.plus(selected).map { it.remoteId!! } - for (sublist in tasks.chunked(DbUtils.MAX_SQLITE_ARGS - keep.size)) { - val tags = tagsToDelete(sublist.map(Task::id), keep) - deleteTags(tags) - modified.addAll(tags.map(Tag::task)) - } - for (task in tasks) { - val added = selected subtract getTagDataForTask(task.id) - if (added.isNotEmpty()) { - modified.add(task.id) - insert(added.map { Tag(task, it) }) - } - } - return ArrayList(modified) - } - - @Transaction - open fun delete(tagData: TagData) { - deleteTags(tagData.remoteId!!) - deleteTagData(tagData) - } - - @Delete - abstract fun delete(tagData: List) - - @Delete - abstract fun deleteTags(tags: List) - - @Query("SELECT tagdata.* FROM tagdata " - + "INNER JOIN tags ON tags.tag_uid = tagdata.remoteId " - + "WHERE tags.task = :id " - + "ORDER BY UPPER(tagdata.name) ASC") - abstract fun getTagDataForTask(id: Long): List - - @Query("SELECT * FROM tagdata WHERE name IN (:names)") - abstract fun getTags(names: List): List - - @Update - abstract fun update(tagData: TagData) - - @Insert - abstract fun insert(tag: TagData): Long - - @Insert - abstract fun insert(tags: Iterable) - - fun createNew(tag: TagData) { - if (Task.isUuidEmpty(tag.remoteId)) { - tag.remoteId = UUIDHelper.newUUID() - } - tag.id = insert(tag) - } - - @Query("SELECT tagdata.*, COUNT(tasks._id) AS count" - + " FROM tagdata" - + " LEFT JOIN tags ON tags.tag_uid = tagdata.remoteId" - + " LEFT JOIN tasks ON tags.task = tasks._id AND tasks.deleted = 0 AND tasks.completed = 0 AND tasks.hideUntil < :now" - + " WHERE tagdata.name IS NOT NULL AND tagdata.name != ''" - + " GROUP BY tagdata.remoteId") - abstract fun getTagFilters(now: Long = currentTimeMillis()): List - - @Query("UPDATE tagdata SET td_order = $NO_ORDER") - abstract fun resetOrders() - - @Query("UPDATE tagdata SET td_order = :order WHERE _id = :id") - abstract fun setOrder(id: Long, order: Int) +import javax.inject.Inject + +@Deprecated("use coroutines") +class TagDataDaoBlocking @Inject constructor(private val dao: TagDataDao) { + fun subscribeToTags(): LiveData> { + return dao.subscribeToTags() + } + + fun getTagByName(name: String): TagData? = runBlocking { + dao.getTagByName(name) + } + + fun getTagWithCase(tag: String): String? = runBlocking { + dao.getTagWithCase(tag) + } + + fun searchTags(query: String): List = runBlocking { + dao.searchTags(query) + } + + fun getAll(): List = runBlocking { + dao.getAll() + } + + fun getByUuid(uuid: String): TagData? = runBlocking { + dao.getByUuid(uuid) + } + + fun getByUuid(uuids: Collection): List = runBlocking { + dao.getByUuid(uuids) + } + + fun tagDataOrderedByName(): List = runBlocking { + dao.tagDataOrderedByName() + } + + fun deleteTagData(tagData: TagData) = runBlocking { + dao.deleteTagData(tagData) + } + + fun deleteTags(tagUid: String) = runBlocking { + dao.deleteTags(tagUid) + } + + fun tagsToDelete(tasks: List, tagsToKeep: List): List = runBlocking { + dao.tagsToDelete(tasks, tagsToKeep) + } + + fun getTagSelections(tasks: List): Pair, Set> = runBlocking { + dao.getTagSelections(tasks) + } + + fun getAllTags(tasks: List): List = runBlocking { + dao.getAllTags(tasks) + } + + fun applyTags(tasks: List, partiallySelected: List, selected: List): List = runBlocking { + dao.applyTags(tasks, partiallySelected, selected) + } + + fun delete(tagData: TagData) = runBlocking { + dao.delete(tagData) + } + + fun delete(tagData: List) = runBlocking { + dao.delete(tagData) + } + + fun deleteTags(tags: List) = runBlocking { + dao.deleteTags(tags) + } + + fun getTagDataForTask(id: Long): List = runBlocking { + dao.getTagDataForTask(id) + } + + fun getTags(names: List): List = runBlocking { + dao.getTags(names) + } + + fun update(tagData: TagData) = runBlocking { + dao.update(tagData) + } + + fun insert(tag: TagData): Long = runBlocking { + dao.insert(tag) + } + + fun insert(tags: Iterable) = runBlocking { + dao.insert(tags) + } + + fun createNew(tag: TagData) = runBlocking { + dao.createNew(tag) + } + + fun getTagFilters(now: Long = currentTimeMillis()): List = runBlocking { + dao.getTagFilters(now) + } + + fun resetOrders() = runBlocking { + dao.resetOrders() + } + + fun setOrder(id: Long, order: Int) = runBlocking { + dao.setOrder(id, order) + } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/data/TaskAttachmentDaoBlocking.kt b/app/src/main/java/org/tasks/data/TaskAttachmentDaoBlocking.kt index 77ceb5dd8..2a49c801b 100644 --- a/app/src/main/java/org/tasks/data/TaskAttachmentDaoBlocking.kt +++ b/app/src/main/java/org/tasks/data/TaskAttachmentDaoBlocking.kt @@ -1,33 +1,35 @@ package org.tasks.data -import androidx.room.* -import com.todoroo.astrid.data.Task -import com.todoroo.astrid.helper.UUIDHelper +import kotlinx.coroutines.runBlocking +import javax.inject.Inject -@Dao -abstract class TaskAttachmentDaoBlocking { - @Query("SELECT * FROM task_attachments WHERE task_id = :taskUuid") - abstract fun getAttachments(taskUuid: String): List +@Deprecated("use coroutines") +class TaskAttachmentDaoBlocking @Inject constructor(private val dao: TaskAttachmentDao) { + fun getAttachments(taskUuid: String): List = runBlocking { + dao.getAttachments(taskUuid) + } - @Query("SELECT task_attachments.* FROM task_attachments INNER JOIN tasks ON tasks._id = :task WHERE task_id = tasks.remoteId") - abstract fun getAttachments(task: Long): List + fun getAttachments(task: Long): List = runBlocking { + dao.getAttachments(task) + } - @Query("SELECT * FROM task_attachments") - abstract fun getAttachments(): List + fun getAttachments(): List = runBlocking { + dao.getAttachments() + } - @Delete - abstract fun delete(taskAttachment: TaskAttachment) + fun delete(taskAttachment: TaskAttachment) = runBlocking { + dao.delete(taskAttachment) + } - @Insert(onConflict = OnConflictStrategy.REPLACE) - abstract fun insert(attachment: TaskAttachment) + fun insert(attachment: TaskAttachment) = runBlocking { + dao.insert(attachment) + } - @Update - abstract fun update(attachment: TaskAttachment) + fun update(attachment: TaskAttachment) = runBlocking { + dao.update(attachment) + } - fun createNew(attachment: TaskAttachment) { - if (Task.isUuidEmpty(attachment.remoteId)) { - attachment.remoteId = UUIDHelper.newUUID() - } - insert(attachment) + fun createNew(attachment: TaskAttachment) = runBlocking { + dao.createNew(attachment) } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/data/TaskListMetadataDaoBlocking.kt b/app/src/main/java/org/tasks/data/TaskListMetadataDaoBlocking.kt index f88edee16..8a97d2085 100644 --- a/app/src/main/java/org/tasks/data/TaskListMetadataDaoBlocking.kt +++ b/app/src/main/java/org/tasks/data/TaskListMetadataDaoBlocking.kt @@ -1,25 +1,27 @@ package org.tasks.data -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.Query -import androidx.room.Update +import kotlinx.coroutines.runBlocking +import javax.inject.Inject -@Dao -abstract class TaskListMetadataDaoBlocking { - @Query("SELECT * from task_list_metadata where tag_uuid = :tagUuid OR filter = :tagUuid LIMIT 1") - abstract fun fetchByTagOrFilter(tagUuid: String): TaskListMetadata? +@Deprecated("use coroutines") +class TaskListMetadataDaoBlocking @Inject constructor(private val dao: TaskListMetadataDao) { + fun fetchByTagOrFilter(tagUuid: String): TaskListMetadata? = runBlocking { + dao.fetchByTagOrFilter(tagUuid) + } - @Query("SELECT * FROM task_list_metadata") - abstract fun getAll(): List + fun getAll(): List = runBlocking { + dao.getAll() + } - @Update - abstract fun update(taskListMetadata: TaskListMetadata) + fun update(taskListMetadata: TaskListMetadata) = runBlocking { + dao.update(taskListMetadata) + } - @Insert - abstract fun insert(taskListMetadata: TaskListMetadata): Long + fun insert(taskListMetadata: TaskListMetadata): Long = runBlocking { + dao.insert(taskListMetadata) + } - fun createNew(taskListMetadata: TaskListMetadata) { - taskListMetadata.id = insert(taskListMetadata) + fun createNew(taskListMetadata: TaskListMetadata) = runBlocking { + dao.createNew(taskListMetadata) } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/data/UserActivityDaoBlocking.kt b/app/src/main/java/org/tasks/data/UserActivityDaoBlocking.kt index 126c42d89..68ce98d0e 100644 --- a/app/src/main/java/org/tasks/data/UserActivityDaoBlocking.kt +++ b/app/src/main/java/org/tasks/data/UserActivityDaoBlocking.kt @@ -1,37 +1,35 @@ package org.tasks.data -import androidx.room.* -import com.todoroo.andlib.utility.DateUtilities -import com.todoroo.astrid.data.Task -import com.todoroo.astrid.helper.UUIDHelper - -@Dao -abstract class UserActivityDaoBlocking { - @Insert - abstract fun insert(userActivity: UserActivity) - - @Update - abstract fun update(userActivity: UserActivity) - - @Delete - abstract fun delete(userActivity: UserActivity) - - @Query("SELECT * FROM userActivity WHERE target_id = :taskUuid ORDER BY created_at DESC ") - abstract fun getCommentsForTask(taskUuid: String): List - - @Query("SELECT userActivity.* FROM userActivity INNER JOIN tasks ON tasks._id = :task WHERE target_id = tasks.remoteId") - abstract fun getComments(task: Long): List - - @Query("SELECT * FROM userActivity") - abstract fun getComments(): List - - fun createNew(item: UserActivity) { - if (item.created == null || item.created == 0L) { - item.created = DateUtilities.now() - } - if (Task.isUuidEmpty(item.remoteId)) { - item.remoteId = UUIDHelper.newUUID() - } - insert(item) +import kotlinx.coroutines.runBlocking +import javax.inject.Inject + +@Deprecated("use coroutines") +class UserActivityDaoBlocking @Inject constructor(private val dao: UserActivityDao) { + fun insert(userActivity: UserActivity) = runBlocking { + dao.insert(userActivity) + } + + fun update(userActivity: UserActivity) = runBlocking { + dao.update(userActivity) + } + + fun delete(userActivity: UserActivity) = runBlocking { + dao.delete(userActivity) + } + + fun getCommentsForTask(taskUuid: String): List = runBlocking { + dao.getCommentsForTask(taskUuid) + } + + fun getComments(task: Long): List = runBlocking { + dao.getComments(task) + } + + fun getComments(): List = runBlocking { + dao.getComments() + } + + fun createNew(item: UserActivity) = runBlocking { + dao.createNew(item) } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/injection/ApplicationModule.kt b/app/src/main/java/org/tasks/injection/ApplicationModule.kt index 927f93b5f..4b93d92ab 100644 --- a/app/src/main/java/org/tasks/injection/ApplicationModule.kt +++ b/app/src/main/java/org/tasks/injection/ApplicationModule.kt @@ -2,7 +2,7 @@ package org.tasks.injection import android.content.Context import com.todoroo.astrid.dao.Database -import com.todoroo.astrid.dao.TaskDaoBlocking +import com.todoroo.astrid.dao.TaskDao import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -17,7 +17,7 @@ import org.tasks.jobs.WorkManager import org.tasks.locale.Locale import org.tasks.location.Geocoder import org.tasks.location.MapboxGeocoder -import org.tasks.notifications.NotificationDaoBlocking +import org.tasks.notifications.NotificationDao import javax.inject.Singleton @Module @@ -33,55 +33,55 @@ class ApplicationModule { @Provides @Singleton - fun getNotificationDao(db: Database): NotificationDaoBlocking = db.notificationDao() + fun getNotificationDao(db: Database): NotificationDao = db.notificationDao() @Provides @Singleton - fun getTagDataDao(db: Database): TagDataDaoBlocking = db.tagDataDao + fun getTagDataDao(db: Database): TagDataDao = db.tagDataDao @Provides @Singleton - fun getUserActivityDao(db: Database): UserActivityDaoBlocking = db.userActivityDao + fun getUserActivityDao(db: Database): UserActivityDao = db.userActivityDao @Provides @Singleton - fun getTaskAttachmentDao(db: Database): TaskAttachmentDaoBlocking = db.taskAttachmentDao + fun getTaskAttachmentDao(db: Database): TaskAttachmentDao = db.taskAttachmentDao @Provides @Singleton - fun getTaskListMetadataDao(db: Database): TaskListMetadataDaoBlocking = db.taskListMetadataDao + fun getTaskListMetadataDao(db: Database): TaskListMetadataDao = db.taskListMetadataDao @Provides @Singleton - fun getGoogleTaskDao(db: Database): GoogleTaskDaoBlocking = db.googleTaskDao + fun getGoogleTaskDao(db: Database): GoogleTaskDao = db.googleTaskDao @Provides @Singleton - fun getAlarmDao(db: Database): AlarmDaoBlocking = db.alarmDao + fun getAlarmDao(db: Database): AlarmDao = db.alarmDao @Provides @Singleton - fun getGeofenceDao(db: Database): LocationDaoBlocking = db.locationDao + fun getGeofenceDao(db: Database): LocationDao = db.locationDao @Provides @Singleton - fun getTagDao(db: Database): TagDaoBlocking = db.tagDao + fun getTagDao(db: Database): TagDao = db.tagDao @Provides @Singleton - fun getFilterDao(db: Database): FilterDaoBlocking = db.filterDao + fun getFilterDao(db: Database): FilterDao = db.filterDao @Provides @Singleton - fun getGoogleTaskListDao(db: Database): GoogleTaskListDaoBlocking = db.googleTaskListDao + fun getGoogleTaskListDao(db: Database): GoogleTaskListDao = db.googleTaskListDao @Provides @Singleton - fun getCaldavDao(db: Database): CaldavDaoBlocking = db.caldavDao + fun getCaldavDao(db: Database): CaldavDao = db.caldavDao @Provides @Singleton - fun getTaskDao(db: Database, workManager: WorkManager): TaskDaoBlocking { + fun getTaskDao(db: Database, workManager: WorkManager): TaskDao { val taskDao = db.taskDao taskDao.initialize(workManager) return taskDao @@ -89,11 +89,11 @@ class ApplicationModule { @Provides @Singleton - fun getDeletionDao(db: Database): DeletionDaoBlocking = db.deletionDao + fun getDeletionDao(db: Database): DeletionDao = db.deletionDao @Provides @Singleton - fun getContentProviderDao(db: Database): ContentProviderDaoBlocking = db.contentProviderDao + fun getContentProviderDao(db: Database): ContentProviderDao = db.contentProviderDao @Provides fun getBillingClient(@ApplicationContext context: Context, inventory: Inventory, firebase: Firebase): BillingClient diff --git a/app/src/main/java/org/tasks/notifications/NotificationDaoBlocking.kt b/app/src/main/java/org/tasks/notifications/NotificationDaoBlocking.kt index 81849c990..b7beaad42 100644 --- a/app/src/main/java/org/tasks/notifications/NotificationDaoBlocking.kt +++ b/app/src/main/java/org/tasks/notifications/NotificationDaoBlocking.kt @@ -1,27 +1,31 @@ package org.tasks.notifications -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query +import kotlinx.coroutines.runBlocking +import javax.inject.Inject -@Dao -interface NotificationDaoBlocking { - @Query("SELECT task FROM notification") - fun getAll(): List +@Deprecated("use coroutines") +class NotificationDaoBlocking @Inject constructor(private val dao: NotificationDao) { + fun getAll(): List = runBlocking { + dao.getAll() + } - @Query("SELECT * FROM notification ORDER BY timestamp DESC") - fun getAllOrdered(): List + fun getAllOrdered(): List = runBlocking { + dao.getAllOrdered() + } - @Insert(onConflict = OnConflictStrategy.REPLACE) - fun insertAll(notifications: List) + fun insertAll(notifications: List) = runBlocking { + dao.insertAll(notifications) + } - @Query("DELETE FROM notification WHERE task = :taskId") - fun delete(taskId: Long) + fun delete(taskId: Long) = runBlocking { + dao.delete(taskId) + } - @Query("DELETE FROM notification WHERE task IN(:taskIds)") - fun deleteAll(taskIds: List) + fun deleteAll(taskIds: List) = runBlocking { + dao.deleteAll(taskIds) + } - @Query("SELECT MAX(timestamp) FROM notification") - fun latestTimestamp(): Long + fun latestTimestamp(): Long = runBlocking { + dao.latestTimestamp() + } } \ No newline at end of file