From 2006e2c84bf4fb92c3020bd6004fb8662dd035ff Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Sat, 17 Dec 2022 15:10:16 -0600 Subject: [PATCH] Convert GoogleTask to CaldavTask --- .../com.todoroo.astrid.dao.Database/88.json | 136 ++---------- .../gtasks/GtasksMetadataServiceTest.kt | 1 - .../todoroo/astrid/service/TaskMoverTest.kt | 8 +- .../java/org/tasks/data/GoogleTaskDaoTests.kt | 2 +- .../astrid/activity/TaskListFragment.kt | 1 - .../adapter/GoogleTaskManualSortAdapter.kt | 8 +- .../com/todoroo/astrid/adapter/TaskAdapter.kt | 35 ++- .../com/todoroo/astrid/api/GtasksFilter.java | 7 +- .../com/todoroo/astrid/api/SearchFilter.kt | 5 - .../astrid/core/BuiltInFilterExposer.kt | 15 +- .../com/todoroo/astrid/core/SortHelper.java | 2 +- .../java/com/todoroo/astrid/dao/Database.kt | 1 - .../astrid/gtasks/GtasksListService.kt | 2 +- .../com/todoroo/astrid/service/TaskCreator.kt | 4 +- .../com/todoroo/astrid/service/TaskDeleter.kt | 7 - .../todoroo/astrid/service/TaskDuplicator.kt | 2 +- .../com/todoroo/astrid/service/TaskMover.kt | 14 +- .../GoogleTaskListSettingsActivity.kt | 14 +- .../java/org/tasks/backup/BackupContainer.kt | 2 +- .../org/tasks/backup/TasksJsonExporter.kt | 3 - .../org/tasks/backup/TasksJsonImporter.kt | 10 +- .../java/org/tasks/compose/edit/SubtaskRow.kt | 6 +- .../main/java/org/tasks/data/CaldavAccount.kt | 1 + app/src/main/java/org/tasks/data/CaldavDao.kt | 45 +++- .../main/java/org/tasks/data/CaldavTask.kt | 15 +- .../main/java/org/tasks/data/DeletionDao.kt | 21 +- .../main/java/org/tasks/data/GoogleTask.kt | 129 +---------- .../main/java/org/tasks/data/GoogleTaskDao.kt | 205 +++++++++++------- .../java/org/tasks/data/GoogleTaskListDao.kt | 4 +- .../main/java/org/tasks/data/SubsetCaldav.kt | 7 +- .../java/org/tasks/data/SubsetGoogleTask.java | 70 ------ .../java/org/tasks/data/TaskContainer.java | 29 +-- app/src/main/java/org/tasks/data/TaskDao.kt | 18 +- .../main/java/org/tasks/data/TaskListQuery.kt | 9 +- .../org/tasks/data/TaskListQueryRecursive.kt | 20 +- .../tasks/filters/FilterCriteriaProvider.kt | 18 +- .../tasks/gtasks/GoogleTaskSynchronizer.kt | 22 +- .../preferences/DefaultFilterProvider.kt | 2 +- .../main/java/org/tasks/ui/ChipProvider.kt | 33 +-- .../org/tasks/ui/NavigationDrawerViewModel.kt | 8 +- .../java/org/tasks/ui/SubtaskControlSet.kt | 12 +- .../java/org/tasks/ui/TaskEditViewModel.kt | 2 +- .../java/org/tasks/widget/ChipProvider.kt | 5 - .../java/org/tasks/makers/GoogleTaskMaker.kt | 3 +- 44 files changed, 360 insertions(+), 603 deletions(-) delete mode 100644 app/src/main/java/org/tasks/data/SubsetGoogleTask.java diff --git a/app/schemas/com.todoroo.astrid.dao.Database/88.json b/app/schemas/com.todoroo.astrid.dao.Database/88.json index a2bfd28a7..4562eb5e5 100644 --- a/app/schemas/com.todoroo.astrid.dao.Database/88.json +++ b/app/schemas/com.todoroo.astrid.dao.Database/88.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 88, - "identityHash": "d9d2cc4048325dbde272d8d4f8e3880f", + "identityHash": "8ddd120bc22139ab9c9d69dbc727df37", "entities": [ { "tableName": "notification", @@ -725,118 +725,6 @@ } ] }, - { - "tableName": "google_tasks", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`gt_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `gt_task` INTEGER NOT NULL, `gt_remote_id` TEXT, `gt_list_id` TEXT, `gt_parent` INTEGER NOT NULL, `gt_remote_parent` TEXT, `gt_moved` INTEGER NOT NULL, `gt_order` INTEGER NOT NULL, `gt_remote_order` INTEGER NOT NULL, `gt_last_sync` INTEGER NOT NULL, `gt_deleted` INTEGER NOT NULL, FOREIGN KEY(`gt_task`) REFERENCES `tasks`(`_id`) ON UPDATE NO ACTION ON DELETE CASCADE )", - "fields": [ - { - "fieldPath": "id", - "columnName": "gt_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "task", - "columnName": "gt_task", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "remoteId", - "columnName": "gt_remote_id", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "listId", - "columnName": "gt_list_id", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "parent", - "columnName": "gt_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "remoteParent", - "columnName": "gt_remote_parent", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "isMoved", - "columnName": "gt_moved", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "order", - "columnName": "gt_order", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "remoteOrder", - "columnName": "gt_remote_order", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lastSync", - "columnName": "gt_last_sync", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "gt_deleted", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "gt_id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "gt_list_parent", - "unique": false, - "columnNames": [ - "gt_list_id", - "gt_parent" - ], - "orders": [], - "createSql": "CREATE INDEX IF NOT EXISTS `gt_list_parent` ON `${TABLE_NAME}` (`gt_list_id`, `gt_parent`)" - }, - { - "name": "index_google_tasks_gt_task", - "unique": false, - "columnNames": [ - "gt_task" - ], - "orders": [], - "createSql": "CREATE INDEX IF NOT EXISTS `index_google_tasks_gt_task` ON `${TABLE_NAME}` (`gt_task`)" - } - ], - "foreignKeys": [ - { - "table": "tasks", - "onDelete": "CASCADE", - "onUpdate": "NO ACTION", - "columns": [ - "gt_task" - ], - "referencedColumns": [ - "_id" - ] - } - ] - }, { "tableName": "filters", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `sql` TEXT, `values` TEXT, `criterion` TEXT, `f_color` INTEGER, `f_icon` INTEGER, `f_order` INTEGER NOT NULL)", @@ -981,7 +869,7 @@ }, { "tableName": "caldav_tasks", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`cd_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `cd_task` INTEGER NOT NULL, `cd_calendar` TEXT, `cd_object` TEXT, `cd_remote_id` TEXT, `cd_etag` TEXT, `cd_last_sync` INTEGER NOT NULL, `cd_deleted` INTEGER NOT NULL, `cd_remote_parent` TEXT, `cd_order` INTEGER, FOREIGN KEY(`cd_task`) REFERENCES `tasks`(`_id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`cd_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `cd_task` INTEGER NOT NULL, `cd_calendar` TEXT, `cd_object` TEXT, `cd_remote_id` TEXT, `cd_etag` TEXT, `cd_last_sync` INTEGER NOT NULL, `cd_deleted` INTEGER NOT NULL, `cd_remote_parent` TEXT, `gt_moved` INTEGER NOT NULL, `gt_remote_order` INTEGER NOT NULL, `gt_parent` INTEGER NOT NULL, `cd_order` INTEGER, FOREIGN KEY(`cd_task`) REFERENCES `tasks`(`_id`) ON UPDATE NO ACTION ON DELETE CASCADE )", "fields": [ { "fieldPath": "id", @@ -1037,6 +925,24 @@ "affinity": "TEXT", "notNull": false }, + { + "fieldPath": "isMoved", + "columnName": "gt_moved", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteOrder", + "columnName": "gt_remote_order", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "parent", + "columnName": "gt_parent", + "affinity": "INTEGER", + "notNull": true + }, { "fieldPath": "order", "columnName": "cd_order", @@ -1397,7 +1303,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd9d2cc4048325dbde272d8d4f8e3880f')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '8ddd120bc22139ab9c9d69dbc727df37')" ] } } \ No newline at end of file diff --git a/app/src/androidTest/java/com/todoroo/astrid/gtasks/GtasksMetadataServiceTest.kt b/app/src/androidTest/java/com/todoroo/astrid/gtasks/GtasksMetadataServiceTest.kt index 54aa5d022..c9482318a 100644 --- a/app/src/androidTest/java/com/todoroo/astrid/gtasks/GtasksMetadataServiceTest.kt +++ b/app/src/androidTest/java/com/todoroo/astrid/gtasks/GtasksMetadataServiceTest.kt @@ -13,7 +13,6 @@ import kotlinx.coroutines.runBlocking import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull import org.junit.Test -import org.tasks.data.GoogleTask import org.tasks.data.GoogleTaskDao import org.tasks.injection.InjectingTestCase import org.tasks.injection.ProductionModule 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 8a43ee777..f00fa5d54 100644 --- a/app/src/androidTest/java/com/todoroo/astrid/service/TaskMoverTest.kt +++ b/app/src/androidTest/java/com/todoroo/astrid/service/TaskMoverTest.kt @@ -49,7 +49,7 @@ class TaskMoverTest : InjectingTestCase() { createTasks(1) googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1"))) moveToGoogleTasks("2", 1) - assertEquals("2", googleTaskDao.getByTaskId(1)!!.listId) + assertEquals("2", googleTaskDao.getByTaskId(1)!!.calendar) } @Test @@ -75,7 +75,7 @@ class TaskMoverTest : InjectingTestCase() { assertTrue(deleted[0].deleted > 0) val task = googleTaskDao.getByTaskId(2)!! assertEquals(1, task.parent) - assertEquals("2", task.listId) + assertEquals("2", task.calendar) } @Test @@ -194,7 +194,7 @@ class TaskMoverTest : InjectingTestCase() { moveToGoogleTasks("2", 2) val task = googleTaskDao.getByTaskId(2)!! assertEquals(0L, task.parent) - assertEquals("2", task.listId) + assertEquals("2", task.calendar) } @Test @@ -228,7 +228,7 @@ class TaskMoverTest : InjectingTestCase() { createTasks(1) caldavDao.insert(newCaldavTask(with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1"))) moveToGoogleTasks("2", 1) - assertEquals("2", googleTaskDao.getByTaskId(1L)!!.listId) + assertEquals("2", googleTaskDao.getByTaskId(1L)!!.calendar) } @Test diff --git a/app/src/androidTest/java/org/tasks/data/GoogleTaskDaoTests.kt b/app/src/androidTest/java/org/tasks/data/GoogleTaskDaoTests.kt index f0e9ce49a..08a7dda84 100644 --- a/app/src/androidTest/java/org/tasks/data/GoogleTaskDaoTests.kt +++ b/app/src/androidTest/java/org/tasks/data/GoogleTaskDaoTests.kt @@ -264,7 +264,7 @@ class GoogleTaskDaoTests : InjectingTestCase() { val googleTask = googleTaskDao.getByRemoteId(remoteId)!! val result = SubsetGoogleTask() result.gt_id = googleTask.id - result.gt_list_id = googleTask.listId + result.gt_list_id = googleTask.calendar result.gt_order = googleTask.order result.gt_parent = googleTask.parent return result diff --git a/app/src/main/java/com/todoroo/astrid/activity/TaskListFragment.kt b/app/src/main/java/com/todoroo/astrid/activity/TaskListFragment.kt index cb6f2fa5a..d5972c495 100644 --- a/app/src/main/java/com/todoroo/astrid/activity/TaskListFragment.kt +++ b/app/src/main/java/com/todoroo/astrid/activity/TaskListFragment.kt @@ -980,7 +980,6 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL companion object { const val TAGS_METADATA_JOIN = "for_tags" // $NON-NLS-1$ - const val GTASK_METADATA_JOIN = "googletask" // $NON-NLS-1$ const val CALDAV_METADATA_JOIN = "for_caldav" // $NON-NLS-1$ const val ACTION_RELOAD = "action_reload" const val ACTION_DELETED = "action_deleted" diff --git a/app/src/main/java/com/todoroo/astrid/adapter/GoogleTaskManualSortAdapter.kt b/app/src/main/java/com/todoroo/astrid/adapter/GoogleTaskManualSortAdapter.kt index 35d03c1cd..cc931357d 100644 --- a/app/src/main/java/com/todoroo/astrid/adapter/GoogleTaskManualSortAdapter.kt +++ b/app/src/main/java/com/todoroo/astrid/adapter/GoogleTaskManualSortAdapter.kt @@ -15,21 +15,21 @@ class GoogleTaskManualSortAdapter internal constructor( override suspend fun moved(from: Int, to: Int, indent: Int) { val task = getTask(from) - val googleTask = task.googleTask + val googleTask = task.caldavTask val previous = if (to > 0) getTask(to - 1) else null if (previous == null) { googleTaskDao.move(googleTask, 0, 0) } else if (to == count || to <= from) { when { indent == 0 -> googleTaskDao.move(googleTask, 0, previous.getPrimarySort() + if (to == count) 0 else 1) - previous.hasParent() && previous.parent == googleTask.parent -> googleTaskDao.move(googleTask, previous.parent, previous.getSecondarySort() + if (to == count) 0 else 1) + previous.hasParent() && previous.parent == task.parent -> googleTaskDao.move(googleTask, previous.parent, previous.getSecondarySort() + if (to == count) 0 else 1) previous.hasParent() -> googleTaskDao.move(googleTask, previous.parent, previous.getSecondarySort() + 1) else -> googleTaskDao.move(googleTask, previous.id, 0) } } else { when { indent == 0 -> googleTaskDao.move(googleTask, 0, previous.getPrimarySort() + if (task.hasParent()) 1 else 0) - previous.hasParent() && previous.parent == googleTask.parent -> googleTaskDao.move(googleTask, previous.parent, previous.getSecondarySort()) + previous.hasParent() && previous.parent == task.parent -> googleTaskDao.move(googleTask, previous.parent, previous.getSecondarySort()) previous.hasParent() -> googleTaskDao.move(googleTask, previous.parent, previous.getSecondarySort() + 1) else -> googleTaskDao.move(googleTask, previous.id, 0) } @@ -37,7 +37,7 @@ class GoogleTaskManualSortAdapter internal constructor( taskDao.touch(task.id) localBroadcastManager.broadcastRefresh() if (BuildConfig.DEBUG) { - googleTaskDao.validateSorting(task.googleTaskList!!) + googleTaskDao.validateSorting(task.caldav!!) } } } \ No newline at end of file diff --git a/app/src/main/java/com/todoroo/astrid/adapter/TaskAdapter.kt b/app/src/main/java/com/todoroo/astrid/adapter/TaskAdapter.kt index e9f48a8c2..905af19d4 100644 --- a/app/src/main/java/com/todoroo/astrid/adapter/TaskAdapter.kt +++ b/app/src/main/java/com/todoroo/astrid/adapter/TaskAdapter.kt @@ -135,21 +135,15 @@ open class TaskAdapter( open suspend fun moved(from: Int, to: Int, indent: Int) { val task = getTask(from) val newParent = findParent(indent, to) - if (newParent?.id ?: 0 == task.parent) { + if ((newParent?.id ?: 0) == task.parent) { if (indent == 0) { changeSortGroup(task, if (from < to) to - 1 else to) } return } else if (newParent != null) { - when { - task.isGoogleTask -> if (task.googleTaskList != newParent.googleTaskList) { - googleTaskDao.markDeleted(task.id) - task.googletask = null - } - task.isCaldavTask -> if (task.caldav != newParent.caldav) { - caldavDao.markDeleted(listOf(task.id)) - task.caldavTask = null - } + if (task.caldav != newParent.caldav) { + caldavDao.markDeleted(listOf(task.id)) + task.caldavTask = null } } when { @@ -250,20 +244,21 @@ open class TaskAdapter( } private suspend fun changeGoogleTaskParent(task: TaskContainer, newParent: TaskContainer?) { - val list = newParent?.googleTaskList ?: task.googleTaskList!! - if (newParent == null || task.googleTaskList == newParent.googleTaskList) { + val list = newParent?.caldav ?: task.caldav!! + if (newParent == null || task.caldav == newParent.caldav) { googleTaskDao.move( - task.googleTask, - newParent?.id ?: 0, - if (newTasksOnTop) 0 else googleTaskDao.getBottom(list, newParent?.id ?: 0)) + task.caldavTask, + newParent?.id ?: 0, + if (newTasksOnTop) 0 else googleTaskDao.getBottom(list, newParent?.id ?: 0) + ) } else { - val googleTask = GoogleTask(task.id, list) + val googleTask = CaldavTask(task.id, list) googleTask.parent = newParent.id googleTaskDao.insertAndShift(googleTask, newTasksOnTop) - task.googletask = SubsetGoogleTask().apply { - gt_id = googleTask.id - gt_list_id = googleTask.listId - gt_order = googleTask.order + task.caldavTask = SubsetCaldav().apply { + cd_id = googleTask.id + cd_calendar = googleTask.calendar + cd_order = googleTask.order ?: 0 gt_parent = googleTask.parent } } diff --git a/app/src/main/java/com/todoroo/astrid/api/GtasksFilter.java b/app/src/main/java/com/todoroo/astrid/api/GtasksFilter.java index 3dcfc3c65..dd8073b25 100644 --- a/app/src/main/java/com/todoroo/astrid/api/GtasksFilter.java +++ b/app/src/main/java/com/todoroo/astrid/api/GtasksFilter.java @@ -12,6 +12,7 @@ import com.todoroo.astrid.data.Task; import org.tasks.R; import org.tasks.data.CaldavCalendar; +import org.tasks.data.CaldavTask; import org.tasks.data.GoogleTask; import org.tasks.data.TaskDao; @@ -57,12 +58,12 @@ public class GtasksFilter extends Filter { private static QueryTemplate getQueryTemplate(CaldavCalendar list) { return new QueryTemplate() - .join(Join.left(GoogleTask.TABLE, Task.ID.eq(GoogleTask.TASK))) + .join(Join.left(CaldavTask.TABLE, Task.ID.eq(CaldavTask.TASK))) .where( Criterion.and( TaskDao.TaskCriteria.activeAndVisible(), - GoogleTask.DELETED.eq(0), - GoogleTask.LIST.eq(list.getUuid()))); + CaldavTask.DELETED.eq(0), + CaldavTask.CALENDAR.eq(list.getUuid()))); } private static Map getValuesForNewTasks(CaldavCalendar list) { diff --git a/app/src/main/java/com/todoroo/astrid/api/SearchFilter.kt b/app/src/main/java/com/todoroo/astrid/api/SearchFilter.kt index 3034b208c..b7c7ea2ba 100644 --- a/app/src/main/java/com/todoroo/astrid/api/SearchFilter.kt +++ b/app/src/main/java/com/todoroo/astrid/api/SearchFilter.kt @@ -61,11 +61,6 @@ class SearchFilter : Filter { .from(CaldavTask.TABLE) .join(Join.inner(CaldavCalendar.TABLE, CaldavCalendar.UUID.eq(CaldavTask.CALENDAR))) .where(CaldavCalendar.NAME.like(matcher))), - Task.ID.`in`( - Query.select(GoogleTask.TASK) - .from(GoogleTask.TABLE) - .join(Join.inner(CaldavCalendar.TABLE, CaldavCalendar.UUID.eq(GoogleTask.LIST))) - .where(CaldavCalendar.NAME.like(matcher))) ))) } } diff --git a/app/src/main/java/com/todoroo/astrid/core/BuiltInFilterExposer.kt b/app/src/main/java/com/todoroo/astrid/core/BuiltInFilterExposer.kt index b3dcc68a4..81bca780c 100644 --- a/app/src/main/java/com/todoroo/astrid/core/BuiltInFilterExposer.kt +++ b/app/src/main/java/com/todoroo/astrid/core/BuiltInFilterExposer.kt @@ -101,9 +101,8 @@ class BuiltInFilterExposer @Inject constructor( Filter( "No list", QueryTemplate() - .join(Join.left(GoogleTask.TABLE, GoogleTask.TASK.eq(Task.ID))) .join(Join.left(CaldavTask.TABLE, CaldavTask.TASK.eq(Task.ID))) - .where(and(GoogleTask.ID.eq(null), CaldavTask.ID.eq(null))) + .where(CaldavTask.ID.eq(null)) ).apply { icon = R.drawable.ic_outline_cloud_off_24px } @@ -116,13 +115,9 @@ class BuiltInFilterExposer @Inject constructor( Filter( "Missing list", QueryTemplate() - .join(Join.left(GoogleTask.TABLE, GoogleTask.TASK.eq(Task.ID))) .join(Join.left(CaldavTask.TABLE, CaldavTask.TASK.eq(Task.ID))) - .join(Join.left(CaldavCalendar.TABLE.`as`("google_task_lists"), CaldavCalendar.TABLE.`as`("google_task_lists").column("cdl_uuid").eq(GoogleTask.LIST))) .join(Join.left(CaldavCalendar.TABLE, CaldavCalendar.UUID.eq(CaldavTask.CALENDAR))) - .where(or( - and(GoogleTask.ID.gt(0), CaldavCalendar.TABLE.`as`("google_task_lists").column("cdl_uuid").eq(null)), - and(CaldavTask.ID.gt(0), CaldavCalendar.UUID.eq(null)))) + .where(and(CaldavTask.ID.gt(0), CaldavCalendar.UUID.eq(null))) ).apply { icon = R.drawable.ic_outline_cloud_off_24px } @@ -131,14 +126,10 @@ class BuiltInFilterExposer @Inject constructor( Filter( "Missing account", QueryTemplate() - .join(Join.left(GoogleTask.TABLE, and(GoogleTask.TASK.eq(Task.ID)))) .join(Join.left(CaldavTask.TABLE, and(CaldavTask.TASK.eq(Task.ID)))) - .join(Join.left(CaldavCalendar.TABLE.`as`("google_task_lists"), CaldavCalendar.TABLE.`as`("google_task_lists").column("cdl_uuid").eq(GoogleTask.LIST))) .join(Join.left(CaldavCalendar.TABLE, CaldavCalendar.UUID.eq(CaldavTask.CALENDAR))) .join(Join.left(CaldavAccount.TABLE, CaldavAccount.UUID.eq(CaldavCalendar.ACCOUNT))) - .where(or( - and(GoogleTask.ID.gt(0), CaldavCalendar.TABLE.`as`("google_task_lists").column("cdl_uuid").eq(null)), - and(CaldavTask.ID.gt(0), CaldavAccount.UUID.eq(null)))) + .where(and(CaldavTask.ID.gt(0), CaldavAccount.UUID.eq(null))) ).apply { icon = R.drawable.ic_outline_cloud_off_24px } diff --git a/app/src/main/java/com/todoroo/astrid/core/SortHelper.java b/app/src/main/java/com/todoroo/astrid/core/SortHelper.java index c298076e1..e373e3273 100644 --- a/app/src/main/java/com/todoroo/astrid/core/SortHelper.java +++ b/app/src/main/java/com/todoroo/astrid/core/SortHelper.java @@ -176,7 +176,7 @@ public class SortHelper { select = "tasks.created AS sort_created"; break; case SORT_GTASKS: - select = "google_tasks.gt_order AS sort_manual"; + select = "caldav_tasks.cd_order AS sort_manual"; break; case SORT_CALDAV: select = CALDAV_ORDER_COLUMN + " AS sort_manual"; 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 4101c02dc..5333940be 100644 --- a/app/src/main/java/com/todoroo/astrid/dao/Database.kt +++ b/app/src/main/java/com/todoroo/astrid/dao/Database.kt @@ -22,7 +22,6 @@ import org.tasks.notifications.NotificationDao Place::class, Geofence::class, Tag::class, - GoogleTask::class, Filter::class, CaldavCalendar::class, CaldavTask::class, diff --git a/app/src/main/java/com/todoroo/astrid/gtasks/GtasksListService.kt b/app/src/main/java/com/todoroo/astrid/gtasks/GtasksListService.kt index 59c42d6aa..1a8260104 100644 --- a/app/src/main/java/com/todoroo/astrid/gtasks/GtasksListService.kt +++ b/app/src/main/java/com/todoroo/astrid/gtasks/GtasksListService.kt @@ -53,7 +53,7 @@ class GtasksListService @Inject constructor( // check for lists that aren't on remote server for (listId in previousLists) { - taskDeleter.deleteGoogleTaskList(googleTaskListDao.getById(listId)!!) + taskDeleter.delete(googleTaskListDao.getById(listId)!!) } localBroadcastManager.broadcastRefreshList() } diff --git a/app/src/main/java/com/todoroo/astrid/service/TaskCreator.kt b/app/src/main/java/com/todoroo/astrid/service/TaskCreator.kt index 2abd10ab6..0410a715c 100644 --- a/app/src/main/java/com/todoroo/astrid/service/TaskCreator.kt +++ b/app/src/main/java/com/todoroo/astrid/service/TaskCreator.kt @@ -55,7 +55,7 @@ class TaskCreator @Inject constructor( val addToTop = preferences.addTasksToTop() if (task.hasTransitory(GoogleTask.KEY)) { googleTaskDao.insertAndShift( - GoogleTask(task.id, task.getTransitory(GoogleTask.KEY)!!), addToTop) + CaldavTask(task.id, task.getTransitory(GoogleTask.KEY)!!), addToTop) } else if (task.hasTransitory(CaldavTask.KEY)) { caldavDao.insert( task, CaldavTask(task.id, task.getTransitory(CaldavTask.KEY)), addToTop) @@ -63,7 +63,7 @@ class TaskCreator @Inject constructor( val remoteList = defaultFilterProvider.getDefaultList() if (remoteList is GtasksFilter) { googleTaskDao.insertAndShift( - GoogleTask(task.id, remoteList.remoteId), addToTop) + CaldavTask(task.id, remoteList.remoteId), addToTop) } else if (remoteList is CaldavFilter) { caldavDao.insert( task, CaldavTask(task.id, remoteList.uuid), addToTop) diff --git a/app/src/main/java/com/todoroo/astrid/service/TaskDeleter.kt b/app/src/main/java/com/todoroo/astrid/service/TaskDeleter.kt index f0fd43f8f..afbd65734 100644 --- a/app/src/main/java/com/todoroo/astrid/service/TaskDeleter.kt +++ b/app/src/main/java/com/todoroo/astrid/service/TaskDeleter.kt @@ -2,7 +2,6 @@ package com.todoroo.astrid.service import com.todoroo.astrid.api.Filter import com.todoroo.astrid.data.Task -import kotlinx.coroutines.runBlocking import org.tasks.LocalBroadcastManager import org.tasks.caldav.VtodoCache import org.tasks.data.* @@ -66,12 +65,6 @@ class TaskDeleter @Inject constructor( localBroadcastManager.broadcastRefresh() } - fun deleteGoogleTaskList(list: CaldavCalendar) = runBlocking { - val tasks = deletionDao.deleteGoogleTaskList(list) - delete(tasks) - localBroadcastManager.broadcastRefreshList() - } - suspend fun delete(list: CaldavCalendar) { vtodoCache.delete(list) val tasks = deletionDao.delete(list) diff --git a/app/src/main/java/com/todoroo/astrid/service/TaskDuplicator.kt b/app/src/main/java/com/todoroo/astrid/service/TaskDuplicator.kt index a112c1c23..6b84a2230 100644 --- a/app/src/main/java/com/todoroo/astrid/service/TaskDuplicator.kt +++ b/app/src/main/java/com/todoroo/astrid/service/TaskDuplicator.kt @@ -58,7 +58,7 @@ class TaskDuplicator @Inject constructor( val googleTask = googleTaskDao.getByTaskId(originalId) val addToTop = preferences.addTasksToTop() if (googleTask != null) { - googleTaskDao.insertAndShift(GoogleTask(clone.id, googleTask.listId!!), addToTop) + googleTaskDao.insertAndShift(CaldavTask(clone.id, googleTask.calendar!!), addToTop) } val caldavTask = caldavDao.getTask(originalId) if (caldavTask != null) { diff --git a/app/src/main/java/com/todoroo/astrid/service/TaskMover.kt b/app/src/main/java/com/todoroo/astrid/service/TaskMover.kt index 3c012b1f7..fef892e9e 100644 --- a/app/src/main/java/com/todoroo/astrid/service/TaskMover.kt +++ b/app/src/main/java/com/todoroo/astrid/service/TaskMover.kt @@ -82,21 +82,21 @@ class TaskMover @Inject constructor( moveLocalTask(task, selectedList) } - private suspend fun moveGoogleTask(task: Task, googleTask: GoogleTask, selected: Filter) { - if (selected is GtasksFilter && googleTask.listId == selected.remoteId) { + private suspend fun moveGoogleTask(task: Task, googleTask: CaldavTask, selected: Filter) { + if (selected is GtasksFilter && googleTask.calendar == selected.remoteId) { return } val id = googleTask.task val children = googleTaskDao.getChildren(id) - val childIds = children.map(GoogleTask::task) + val childIds = children.map(CaldavTask::task) googleTaskDao.markDeleted(id, DateUtilities.now()) when(selected) { is GtasksFilter -> { val listId = selected.remoteId - googleTaskDao.insertAndShift(GoogleTask(id, listId), preferences.addTasksToTop()) + googleTaskDao.insertAndShift(CaldavTask(id, listId), preferences.addTasksToTop()) children.takeIf { it.isNotEmpty() } ?.map { - val newChild = GoogleTask(it.task, listId) + val newChild = CaldavTask(it.task, listId) newChild.order = it.order newChild.parent = id newChild @@ -178,10 +178,10 @@ class TaskMover @Inject constructor( private suspend fun moveToGoogleTasks(id: Long, children: List, filter: GtasksFilter) { taskDao.setParent(0, children) val listId = filter.remoteId - googleTaskDao.insertAndShift(GoogleTask(id, listId), preferences.addTasksToTop()) + googleTaskDao.insertAndShift(CaldavTask(id, listId), preferences.addTasksToTop()) children.takeIf { it.isNotEmpty() } ?.mapIndexed { index, task -> - val newChild = GoogleTask(task, listId) + val newChild = CaldavTask(task, listId) newChild.order = index.toLong() newChild.parent = id newChild diff --git a/app/src/main/java/org/tasks/activities/GoogleTaskListSettingsActivity.kt b/app/src/main/java/org/tasks/activities/GoogleTaskListSettingsActivity.kt index c3bd23d3d..e288b5d3b 100644 --- a/app/src/main/java/org/tasks/activities/GoogleTaskListSettingsActivity.kt +++ b/app/src/main/java/org/tasks/activities/GoogleTaskListSettingsActivity.kt @@ -8,6 +8,7 @@ import android.view.View import android.view.inputmethod.InputMethodManager import android.widget.ProgressBar import androidx.activity.viewModels +import androidx.lifecycle.lifecycleScope import com.google.android.material.textfield.TextInputEditText import com.google.api.services.tasks.model.TaskList import com.todoroo.astrid.activity.MainActivity @@ -15,6 +16,9 @@ import com.todoroo.astrid.activity.TaskListFragment import com.todoroo.astrid.api.GtasksFilter import com.todoroo.astrid.service.TaskDeleter import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.NonCancellable +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.tasks.R import org.tasks.Strings.isNullOrEmpty import org.tasks.data.CaldavAccount @@ -177,9 +181,13 @@ class GoogleTaskListSettingsActivity : BaseListSettingsActivity() { private fun onListDeleted(deleted: Boolean) { if (deleted) { - taskDeleter.deleteGoogleTaskList(gtasksList) - setResult(Activity.RESULT_OK, Intent(TaskListFragment.ACTION_DELETED)) - finish() + lifecycleScope.launch { + withContext(NonCancellable) { + taskDeleter.delete(gtasksList) + } + setResult(Activity.RESULT_OK, Intent(TaskListFragment.ACTION_DELETED)) + finish() + } } } diff --git a/app/src/main/java/org/tasks/backup/BackupContainer.kt b/app/src/main/java/org/tasks/backup/BackupContainer.kt index 687bd1f97..f9b05d98a 100644 --- a/app/src/main/java/org/tasks/backup/BackupContainer.kt +++ b/app/src/main/java/org/tasks/backup/BackupContainer.kt @@ -26,11 +26,11 @@ class BackupContainer( val alarms: List, val geofences: List?, val tags: List, - val google: List, val comments: List, val attachments: List?, val caldavTasks: List?, val vtodo: String?, + val google: List = emptyList(), ) { val locations: List = emptyList() } diff --git a/app/src/main/java/org/tasks/backup/TasksJsonExporter.kt b/app/src/main/java/org/tasks/backup/TasksJsonExporter.kt index 76c0f68bb..9cf2637e5 100755 --- a/app/src/main/java/org/tasks/backup/TasksJsonExporter.kt +++ b/app/src/main/java/org/tasks/backup/TasksJsonExporter.kt @@ -37,9 +37,7 @@ class TasksJsonExporter @Inject constructor( private val alarmDao: AlarmDao, private val locationDao: LocationDao, private val tagDao: TagDao, - private val googleTaskDao: GoogleTaskDao, private val filterDao: FilterDao, - private val googleTaskListDao: GoogleTaskListDao, private val taskAttachmentDao: TaskAttachmentDao, private val caldavDao: CaldavDao, private val workManager: WorkManager, @@ -117,7 +115,6 @@ class TasksJsonExporter @Inject constructor( alarmDao.getAlarms(taskId), locationDao.getGeofencesForTask(taskId), tagDao.getTagsForTask(taskId), - googleTaskDao.getAllByTaskId(taskId), userActivityDao.getComments(taskId), taskAttachmentDao.getAttachmentsForTask(taskId), caldavTasks, diff --git a/app/src/main/java/org/tasks/backup/TasksJsonImporter.kt b/app/src/main/java/org/tasks/backup/TasksJsonImporter.kt index abc2e961e..3493cf8eb 100644 --- a/app/src/main/java/org/tasks/backup/TasksJsonImporter.kt +++ b/app/src/main/java/org/tasks/backup/TasksJsonImporter.kt @@ -187,8 +187,14 @@ class TasksJsonImporter @Inject constructor( userActivityDao.createNew(comment) } for (googleTask in backup.google) { - googleTask.task = taskId - googleTaskDao.insert(googleTask) + googleTaskDao.insert( + CaldavTask( + task = taskId, + calendar = googleTask.listId, + remoteId = googleTask.remoteId, + `object` = null, + ) + ) } for (location in backup.locations) { val place = newPlace() diff --git a/app/src/main/java/org/tasks/compose/edit/SubtaskRow.kt b/app/src/main/java/org/tasks/compose/edit/SubtaskRow.kt index 9b7424edd..96d4265aa 100644 --- a/app/src/main/java/org/tasks/compose/edit/SubtaskRow.kt +++ b/app/src/main/java/org/tasks/compose/edit/SubtaskRow.kt @@ -28,13 +28,13 @@ import com.todoroo.astrid.api.Filter import com.todoroo.astrid.api.GtasksFilter import com.todoroo.astrid.data.Task import org.tasks.compose.* -import org.tasks.data.GoogleTask +import org.tasks.data.CaldavTask import org.tasks.data.TaskContainer @Composable fun SubtaskRow( filter: Filter?, - googleTask: GoogleTask?, + googleTask: CaldavTask?, desaturate: Boolean, existingSubtasks: List, newSubtasks: List, @@ -63,7 +63,7 @@ fun SubtaskRow( Column { val isGoogleTaskChild = - filter is GtasksFilter && googleTask != null && googleTask.parent > 0 && googleTask.listId == filter.remoteId + filter is GtasksFilter && googleTask != null && googleTask.parent > 0 && googleTask.calendar == filter.remoteId if (isGoogleTaskChild) { DisabledText( text = stringResource(id = org.tasks.R.string.subtasks_multilevel_google_task), diff --git a/app/src/main/java/org/tasks/data/CaldavAccount.kt b/app/src/main/java/org/tasks/data/CaldavAccount.kt index e5fe0e021..8b622face 100644 --- a/app/src/main/java/org/tasks/data/CaldavAccount.kt +++ b/app/src/main/java/org/tasks/data/CaldavAccount.kt @@ -230,6 +230,7 @@ class CaldavAccount : Parcelable { companion object { val TABLE = Table("caldav_accounts") val UUID = TABLE.column("cda_uuid") + val ACCOUNT_TYPE = TABLE.column("cda_account_type") const val TYPE_CALDAV = 0 @Deprecated("use etebase") const val TYPE_ETESYNC = 1 diff --git a/app/src/main/java/org/tasks/data/CaldavDao.kt b/app/src/main/java/org/tasks/data/CaldavDao.kt index 8cf6da7c2..e516d8d24 100644 --- a/app/src/main/java/org/tasks/data/CaldavDao.kt +++ b/app/src/main/java/org/tasks/data/CaldavDao.kt @@ -108,10 +108,26 @@ ORDER BY CASE cda_account_type return insert(caldavTask) } - @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") + @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 suspend fun findFirstTask(calendar: String, parent: Long): Long? - @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") + @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 suspend fun findLastTask(calendar: String, parent: Long): Long? @Insert @@ -250,12 +266,16 @@ SELECT EXISTS(SELECT 1 @Query(""" SELECT caldav_lists.*, COUNT(DISTINCT(tasks._id)) AS count, COUNT(DISTINCT(principal_access.id)) AS principals 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 + 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 LEFT JOIN principal_access ON caldav_lists.cdl_id = principal_access.list + INNER JOIN caldav_accounts ON caldav_accounts.cda_uuid = caldav_lists.cdl_account WHERE caldav_lists.cdl_account = :uuid +AND caldav_accounts.cda_account_type != $TYPE_GOOGLE_TASKS GROUP BY caldav_lists.cdl_uuid """) abstract suspend fun getCaldavFilters(uuid: String, now: Long = currentTimeMillis()): List @@ -321,7 +341,18 @@ GROUP BY caldav_lists.cdl_uuid @Query("UPDATE tasks SET modified = :modificationTime WHERE _id in (:ids)") internal abstract suspend 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") + @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 suspend fun getTasksToShift(calendar: String, parent: Long, from: Long, to: Long?): List @Query("UPDATE caldav_lists SET cdl_order = $NO_ORDER") diff --git a/app/src/main/java/org/tasks/data/CaldavTask.kt b/app/src/main/java/org/tasks/data/CaldavTask.kt index ccdf6ecfe..26022899a 100644 --- a/app/src/main/java/org/tasks/data/CaldavTask.kt +++ b/app/src/main/java/org/tasks/data/CaldavTask.kt @@ -52,8 +52,18 @@ class CaldavTask { @ColumnInfo(name = "cd_remote_parent") var remoteParent: String? = null - @ColumnInfo(name = "cd_order") + @ColumnInfo(name = "gt_moved") + var isMoved: Boolean = false + + @ColumnInfo(name = "gt_remote_order") + var remoteOrder: Long = 0 + + @ColumnInfo(name = "gt_parent") + var parent: Long = 0 + @Transient + @Deprecated("For google tasks and importing old backup files") + @ColumnInfo(name = "cd_order") var order: Long? = null constructor() @@ -83,8 +93,9 @@ class CaldavTask { const val KEY = "caldav" @JvmField val TABLE = Table("caldav_tasks") val ID = TABLE.column("cd_id") + val PARENT = TABLE.column("gt_parent") @JvmField val TASK = TABLE.column("cd_task") @JvmField val DELETED = TABLE.column("cd_deleted") @JvmField val CALENDAR = TABLE.column("cd_calendar") } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/tasks/data/DeletionDao.kt b/app/src/main/java/org/tasks/data/DeletionDao.kt index 6548c080c..2987610f8 100644 --- a/app/src/main/java/org/tasks/data/DeletionDao.kt +++ b/app/src/main/java/org/tasks/data/DeletionDao.kt @@ -55,17 +55,6 @@ WHERE recurring = 1 ids.eachChunk(this::markDeletedInternal) } - @Query("SELECT gt_task FROM google_tasks WHERE gt_deleted = 0 AND gt_list_id = :listId") - internal abstract suspend fun getActiveGoogleTasks(listId: String): List - - @Transaction - open suspend fun deleteGoogleTaskList(googleTaskList: CaldavCalendar): List { - val tasks = getActiveGoogleTasks(googleTaskList.uuid!!) - delete(tasks) - delete(googleTaskList) - return tasks - } - @Query("SELECT * FROM caldav_lists WHERE cdl_account = :account ORDER BY cdl_name ASC") abstract suspend fun getLists(account: String): List @@ -95,14 +84,8 @@ WHERE recurring = 1 @Transaction open suspend fun delete(caldavAccount: CaldavAccount): List { val deleted = ArrayList() - if (caldavAccount.isGoogleTasks) { - for (list in getLists(caldavAccount.uuid!!)) { - deleted.addAll(deleteGoogleTaskList(list)) - } - } else { - for (calendar in getCalendars(caldavAccount.uuid!!)) { - deleted.addAll(delete(calendar)) - } + for (calendar in getCalendars(caldavAccount.uuid!!)) { + deleted.addAll(delete(calendar)) } deleteCaldavAccount(caldavAccount) return deleted diff --git a/app/src/main/java/org/tasks/data/GoogleTask.kt b/app/src/main/java/org/tasks/data/GoogleTask.kt index 2645870a6..60a0b68da 100644 --- a/app/src/main/java/org/tasks/data/GoogleTask.kt +++ b/app/src/main/java/org/tasks/data/GoogleTask.kt @@ -1,126 +1,15 @@ package org.tasks.data -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.ForeignKey -import androidx.room.Ignore -import androidx.room.Index -import androidx.room.PrimaryKey -import com.todoroo.andlib.data.Table -import com.todoroo.astrid.data.Task - -@Entity( - tableName = "google_tasks", - indices = [ - Index(name = "gt_list_parent", value = ["gt_list_id", "gt_parent"]) - ], - foreignKeys = [ - ForeignKey( - entity = Task::class, - parentColumns = ["_id"], - childColumns = ["gt_task"], - onDelete = ForeignKey.CASCADE, - ), - ] -) -class GoogleTask { - @PrimaryKey(autoGenerate = true) - @ColumnInfo(name = "gt_id") - @Transient - var id: Long = 0 - - @ColumnInfo(name = "gt_task", index = true) - @Transient - var task: Long = 0 - - @ColumnInfo(name = "gt_remote_id") - var remoteId: String? = "" - - @ColumnInfo(name = "gt_list_id") - var listId: String? = "" - - @ColumnInfo(name = "gt_parent") - @Transient - var parent: Long = 0 - - @ColumnInfo(name = "gt_remote_parent") - var remoteParent: String? = null - set(value) { - field = if (value?.isNotBlank() == true) value else null - } - - @ColumnInfo(name = "gt_moved") - @Transient - var isMoved = false - - @ColumnInfo(name = "gt_order") - @Transient - var order: Long = 0 - - @ColumnInfo(name = "gt_remote_order") - var remoteOrder: Long = 0 - - @ColumnInfo(name = "gt_last_sync") - var lastSync: Long = 0 - - @ColumnInfo(name = "gt_deleted") - var deleted: Long = 0 - - constructor() - - @Ignore - constructor(task: Long, listId: String) { - this.task = task - this.listId = listId - } - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is GoogleTask) return false - - if (id != other.id) return false - if (task != other.task) return false - if (remoteId != other.remoteId) return false - if (listId != other.listId) return false - if (parent != other.parent) return false - if (remoteParent != other.remoteParent) return false - if (isMoved != other.isMoved) return false - if (order != other.order) return false - if (remoteOrder != other.remoteOrder) return false - if (lastSync != other.lastSync) return false - if (deleted != other.deleted) return false - - return true - } - - override fun hashCode(): Int { - var result = id.hashCode() - result = 31 * result + task.hashCode() - result = 31 * result + remoteId.hashCode() - result = 31 * result + listId.hashCode() - result = 31 * result + parent.hashCode() - result = 31 * result + (remoteParent?.hashCode() ?: 0) - result = 31 * result + isMoved.hashCode() - result = 31 * result + order.hashCode() - result = 31 * result + remoteOrder.hashCode() - result = 31 * result + lastSync.hashCode() - result = 31 * result + deleted.hashCode() - return result - } - - override fun toString(): String = - "GoogleTask(id=$id, task=$task, remoteId='$remoteId', listId='$listId', parent=$parent, remoteParent=$remoteParent, isMoved=$isMoved, order=$order, remoteOrder=$remoteOrder, lastSync=$lastSync, deleted=$deleted)" - - val isNew: Boolean - get() = id == 0L - +@Deprecated("For backup use only") +data class GoogleTask( + var remoteId: String? = "", + var listId: String? = "", + var remoteParent: String? = null, + var remoteOrder: Long = 0, + var lastSync: Long = 0, + var deleted: Long = 0, +) { companion object { const val KEY = "gtasks" - @JvmField val TABLE = Table("google_tasks") - val ID = TABLE.column("gt_id") - @JvmField val PARENT = TABLE.column("gt_parent") - @JvmField val TASK = TABLE.column("gt_task") - @JvmField val DELETED = TABLE.column("gt_deleted") - @JvmField val LIST = TABLE.column("gt_list_id") } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/data/GoogleTaskDao.kt b/app/src/main/java/org/tasks/data/GoogleTaskDao.kt index 794b87e98..090af8a28 100644 --- a/app/src/main/java/org/tasks/data/GoogleTaskDao.kt +++ b/app/src/main/java/org/tasks/data/GoogleTaskDao.kt @@ -9,166 +9,219 @@ import org.tasks.time.DateTimeUtils.currentTimeMillis @Dao abstract class GoogleTaskDao { @Insert - abstract suspend fun insert(task: GoogleTask): Long + abstract suspend fun insert(task: CaldavTask): Long @Insert - abstract suspend fun insert(tasks: Iterable) + abstract suspend fun insert(tasks: Iterable) @Transaction - open suspend fun insertAndShift(task: GoogleTask, top: Boolean) { + open suspend fun insertAndShift(task: CaldavTask, top: Boolean) { if (top) { task.order = 0 - shiftDown(task.listId!!, task.parent, 0) + shiftDown(task.calendar!!, task.parent, 0) } else { - task.order = getBottom(task.listId!!, task.parent) + task.order = getBottom(task.calendar!!, task.parent) } task.id = insert(task) } - @Query("UPDATE google_tasks SET gt_order = gt_order + 1 WHERE gt_list_id = :listId AND gt_parent = :parent AND gt_order >= :position") + @Query("UPDATE caldav_tasks SET cd_order = cd_order + 1 WHERE cd_calendar = :listId AND gt_parent = :parent AND cd_order >= :position") internal abstract suspend fun shiftDown(listId: String, parent: Long, position: Long) - @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") + @Query("UPDATE caldav_tasks SET cd_order = cd_order - 1 WHERE cd_calendar = :listId AND gt_parent = :parent AND cd_order > :from AND cd_order <= :to") internal abstract suspend fun shiftUp(listId: String, parent: Long, from: Long, to: Long) - @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") + @Query("UPDATE caldav_tasks SET cd_order = cd_order + 1 WHERE cd_calendar = :listId AND gt_parent = :parent AND cd_order < :from AND cd_order >= :to") internal abstract suspend fun shiftDown(listId: String, parent: Long, from: Long, to: Long) - @Query("UPDATE google_tasks SET gt_order = gt_order - 1 WHERE gt_list_id = :listId AND gt_parent = :parent AND gt_order >= :position") + @Query("UPDATE caldav_tasks SET cd_order = cd_order - 1 WHERE cd_calendar = :listId AND gt_parent = :parent AND cd_order >= :position") internal abstract suspend fun shiftUp(listId: String, parent: Long, position: Long) @Transaction - open suspend fun move(task: SubsetGoogleTask, newParent: Long, newPosition: Long) { - val previousParent = task.parent - val previousPosition = task.order + open suspend fun move(task: SubsetCaldav, newParent: Long, newPosition: Long) { + val previousParent = task.gt_parent + val previousPosition = task.cd_order!! if (newParent == previousParent) { if (previousPosition < newPosition) { - shiftUp(task.listId, newParent, previousPosition, newPosition) + shiftUp(task.cd_calendar!!, newParent, previousPosition, newPosition) } else { - shiftDown(task.listId, newParent, previousPosition, newPosition) + shiftDown(task.cd_calendar!!, newParent, previousPosition, newPosition) } } else { - shiftUp(task.listId, previousParent, previousPosition) - shiftDown(task.listId, newParent, newPosition) + shiftUp(task.cd_calendar!!, previousParent, previousPosition) + shiftDown(task.cd_calendar!!, newParent, newPosition) } - task.parent = newParent - task.order = newPosition + task.gt_parent = newParent + task.cd_order = newPosition update(task) } - @Query("SELECT * FROM google_tasks WHERE gt_task = :taskId AND gt_deleted = 0 LIMIT 1") - abstract suspend fun getByTaskId(taskId: Long): GoogleTask? + @Query("SELECT * FROM caldav_tasks WHERE cd_task = :taskId AND cd_deleted = 0 LIMIT 1") + abstract suspend fun getByTaskId(taskId: Long): CaldavTask? - @Query("SELECT * FROM google_tasks WHERE gt_task = :taskId AND gt_deleted = 0 LIMIT 1") - abstract fun watchGoogleTask(taskId: Long): Flow + @Query("SELECT * FROM caldav_tasks WHERE cd_task = :taskId AND cd_deleted = 0 LIMIT 1") + abstract fun watchGoogleTask(taskId: Long): Flow @Update - abstract suspend fun update(googleTask: GoogleTask) + abstract suspend fun update(googleTask: CaldavTask) - private suspend fun update(googleTask: SubsetGoogleTask) { - update(googleTask.id, googleTask.parent, googleTask.order) + private suspend fun update(googleTask: SubsetCaldav) { + update(googleTask.cd_id, googleTask.gt_parent, googleTask.cd_order!!) } - @Query("UPDATE google_tasks SET gt_order = :order, gt_parent = :parent, gt_moved = 1 WHERE gt_id = :id") + @Query("UPDATE caldav_tasks SET cd_order = :order, gt_parent = :parent, gt_moved = 1 WHERE cd_id = :id") abstract suspend fun update(id: Long, parent: Long, order: Long) - @Query("UPDATE google_tasks SET gt_deleted = :now WHERE gt_task = :task OR gt_parent = :task") + @Query("UPDATE caldav_tasks SET cd_deleted = :now WHERE cd_task = :task OR gt_parent = :task") abstract suspend fun markDeleted(task: Long, now: Long = currentTimeMillis()) @Delete - abstract suspend fun delete(deleted: GoogleTask) + abstract suspend fun delete(deleted: CaldavTask) - @Query("SELECT * FROM google_tasks WHERE gt_remote_id = :remoteId LIMIT 1") - abstract suspend fun getByRemoteId(remoteId: String): GoogleTask? + @Query("SELECT * FROM caldav_tasks WHERE cd_remote_id = :remoteId LIMIT 1") + abstract suspend fun getByRemoteId(remoteId: String): CaldavTask? - @Query("SELECT * FROM google_tasks WHERE gt_task = :taskId AND gt_deleted > 0") - abstract suspend fun getDeletedByTaskId(taskId: Long): List + @Query("SELECT * FROM caldav_tasks WHERE cd_task = :taskId AND cd_deleted > 0") + abstract suspend fun getDeletedByTaskId(taskId: Long): List - @Query("SELECT * FROM google_tasks WHERE gt_task = :taskId") - abstract suspend fun getAllByTaskId(taskId: Long): List + @Query("SELECT * FROM caldav_tasks WHERE cd_task = :taskId") + abstract suspend fun getAllByTaskId(taskId: Long): List - @Query("SELECT DISTINCT gt_list_id FROM google_tasks WHERE gt_deleted = 0 AND gt_task IN (:tasks)") + @Query("SELECT DISTINCT cd_calendar FROM caldav_tasks WHERE cd_deleted = 0 AND cd_task IN (:tasks)") abstract suspend fun getLists(tasks: List): List - @Query("SELECT gt_task FROM google_tasks WHERE gt_parent IN (:ids) AND gt_deleted = 0") + @Query("SELECT cd_task FROM caldav_tasks WHERE gt_parent IN (:ids) AND cd_deleted = 0") abstract suspend fun getChildren(ids: List): List suspend fun hasRecurringParent(ids: List): List = ids.chunkedMap { internalHasRecurringParent(it) } @Query(""" -SELECT gt_task -FROM google_tasks +SELECT cd_task +FROM caldav_tasks INNER JOIN tasks ON gt_parent = _id -WHERE gt_task IN (:ids) - AND gt_deleted = 0 +WHERE cd_task IN (:ids) + AND cd_deleted = 0 AND tasks.recurrence IS NOT NULL AND tasks.recurrence != '' AND tasks.completed = 0 """) abstract suspend fun internalHasRecurringParent(ids: List): List - @Query("SELECT tasks.* FROM tasks JOIN google_tasks ON tasks._id = gt_task WHERE gt_parent = :taskId") + @Query("SELECT tasks.* FROM tasks JOIN caldav_tasks ON tasks._id = cd_task WHERE gt_parent = :taskId") abstract suspend fun getChildTasks(taskId: Long): List - @Query("SELECT tasks.* FROM tasks JOIN google_tasks ON tasks._id = gt_parent WHERE gt_task = :taskId") + @Query("SELECT tasks.* FROM tasks JOIN caldav_tasks ON tasks._id = gt_parent WHERE cd_task = :taskId") abstract suspend fun getParentTask(taskId: Long): Task? - @Query("SELECT * FROM google_tasks WHERE gt_parent = :id AND gt_deleted = 0") - abstract suspend fun getChildren(id: Long): List + @Query("SELECT * FROM caldav_tasks WHERE gt_parent = :id AND cd_deleted = 0") + abstract suspend 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") + @Query("SELECT IFNULL(MAX(cd_order), -1) + 1 FROM caldav_tasks WHERE cd_calendar = :listId AND gt_parent = :parent") abstract suspend 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") + @Query( + """ +SELECT cd_remote_id +FROM caldav_tasks + JOIN tasks ON tasks._id = cd_task +WHERE deleted = 0 + AND cd_calendar = :listId + AND gt_parent = :parent + AND cd_order < :order + AND cd_remote_id IS NOT NULL + AND cd_remote_id != '' +ORDER BY cd_order DESC + """ + ) abstract suspend fun getPrevious(listId: String, parent: Long, order: Long): String? - @Query("SELECT gt_remote_id FROM google_tasks WHERE gt_task = :task") + @Query("SELECT cd_remote_id FROM caldav_tasks WHERE cd_task = :task") abstract suspend fun getRemoteId(task: Long): String? - @Query("SELECT gt_task FROM google_tasks WHERE gt_remote_id = :remoteId") + @Query("SELECT cd_task FROM caldav_tasks WHERE cd_remote_id = :remoteId") abstract suspend 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 suspend fun getByLocalOrder(listId: String): List + @Query( + """ +SELECT caldav_tasks.*, cd_order AS primary_sort, NULL AS secondary_sort +FROM caldav_tasks + JOIN tasks ON tasks._id = cd_task +WHERE gt_parent = 0 + AND cd_calendar = :listId + AND tasks.deleted = 0 +UNION +SELECT c.*, p.cd_order AS primary_sort, c.cd_order AS secondary_sort +FROM caldav_tasks AS c + LEFT JOIN caldav_tasks AS p ON c.gt_parent = p.cd_task + JOIN tasks ON tasks._id = c.cd_task +WHERE c.gt_parent > 0 + AND c.cd_calendar = :listId + AND tasks.deleted = 0 +ORDER BY primary_sort ASC, secondary_sort ASC + """ + ) + abstract suspend 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") - internal abstract suspend fun getByRemoteOrder(listId: String): List + @Query( + """ +SELECT caldav_tasks.*, gt_remote_order AS primary_sort, NULL AS secondary_sort +FROM caldav_tasks + JOIN tasks ON tasks._id = cd_task +WHERE gt_parent = 0 + AND cd_calendar = :listId + AND tasks.deleted = 0 +UNION +SELECT c.*, p.gt_remote_order AS primary_sort, c.gt_remote_order AS secondary_sort +FROM caldav_tasks AS c + LEFT JOIN caldav_tasks AS p ON c.gt_parent = p.cd_task + JOIN tasks ON tasks._id = c.cd_task +WHERE c.gt_parent > 0 + AND c.cd_calendar = :listId + AND tasks.deleted = 0 +ORDER BY primary_sort ASC, secondary_sort ASC + """ + ) + internal abstract suspend fun getByRemoteOrder(listId: String): List - @Query(""" -UPDATE google_tasks -SET gt_parent = IFNULL((SELECT gt_task - FROM google_tasks AS p - WHERE google_tasks.gt_remote_parent IS NOT NULL - AND google_tasks.gt_remote_parent != '' - AND 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) + @Query( + """ +UPDATE caldav_tasks +SET gt_parent = IFNULL((SELECT cd_task + FROM caldav_tasks AS p + WHERE caldav_tasks.cd_remote_parent IS NOT NULL + AND caldav_tasks.cd_remote_parent != '' + AND p.cd_remote_id = caldav_tasks.cd_remote_parent + AND p.cd_calendar = caldav_tasks.cd_calendar + AND p.cd_deleted = 0), 0) WHERE gt_moved = 0 - """) + """ + ) abstract suspend fun updateParents() - @Query(""" -UPDATE google_tasks -SET gt_parent = IFNULL((SELECT gt_task - FROM google_tasks AS p - WHERE google_tasks.gt_remote_parent IS NOT NULL - AND google_tasks.gt_remote_parent != '' - AND 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_list_id = :listId + @Query( + """ +UPDATE caldav_tasks +SET gt_parent = IFNULL((SELECT cd_task + FROM caldav_tasks AS p + WHERE caldav_tasks.cd_remote_parent IS NOT NULL + AND caldav_tasks.cd_remote_parent != '' + AND p.cd_remote_id = caldav_tasks.cd_remote_parent + AND p.cd_calendar = caldav_tasks.cd_calendar + AND p.cd_deleted = 0), 0) +WHERE cd_calendar = :listId AND gt_moved = 0 - """) + """ + ) abstract suspend fun updateParents(listId: String) @Query(""" -UPDATE google_tasks -SET gt_remote_parent = CASE WHEN :parent == '' THEN NULL ELSE :parent END, +UPDATE caldav_tasks +SET cd_remote_parent = CASE WHEN :parent == '' THEN NULL ELSE :parent END, gt_remote_order = :position -WHERE gt_remote_id = :id +WHERE cd_remote_id = :id """) abstract suspend fun updatePosition(id: String, parent: String?, position: String) diff --git a/app/src/main/java/org/tasks/data/GoogleTaskListDao.kt b/app/src/main/java/org/tasks/data/GoogleTaskListDao.kt index b4c752605..4f82cbd30 100644 --- a/app/src/main/java/org/tasks/data/GoogleTaskListDao.kt +++ b/app/src/main/java/org/tasks/data/GoogleTaskListDao.kt @@ -30,8 +30,8 @@ interface GoogleTaskListDao { @Query("SELECT caldav_lists.*, COUNT(tasks._id) AS count" + " FROM caldav_lists " - + " LEFT JOIN google_tasks ON google_tasks.gt_list_id = caldav_lists.cdl_uuid" - + " 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" + + " 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 = :account" + " GROUP BY caldav_lists.cdl_uuid") suspend fun getGoogleTaskFilters(account: String, now: Long = currentTimeMillis()): List diff --git a/app/src/main/java/org/tasks/data/SubsetCaldav.kt b/app/src/main/java/org/tasks/data/SubsetCaldav.kt index 985bacc50..fc55e8fa1 100644 --- a/app/src/main/java/org/tasks/data/SubsetCaldav.kt +++ b/app/src/main/java/org/tasks/data/SubsetCaldav.kt @@ -4,6 +4,7 @@ class SubsetCaldav { var cd_id: Long = 0 var cd_calendar: String? = null var cd_remote_parent: String? = null + var gt_parent: Long = 0 var cd_order: Long? = null override fun equals(other: Any?): Boolean { @@ -13,6 +14,7 @@ class SubsetCaldav { if (cd_id != other.cd_id) return false if (cd_calendar != other.cd_calendar) return false if (cd_remote_parent != other.cd_remote_parent) return false + if (gt_parent != other.gt_parent) return false if (cd_order != other.cd_order) return false return true @@ -22,10 +24,11 @@ class SubsetCaldav { var result = cd_id.hashCode() result = 31 * result + (cd_calendar?.hashCode() ?: 0) result = 31 * result + (cd_remote_parent?.hashCode() ?: 0) - result = 31 * result + cd_order.hashCode() + result = 31 * result + (gt_parent.hashCode()) + result = 31 * result + (cd_order.hashCode()) return result } override fun toString(): String = - "SubsetCaldav(cd_id=$cd_id, cd_calendar=$cd_calendar, cd_remote_parent=$cd_remote_parent, cd_order=$cd_order)" + "SubsetCaldav(cd_id=$cd_id, cd_calendar=$cd_calendar, cd_remote_parent=$cd_remote_parent, gt_parent=$gt_parent, cd_order=$cd_order)" } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/data/SubsetGoogleTask.java b/app/src/main/java/org/tasks/data/SubsetGoogleTask.java deleted file mode 100644 index ed6cb79d9..000000000 --- a/app/src/main/java/org/tasks/data/SubsetGoogleTask.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.tasks.data; - -import java.util.Objects; - -public class SubsetGoogleTask { - - public long gt_id; - public long gt_parent; - public String gt_list_id; - public long gt_order; - - public long getId() { - return gt_id; - } - - public String getListId() { - return gt_list_id; - } - - public long getParent() { - return gt_parent; - } - - public void setParent(long parent) { - gt_parent = parent; - } - - public long getOrder() { - return gt_order; - } - - public void setOrder(long order) { - gt_order = order; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof SubsetGoogleTask)) { - return false; - } - SubsetGoogleTask that = (SubsetGoogleTask) o; - return gt_id == that.gt_id - && gt_parent == that.gt_parent - && gt_order == that.gt_order - && Objects.equals(gt_list_id, that.gt_list_id); - } - - @Override - public int hashCode() { - return Objects.hash(gt_id, gt_parent, gt_list_id, gt_order); - } - - @Override - public String toString() { - return "SubsetGoogleTask{" - + "gt_id=" - + gt_id - + ", gt_parent=" - + gt_parent - + ", gt_list_id='" - + gt_list_id - + '\'' - + ", gt_order=" - + gt_order - + '}'; - } -} diff --git a/app/src/main/java/org/tasks/data/TaskContainer.java b/app/src/main/java/org/tasks/data/TaskContainer.java index 4ce0a47e6..8348b149b 100644 --- a/app/src/main/java/org/tasks/data/TaskContainer.java +++ b/app/src/main/java/org/tasks/data/TaskContainer.java @@ -7,9 +7,9 @@ import java.util.Objects; public class TaskContainer { @Embedded public Task task; - @Embedded public SubsetGoogleTask googletask; @Embedded public SubsetCaldav caldavTask; @Embedded public Location location; + public boolean isGoogleTask; public boolean parentComplete; public String tags; public int children; @@ -23,16 +23,8 @@ public class TaskContainer { return tags; } - public @Nullable String getGoogleTaskList() { - return isGoogleTask() ? googletask.getListId() : null; - } - - public boolean isGoogleTask() { - return googletask != null; - } - public @Nullable String getCaldav() { - return isCaldavTask() ? caldavTask.getCd_calendar() : null; + return caldavTask.getCd_calendar(); } public boolean isCaldavTask() { @@ -127,7 +119,6 @@ public class TaskContainer { && indent == that.indent && targetIndent == that.targetIndent && Objects.equals(task, that.task) - && Objects.equals(googletask, that.googletask) && Objects.equals(caldavTask, that.caldavTask) && Objects.equals(location, that.location) && Objects.equals(tags, that.tags) @@ -138,7 +129,6 @@ public class TaskContainer { public int hashCode() { return Objects.hash( task, - googletask, caldavTask, location, tags, @@ -155,8 +145,6 @@ public class TaskContainer { return "TaskContainer{" + "task=" + task - + ", googletask=" - + googletask + ", caldavTask=" + caldavTask + ", location=" @@ -184,17 +172,16 @@ public class TaskContainer { } public long getParent() { - if (googletask != null) { - return googletask.getParent(); + if (isGoogleTask) { + return caldavTask.getGt_parent(); } else { return task.getParent(); } } public void setParent(long parent) { - if (googletask != null) { - task.setParent(0); - googletask.setParent(parent); + if (isGoogleTask) { + caldavTask.setGt_parent(parent); } else { task.setParent(parent); } @@ -208,10 +195,6 @@ public class TaskContainer { return children > 0; } - public SubsetGoogleTask getGoogleTask() { - return googletask; - } - public SubsetCaldav getCaldavTask() { return caldavTask; } diff --git a/app/src/main/java/org/tasks/data/TaskDao.kt b/app/src/main/java/org/tasks/data/TaskDao.kt index 110105924..004610535 100644 --- a/app/src/main/java/org/tasks/data/TaskDao.kt +++ b/app/src/main/java/org/tasks/data/TaskDao.kt @@ -61,11 +61,11 @@ abstract class TaskDao(private val database: Database) { abstract suspend fun setCompletionDate(remoteIds: List, completionDate: Long, updateTime: Long = now()) @Query("SELECT tasks.* FROM tasks " - + "LEFT JOIN google_tasks ON tasks._id = google_tasks.gt_task " - + "LEFT JOIN caldav_lists ON google_tasks.gt_list_id = caldav_lists.cdl_uuid " + + "LEFT JOIN caldav_tasks ON tasks._id = caldav_tasks.cd_task " + + "LEFT JOIN caldav_lists ON caldav_tasks.cd_calendar = caldav_lists.cdl_uuid " + "WHERE cdl_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") + + "AND (tasks.modified > caldav_tasks.cd_last_sync OR caldav_tasks.cd_remote_id = '' OR caldav_tasks.cd_deleted > 0) " + + "ORDER BY CASE WHEN parent = 0 THEN 0 ELSE 1 END, `order` ASC") abstract suspend fun getGoogleTasksToPush(account: String): List @Query(""" @@ -130,11 +130,11 @@ abstract class TaskDao(private val database: Database) { @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 + FROM caldav_tasks + INNER JOIN tasks ON cd_task = _id WHERE deleted = 0 AND gt_parent > 0 - AND gt_deleted = 0) AS hasGoogleSubtasks + AND cd_deleted = 0) AS hasGoogleSubtasks """) abstract suspend fun getSubtaskInfo(): SubtaskInfo @@ -246,10 +246,8 @@ FROM recursive_tasks @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 +WHERE cd_id IS NULL AND parent = 0 """) abstract suspend fun getLocalTasks(): List diff --git a/app/src/main/java/org/tasks/data/TaskListQuery.kt b/app/src/main/java/org/tasks/data/TaskListQuery.kt index ad1016eac..c620f755c 100644 --- a/app/src/main/java/org/tasks/data/TaskListQuery.kt +++ b/app/src/main/java/org/tasks/data/TaskListQuery.kt @@ -6,27 +6,26 @@ import com.todoroo.andlib.sql.Join import com.todoroo.astrid.activity.TaskListFragment import com.todoroo.astrid.api.Filter import com.todoroo.astrid.data.Task +import org.tasks.data.CaldavAccount.Companion.TYPE_GOOGLE_TASKS import org.tasks.data.TaskListQueryNonRecursive.getNonRecursiveQuery import org.tasks.data.TaskListQueryRecursive.getRecursiveQuery import org.tasks.preferences.QueryPreferences object TaskListQuery { - private val JOIN_GTASK = Criterion.and( - Task.ID.eq(field("${TaskListFragment.GTASK_METADATA_JOIN}.gt_task")), - field("${TaskListFragment.GTASK_METADATA_JOIN}.gt_deleted").eq(0)) private val JOIN_CALDAV = Criterion.and( Task.ID.eq(field("${TaskListFragment.CALDAV_METADATA_JOIN}.cd_task")), field("${TaskListFragment.CALDAV_METADATA_JOIN}.cd_deleted").eq(0)) val JOINS = """ - ${Join.left(GoogleTask.TABLE.`as`(TaskListFragment.GTASK_METADATA_JOIN), JOIN_GTASK)} ${Join.left(CaldavTask.TABLE.`as`(TaskListFragment.CALDAV_METADATA_JOIN), JOIN_CALDAV)} + ${Join.left(CaldavCalendar.TABLE, field("${TaskListFragment.CALDAV_METADATA_JOIN}.cd_calendar").eq(CaldavCalendar.UUID))} + ${Join.left(CaldavAccount.TABLE, CaldavCalendar.ACCOUNT.eq(CaldavAccount.UUID))} ${Join.left(Geofence.TABLE, Geofence.TASK.eq(Task.ID))} ${Join.left(Place.TABLE, Place.UID.eq(Geofence.PLACE))} """.trimIndent() val FIELDS = listOf( field("tasks.*"), - field("${TaskListFragment.GTASK_METADATA_JOIN}.*"), field("${TaskListFragment.CALDAV_METADATA_JOIN}.*"), + field("CASE ${CaldavAccount.ACCOUNT_TYPE} WHEN $TYPE_GOOGLE_TASKS THEN 1 ELSE 0 END").`as`("isGoogleTask"), field("geofences.*"), field("places.*")) diff --git a/app/src/main/java/org/tasks/data/TaskListQueryRecursive.kt b/app/src/main/java/org/tasks/data/TaskListQueryRecursive.kt index 521c199cd..20d235e7e 100644 --- a/app/src/main/java/org/tasks/data/TaskListQueryRecursive.kt +++ b/app/src/main/java/org/tasks/data/TaskListQueryRecursive.kt @@ -35,13 +35,13 @@ internal object TaskListQueryRecursive { """.trimIndent() private val GOOGLE_SUBTASKS = QueryTemplate() - .join(Join.inner(RECURSIVE, GoogleTask.PARENT.eq(RECURSIVE_TASK))) - .join(Join.inner(GoogleTask.TABLE, Criterion.and(GoogleTask.TASK.eq(Task.ID), GoogleTask.DELETED.eq(0)))) + .join(Join.inner(RECURSIVE, CaldavTask.PARENT.eq(RECURSIVE_TASK))) + .join(Join.inner(CaldavTask.TABLE, Criterion.and(CaldavTask.TASK.eq(Task.ID), CaldavTask.DELETED.eq(0)))) .where(activeAndVisible()) private val ALL_SUBTASKS = QueryTemplate() - .join(Join.inner(RECURSIVE, Criterion.or(GoogleTask.PARENT.eq(RECURSIVE_TASK), Task.PARENT.eq(RECURSIVE_TASK)))) - .join(Join.left(GoogleTask.TABLE, Criterion.and(GoogleTask.TASK.eq(Task.ID), GoogleTask.DELETED.eq(0)))) + .join(Join.inner(RECURSIVE, Criterion.or(CaldavTask.PARENT.eq(RECURSIVE_TASK), Task.PARENT.eq(RECURSIVE_TASK)))) + .join(Join.left(CaldavTask.TABLE, Criterion.and(CaldavTask.TASK.eq(Task.ID), CaldavTask.DELETED.eq(0)))) .where(activeAndVisible()) fun getRecursiveQuery( @@ -85,7 +85,7 @@ internal object TaskListQueryRecursive { when { manualSort && filter is GtasksFilter -> { sortMode = SortHelper.SORT_GTASKS - sortField = "google_tasks.gt_order" + sortField = "caldav_tasks.cd_order" } manualSort && filter is CaldavFilter -> { sortMode = SortHelper.SORT_CALDAV @@ -141,12 +141,12 @@ internal object TaskListQueryRecursive { private fun newGoogleTaskQuery(filter: GtasksFilter) = QueryTemplate() .join(Join.inner( - GoogleTask.TABLE, + CaldavTask.TABLE, Criterion.and( - GoogleTask.LIST.eq(filter.remoteId), - GoogleTask.PARENT.eq(0), - GoogleTask.TASK.eq(Task.ID), - GoogleTask.DELETED.eq(0)))) + CaldavTask.CALENDAR.eq(filter.remoteId), + CaldavTask.PARENT.eq(0), + CaldavTask.TASK.eq(Task.ID), + CaldavTask.DELETED.eq(0)))) .where(activeAndVisible()) .toString() } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/filters/FilterCriteriaProvider.kt b/app/src/main/java/org/tasks/filters/FilterCriteriaProvider.kt index 28b60341a..cae4cc8d4 100644 --- a/app/src/main/java/org/tasks/filters/FilterCriteriaProvider.kt +++ b/app/src/main/java/org/tasks/filters/FilterCriteriaProvider.kt @@ -137,10 +137,10 @@ class FilterCriteriaProvider @Inject constructor( select(Task.ID) .from(Task.TABLE) .join(left(Task.TABLE.`as`("children"), Task.ID.eq(field("children.parent")))) - .join(left(GoogleTask.TABLE, GoogleTask.PARENT.eq(Task.ID))) + .join(left(CaldavTask.TABLE, CaldavTask.PARENT.eq(Task.ID))) .where(or( isNotNull(field("children._id")), - isNotNull(GoogleTask.ID) + isNotNull(CaldavTask.ID) )) .toString() ) @@ -151,10 +151,10 @@ class FilterCriteriaProvider @Inject constructor( context.getString(R.string.custom_filter_is_subtask), select(Task.ID) .from(Task.TABLE) - .join(left(GoogleTask.TABLE, GoogleTask.TASK.eq(Task.ID))) + .join(left(CaldavTask.TABLE, CaldavTask.TASK.eq(Task.ID))) .where(or( field("${Task.PARENT}>0").eq(1), - field("${GoogleTask.PARENT}>0").eq(1) + field("${CaldavTask.PARENT}>0").eq(1) )) .toString() ) @@ -298,14 +298,14 @@ class FilterCriteriaProvider @Inject constructor( return MultipleSelectCriterion( IDENTIFIER_GTASKS, context.getString(R.string.CFC_gtasks_list_text), - select(GoogleTask.TASK) - .from(GoogleTask.TABLE) - .join(inner(Task.TABLE, GoogleTask.TASK.eq(Task.ID))) + select(CaldavTask.TASK) + .from(CaldavTask.TABLE) + .join(inner(Task.TABLE, CaldavTask.TASK.eq(Task.ID))) .where( and( activeAndVisible(), - GoogleTask.DELETED.eq(0), - GoogleTask.LIST.eq("?"))) + CaldavTask.DELETED.eq(0), + CaldavTask.CALENDAR.eq("?"))) .toString(), values, listNames, diff --git a/app/src/main/java/org/tasks/gtasks/GoogleTaskSynchronizer.kt b/app/src/main/java/org/tasks/gtasks/GoogleTaskSynchronizer.kt index 4da885563..89d0f1fe6 100644 --- a/app/src/main/java/org/tasks/gtasks/GoogleTaskSynchronizer.kt +++ b/app/src/main/java/org/tasks/gtasks/GoogleTaskSynchronizer.kt @@ -179,7 +179,7 @@ class GoogleTaskSynchronizer @Inject constructor( @Throws(IOException::class) private suspend fun pushTask(task: com.todoroo.astrid.data.Task, gtasksInvoker: GtasksInvoker) { for (deleted in googleTaskDao.getDeletedByTaskId(task.id)) { - gtasksInvoker.deleteGtask(deleted.listId, deleted.remoteId) + gtasksInvoker.deleteGtask(deleted.calendar, deleted.remoteId) googleTaskDao.delete(deleted) } val gtasksMetadata = googleTaskDao.getByTaskId(task.id) ?: return @@ -189,14 +189,14 @@ class GoogleTaskSynchronizer @Inject constructor( val defaultRemoteList = defaultFilterProvider.defaultList var listId = if (defaultRemoteList is GtasksFilter) defaultRemoteList.remoteId else DEFAULT_LIST if (isNullOrEmpty(gtasksMetadata.remoteId)) { // Create case - val selectedList = gtasksMetadata.listId + val selectedList = gtasksMetadata.calendar if (!isNullOrEmpty(selectedList)) { listId = selectedList } newlyCreated = true } else { // update case remoteId = gtasksMetadata.remoteId - listId = gtasksMetadata.listId + listId = gtasksMetadata.calendar remoteModel.id = remoteId } @@ -227,7 +227,7 @@ class GoogleTaskSynchronizer @Inject constructor( val parent = gtasksMetadata.parent val localParent = if (parent > 0) googleTaskDao.getRemoteId(parent) else null val previous = googleTaskDao.getPrevious( - listId!!, if (isNullOrEmpty(localParent)) 0 else parent, gtasksMetadata.order) + listId!!, if (isNullOrEmpty(localParent)) 0 else parent, gtasksMetadata.order ?: 0) val created: Task? created = try { gtasksInvoker.createGtask(listId, remoteModel, localParent, previous) @@ -237,7 +237,7 @@ class GoogleTaskSynchronizer @Inject constructor( if (created != null) { // Update the metadata for the newly created task gtasksMetadata.remoteId = created.id - gtasksMetadata.listId = listId + gtasksMetadata.calendar = listId setOrderAndParent(gtasksMetadata, created) } else { return @@ -251,7 +251,7 @@ class GoogleTaskSynchronizer @Inject constructor( val previous = googleTaskDao.getPrevious( listId!!, if (isNullOrEmpty(localParent)) 0 else parent, - gtasksMetadata.order) + gtasksMetadata.order ?: 0) gtasksInvoker .moveGtask(listId, remoteModel.id, localParent, previous) ?.let { setOrderAndParent(gtasksMetadata, it) } @@ -303,7 +303,7 @@ class GoogleTaskSynchronizer @Inject constructor( var googleTask = googleTaskDao.getByRemoteId(remoteId) var task: com.todoroo.astrid.data.Task? = null if (googleTask == null) { - googleTask = GoogleTask(0, "") + googleTask = CaldavTask(0, "") } else if (googleTask.task > 0) { task = taskDao.fetch(googleTask.task) } @@ -339,7 +339,7 @@ class GoogleTaskSynchronizer @Inject constructor( val dueDate = GtasksApiUtilities.gtasksDueTimeToUnixTime(gtask.due?.let(::DateTime)) mergeDates(createDueDate(com.todoroo.astrid.data.Task.URGENCY_SPECIFIC_DAY, dueDate), task) task.notes = getTruncatedValue(task.notes, gtask.notes, MAX_DESCRIPTION_LENGTH) - googleTask.listId = listId + googleTask.calendar = listId if (task.title?.isNotBlank() == true || task.notes?.isNotBlank() == true) { write(task, googleTask) } @@ -351,13 +351,13 @@ class GoogleTaskSynchronizer @Inject constructor( ) } - private suspend fun setOrderAndParent(googleTask: GoogleTask, task: Task) { + private suspend fun setOrderAndParent(googleTask: CaldavTask, task: Task) { task.position?.toLongOrNull()?.let { googleTask.remoteOrder = it } googleTask.remoteParent = task.parent?.takeIf { it.isNotBlank() } googleTask.parent = googleTask.remoteParent?.let { googleTaskDao.getTask(it) } ?: 0L } - private suspend fun write(task: com.todoroo.astrid.data.Task, googleTask: GoogleTask) { + private suspend fun write(task: com.todoroo.astrid.data.Task, googleTask: CaldavTask) { task.suppressSync() task.suppressRefresh() if (task.isNew) { @@ -367,7 +367,7 @@ class GoogleTaskSynchronizer @Inject constructor( taskDao.save(task) googleTask.lastSync = task.modificationDate googleTask.task = task.id - if (googleTask.isNew) { + if (googleTask.id == 0L) { googleTaskDao.insert(googleTask) } else { googleTaskDao.update(googleTask) diff --git a/app/src/main/java/org/tasks/preferences/DefaultFilterProvider.kt b/app/src/main/java/org/tasks/preferences/DefaultFilterProvider.kt index 0ffd636b4..c5d40d4b8 100644 --- a/app/src/main/java/org/tasks/preferences/DefaultFilterProvider.kt +++ b/app/src/main/java/org/tasks/preferences/DefaultFilterProvider.kt @@ -170,7 +170,7 @@ class DefaultFilterProvider @Inject constructor( val googleTask = googleTaskDao.getByTaskId(task.id) val caldavTask = caldavDao.getTask(task.id) if (googleTask != null) { - val googleTaskList = googleTaskListDao.getByRemoteId(googleTask.listId!!) + val googleTaskList = googleTaskListDao.getByRemoteId(googleTask.calendar!!) if (googleTaskList != null) { originalList = GtasksFilter(googleTaskList) } diff --git a/app/src/main/java/org/tasks/ui/ChipProvider.kt b/app/src/main/java/org/tasks/ui/ChipProvider.kt index 5708e9935..1edc772a1 100644 --- a/app/src/main/java/org/tasks/ui/ChipProvider.kt +++ b/app/src/main/java/org/tasks/ui/ChipProvider.kt @@ -99,29 +99,16 @@ class ChipProvider @Inject constructor( ) } } - if (!isSubtask && preferences.showListChip) { - if (!isNullOrEmpty(task.googleTaskList) && filter !is GtasksFilter) { - lists.getCaldavList(task.googleTaskList)?.let { list -> - FilterChip( - filter = GtasksFilter(list), - defaultIcon = R.drawable.ic_list_24px, - onClick = onClick, - showText = showText, - showIcon = showIcon, - colorProvider = this::getColor, - ) - } - } else if (!isNullOrEmpty(task.caldav) && filter !is CaldavFilter) { - lists.getCaldavList(task.caldav)?.let { list -> - FilterChip( - filter = CaldavFilter(list), - defaultIcon = R.drawable.ic_list_24px, - onClick = onClick, - showText = showText, - showIcon = showIcon, - colorProvider = this::getColor, - ) - } + if (!isSubtask && preferences.showListChip && filter !is CaldavFilter) { + lists.getCaldavList(task.caldav)?.let { list -> + FilterChip( + filter = if (task.isGoogleTask) GtasksFilter(list) else CaldavFilter(list), + defaultIcon = R.drawable.ic_list_24px, + onClick = onClick, + showText = showText, + showIcon = showIcon, + colorProvider = this::getColor, + ) } } val tagString = task.tagsString diff --git a/app/src/main/java/org/tasks/ui/NavigationDrawerViewModel.kt b/app/src/main/java/org/tasks/ui/NavigationDrawerViewModel.kt index 0b851e338..66d0340f7 100644 --- a/app/src/main/java/org/tasks/ui/NavigationDrawerViewModel.kt +++ b/app/src/main/java/org/tasks/ui/NavigationDrawerViewModel.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.launch import org.tasks.LocalBroadcastManager import org.tasks.data.TaskDao import org.tasks.filters.FilterProvider +import timber.log.Timber import javax.inject.Inject @HiltViewModel @@ -51,7 +52,12 @@ class NavigationDrawerViewModel @Inject constructor( .navDrawerItems() .onEach { if (it is Filter && it.count == -1) { - it.count = taskDao.count(it) + it.count = try { + taskDao.count(it) + } catch (e: Exception) { + Timber.e(e) + 0 + } } } .let { filters -> _viewState.update { it.copy(filters = filters) } } diff --git a/app/src/main/java/org/tasks/ui/SubtaskControlSet.kt b/app/src/main/java/org/tasks/ui/SubtaskControlSet.kt index b4c9af8c8..81ce3fa95 100644 --- a/app/src/main/java/org/tasks/ui/SubtaskControlSet.kt +++ b/app/src/main/java/org/tasks/ui/SubtaskControlSet.kt @@ -23,7 +23,7 @@ import kotlinx.coroutines.launch import org.tasks.R import org.tasks.compose.collectAsStateLifecycleAware import org.tasks.compose.edit.SubtaskRow -import org.tasks.data.GoogleTask +import org.tasks.data.CaldavTask import org.tasks.data.GoogleTaskDao import org.tasks.data.TaskDao.TaskCriteria.activeAndVisible import org.tasks.preferences.Preferences @@ -111,18 +111,18 @@ class SubtaskControlSet : TaskEditControlFragment() { private fun getQueryTemplate(task: Task): QueryTemplate = QueryTemplate() .join( Join.left( - GoogleTask.TABLE, + CaldavTask.TABLE, Criterion.and( - GoogleTask.PARENT.eq(task.id), - GoogleTask.TASK.eq(Task.ID), - GoogleTask.DELETED.eq(0) + CaldavTask.PARENT.eq(task.id), + CaldavTask.TASK.eq(Task.ID), + CaldavTask.DELETED.eq(0) ) ) ) .where( Criterion.and( activeAndVisible(), - Criterion.or(Task.PARENT.eq(task.id), GoogleTask.TASK.gt(0)) + Criterion.or(Task.PARENT.eq(task.id), CaldavTask.TASK.gt(0)) ) ) } diff --git a/app/src/main/java/org/tasks/ui/TaskEditViewModel.kt b/app/src/main/java/org/tasks/ui/TaskEditViewModel.kt index 92536db77..2c18e159e 100644 --- a/app/src/main/java/org/tasks/ui/TaskEditViewModel.kt +++ b/app/src/main/java/org/tasks/ui/TaskEditViewModel.kt @@ -292,7 +292,7 @@ class TaskEditViewModel @Inject constructor( firebase?.addTask("subtasks") when (selectedList.value) { is GtasksFilter -> { - val googleTask = GoogleTask(subtask.id, (selectedList.value as GtasksFilter).remoteId) + val googleTask = CaldavTask(subtask.id, (selectedList.value as GtasksFilter).remoteId) googleTask.parent = task.id googleTask.isMoved = true googleTaskDao.insertAndShift(googleTask, false) diff --git a/app/src/main/java/org/tasks/widget/ChipProvider.kt b/app/src/main/java/org/tasks/widget/ChipProvider.kt index 804ae1f20..3a20a5807 100644 --- a/app/src/main/java/org/tasks/widget/ChipProvider.kt +++ b/app/src/main/java/org/tasks/widget/ChipProvider.kt @@ -5,7 +5,6 @@ import android.widget.RemoteViews import com.todoroo.andlib.utility.DateUtilities import com.todoroo.astrid.api.CaldavFilter import com.todoroo.astrid.api.Filter -import com.todoroo.astrid.api.GtasksFilter import com.todoroo.astrid.api.TagFilter import com.todoroo.astrid.data.Task import dagger.hilt.android.qualifiers.ApplicationContext @@ -74,10 +73,6 @@ class ChipProvider @Inject constructor( } fun getListChip(filter: Filter?, task: TaskContainer): RemoteViews? { - task.googleTaskList - ?.takeIf { filter !is GtasksFilter } - ?.let { newChip(GtasksFilter(chipListCache.getCaldavList(it)), R.drawable.ic_list_24px) } - ?.let { return it } task.caldav ?.takeIf { filter !is CaldavFilter } ?.let { newChip(CaldavFilter(chipListCache.getCaldavList(it)), R.drawable.ic_list_24px) } diff --git a/app/src/test/java/org/tasks/makers/GoogleTaskMaker.kt b/app/src/test/java/org/tasks/makers/GoogleTaskMaker.kt index d29a02ff7..7a5f65f4e 100644 --- a/app/src/test/java/org/tasks/makers/GoogleTaskMaker.kt +++ b/app/src/test/java/org/tasks/makers/GoogleTaskMaker.kt @@ -5,7 +5,6 @@ import com.natpryce.makeiteasy.Property import com.natpryce.makeiteasy.Property.newProperty import com.natpryce.makeiteasy.PropertyValue import com.todoroo.astrid.helper.UUIDHelper -import org.tasks.data.GoogleTask import org.tasks.makers.Maker.make object GoogleTaskMaker { @@ -18,7 +17,7 @@ object GoogleTaskMaker { private val instantiator = Instantiator { val task = GoogleTask() - task.listId = it.valueOf(LIST, "1") + task.calendar = it.valueOf(LIST, "1") task.order = it.valueOf(ORDER, 0) task.remoteId = it.valueOf(REMOTE_ID, UUIDHelper.newUUID()) task.task = it.valueOf(TASK, 1)