From 3943d620a5d9e4287da5f44603db050132ac87a1 Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Thu, 11 Jan 2018 13:33:52 -0600 Subject: [PATCH] Add 'google_tasks' table --- .../com.todoroo.astrid.dao.Database/50.json | 693 ++++++++++++++++++ .../java/org/tasks/location/GeofenceApi.java | 8 +- .../java/org/tasks/location/PlacePicker.java | 3 +- .../astrid/alarms/AlarmJobServiceTest.java | 23 +- .../todoroo/astrid/dao/MetadataDaoTests.java | 169 ----- .../astrid/repeats/NewRepeatTests.java | 16 +- .../java/org/tasks/injection/TestModule.java | 26 +- .../astrid/gtasks/GtasksIndentActionTest.java | 21 +- .../astrid/gtasks/GtasksListServiceTest.java | 8 +- .../gtasks/GtasksMetadataServiceTest.java | 20 +- .../gtasks/GtasksTaskListUpdaterTest.java | 32 +- .../astrid/gtasks/GtasksTaskMovingTest.java | 28 +- .../org/tasks/injection/TestComponent.java | 3 - .../java/org/tasks/location/GeofenceApi.java | 8 +- .../java/org/tasks/location/PlacePicker.java | 3 +- .../astrid/gtasks/GtasksListService.java | 13 +- .../astrid/gtasks/GtasksPreferences.java | 7 +- .../gtasks/GtasksSubtaskListFragment.java | 5 +- .../astrid/gtasks/GtasksTaskListUpdater.java | 116 ++- .../OrderedMetadataListFragmentHelper.java | 23 +- .../astrid/gtasks/sync/GtasksSyncService.java | 110 ++- .../gtasks/sync/GtasksTaskContainer.java | 14 +- .../tasks/gtasks/GoogleTaskSyncAdapter.java | 110 ++- .../org/tasks/ui/GoogleTaskListFragment.java | 30 +- .../com/todoroo/astrid/api/GtasksFilter.java | 32 +- .../astrid/backup/BackupConstants.java | 2 + .../astrid/backup/TasksXmlExporter.java | 31 +- .../astrid/backup/TasksXmlImporter.java | 76 +- .../astrid/core/OldTaskPreferences.java | 7 +- .../java/com/todoroo/astrid/dao/Database.java | 15 +- .../com/todoroo/astrid/dao/MetadataDao.java | 139 ---- .../java/com/todoroo/astrid/dao/TaskDao.java | 27 +- .../com/todoroo/astrid/data/Metadata.java | 179 ----- .../java/com/todoroo/astrid/data/TagData.java | 2 +- .../todoroo/astrid/gtasks/GtasksMetadata.java | 82 --- .../astrid/service/StartupService.java | 7 +- .../todoroo/astrid/service/TaskCreator.java | 43 +- .../astrid/service/TaskDuplicator.java | 39 +- .../todoroo/astrid/tags/TagsControlSet.java | 4 - .../main/java/org/tasks/backup/XmlReader.java | 38 +- app/src/main/java/org/tasks/data/Alarm.java | 8 +- .../main/java/org/tasks/data/AlarmDao.java | 5 +- .../main/java/org/tasks/data/GoogleTask.java | 200 +++++ .../java/org/tasks/data/GoogleTaskDao.java | 51 ++ .../main/java/org/tasks/data/Location.java | 2 - .../main/java/org/tasks/data/LocationDao.java | 3 + app/src/main/java/org/tasks/data/Tag.java | 2 - app/src/main/java/org/tasks/data/TagDao.java | 6 + .../main/java/org/tasks/db/Migrations.java | 13 +- .../tasks/filters/FilterCriteriaProvider.java | 30 +- .../tasks/injection/ApplicationModule.java | 9 +- .../org/tasks/tasklist/TagListFragment.java | 3 +- 52 files changed, 1444 insertions(+), 1100 deletions(-) create mode 100644 app/schemas/com.todoroo.astrid.dao.Database/50.json delete mode 100644 app/src/androidTest/java/com/todoroo/astrid/dao/MetadataDaoTests.java delete mode 100644 app/src/main/java/com/todoroo/astrid/dao/MetadataDao.java delete mode 100644 app/src/main/java/com/todoroo/astrid/data/Metadata.java delete mode 100644 app/src/main/java/com/todoroo/astrid/gtasks/GtasksMetadata.java create mode 100644 app/src/main/java/org/tasks/data/GoogleTask.java create mode 100644 app/src/main/java/org/tasks/data/GoogleTaskDao.java diff --git a/app/schemas/com.todoroo.astrid.dao.Database/50.json b/app/schemas/com.todoroo.astrid.dao.Database/50.json new file mode 100644 index 000000000..dce114421 --- /dev/null +++ b/app/schemas/com.todoroo.astrid.dao.Database/50.json @@ -0,0 +1,693 @@ +{ + "formatVersion": 1, + "database": { + "version": 50, + "identityHash": "e08be332b5c3e35040e5fd89d68fd304", + "entities": [ + { + "tableName": "notification", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `type` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "uid", + "columnName": "uid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "taskId", + "columnName": "task", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "uid" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_notification_task", + "unique": true, + "columnNames": [ + "task" + ], + "createSql": "CREATE UNIQUE INDEX `index_notification_task` ON `${TABLE_NAME}` (`task`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "tagdata", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `remoteId` TEXT, `name` TEXT, `color` INTEGER, `tagOrdering` TEXT, `deleted` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "remoteId", + "columnName": "remoteId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "color", + "columnName": "color", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "tagOrdering", + "columnName": "tagOrdering", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "deleted", + "columnName": "deleted", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "userActivity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `remoteId` TEXT, `action` TEXT, `message` TEXT, `picture` TEXT, `target_id` TEXT, `created_at` INTEGER, `deleted_at` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "remoteId", + "columnName": "remoteId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "action", + "columnName": "action", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "message", + "columnName": "message", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "picture", + "columnName": "picture", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "targetId", + "columnName": "target_id", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "created", + "columnName": "created_at", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "deleted", + "columnName": "deleted_at", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "task_attachments", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `remoteId` TEXT, `task_id` TEXT, `name` TEXT, `path` TEXT, `content_type` TEXT, `deleted_at` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "remoteId", + "columnName": "remoteId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "taskId", + "columnName": "task_id", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "path", + "columnName": "path", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "contentType", + "columnName": "content_type", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "deleted", + "columnName": "deleted_at", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "task_list_metadata", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `remoteId` TEXT, `tag_uuid` TEXT, `filter` TEXT, `task_ids` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "remoteId", + "columnName": "remoteId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "tagUuid", + "columnName": "tag_uuid", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "filter", + "columnName": "filter", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "taskIds", + "columnName": "task_ids", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "store", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `type` TEXT, `item` TEXT, `value` TEXT, `value2` TEXT, `value3` TEXT, `value4` TEXT, `deleted` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "item", + "columnName": "item", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "value2", + "columnName": "value2", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "value3", + "columnName": "value3", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "value4", + "columnName": "value4", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "deleted", + "columnName": "deleted", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "so_id", + "unique": false, + "columnNames": [ + "type", + "item" + ], + "createSql": "CREATE INDEX `so_id` ON `${TABLE_NAME}` (`type`, `item`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "tasks", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT, `importance` INTEGER, `dueDate` INTEGER, `hideUntil` INTEGER, `created` INTEGER, `modified` INTEGER, `completed` INTEGER, `deleted` INTEGER, `notes` TEXT, `estimatedSeconds` INTEGER, `elapsedSeconds` INTEGER, `timerStart` INTEGER, `notificationFlags` INTEGER, `notifications` INTEGER, `lastNotified` INTEGER, `snoozeTime` INTEGER, `recurrence` TEXT, `repeatUntil` INTEGER, `calendarUri` TEXT, `remoteId` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "importance", + "columnName": "importance", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "dueDate", + "columnName": "dueDate", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "hideUntil", + "columnName": "hideUntil", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "created", + "columnName": "created", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "modified", + "columnName": "modified", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "completed", + "columnName": "completed", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "deleted", + "columnName": "deleted", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "notes", + "columnName": "notes", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "estimatedSeconds", + "columnName": "estimatedSeconds", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "elapsedSeconds", + "columnName": "elapsedSeconds", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "timerStart", + "columnName": "timerStart", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "notificationFlags", + "columnName": "notificationFlags", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "notifications", + "columnName": "notifications", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "lastNotified", + "columnName": "lastNotified", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "snoozeTime", + "columnName": "snoozeTime", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "recurrence", + "columnName": "recurrence", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "repeatUntil", + "columnName": "repeatUntil", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "calendarUri", + "columnName": "calendarUri", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "remoteId", + "columnName": "remoteId", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "t_rid", + "unique": true, + "columnNames": [ + "remoteId" + ], + "createSql": "CREATE UNIQUE INDEX `t_rid` ON `${TABLE_NAME}` (`remoteId`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "alarms", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `time` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "task", + "columnName": "task", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "time", + "columnName": "time", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "locations", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `name` TEXT, `latitude` REAL NOT NULL, `longitude` REAL NOT NULL, `radius` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "task", + "columnName": "task", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "latitude", + "columnName": "latitude", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "longitude", + "columnName": "longitude", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "radius", + "columnName": "radius", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "tags", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `name` TEXT, `tag_uid` TEXT, `task_uid` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "task", + "columnName": "task", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "tagUid", + "columnName": "tag_uid", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "taskUid", + "columnName": "task_uid", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "google_tasks", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `remote_id` TEXT, `list_id` TEXT, `parent` INTEGER NOT NULL, `indent` INTEGER NOT NULL, `order` INTEGER NOT NULL, `remote_order` INTEGER NOT NULL, `last_sync` INTEGER NOT NULL, `deleted` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "task", + "columnName": "task", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteId", + "columnName": "remote_id", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "listId", + "columnName": "list_id", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "parent", + "columnName": "parent", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "indent", + "columnName": "indent", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "order", + "columnName": "order", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteOrder", + "columnName": "remote_order", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastSync", + "columnName": "last_sync", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "deleted", + "columnName": "deleted", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + } + ], + "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, \"e08be332b5c3e35040e5fd89d68fd304\")" + ] + } +} \ No newline at end of file diff --git a/app/src/amazon/java/org/tasks/location/GeofenceApi.java b/app/src/amazon/java/org/tasks/location/GeofenceApi.java index d7a406d82..1c07156eb 100644 --- a/app/src/amazon/java/org/tasks/location/GeofenceApi.java +++ b/app/src/amazon/java/org/tasks/location/GeofenceApi.java @@ -1,5 +1,7 @@ package org.tasks.location; +import org.tasks.data.Location; + import java.util.List; import javax.inject.Inject; @@ -12,15 +14,15 @@ public class GeofenceApi { } - public void register(List activeGeofences) { + public void register(List activeGeofences) { } - public void cancel(Geofence geofence) { + public void cancel(Location geofence) { } - public void cancel(List geofences) { + public void cancel(List geofences) { } } diff --git a/app/src/amazon/java/org/tasks/location/PlacePicker.java b/app/src/amazon/java/org/tasks/location/PlacePicker.java index 187568317..0cc390a42 100644 --- a/app/src/amazon/java/org/tasks/location/PlacePicker.java +++ b/app/src/amazon/java/org/tasks/location/PlacePicker.java @@ -4,6 +4,7 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; +import org.tasks.data.Location; import org.tasks.preferences.Preferences; public class PlacePicker { @@ -11,7 +12,7 @@ public class PlacePicker { return null; } - public static Geofence getPlace(Context context, Intent data, Preferences preferences) { + public static Location getPlace(Context context, Intent data, Preferences preferences) { return null; } } diff --git a/app/src/androidTest/java/com/todoroo/astrid/alarms/AlarmJobServiceTest.java b/app/src/androidTest/java/com/todoroo/astrid/alarms/AlarmJobServiceTest.java index 47442a12a..de6c6b266 100644 --- a/app/src/androidTest/java/com/todoroo/astrid/alarms/AlarmJobServiceTest.java +++ b/app/src/androidTest/java/com/todoroo/astrid/alarms/AlarmJobServiceTest.java @@ -2,9 +2,7 @@ package com.todoroo.astrid.alarms; import android.support.test.runner.AndroidJUnit4; -import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.TaskDao; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.Task; import org.junit.After; @@ -12,6 +10,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; +import org.tasks.data.Alarm; +import org.tasks.data.AlarmDao; import org.tasks.injection.InjectingTestCase; import org.tasks.injection.TestComponent; import org.tasks.jobs.AlarmJob; @@ -30,7 +30,7 @@ import static org.tasks.makers.TaskMaker.newTask; @RunWith(AndroidJUnit4.class) public class AlarmJobServiceTest extends InjectingTestCase { - @Inject MetadataDao metadataDao; + @Inject AlarmDao alarmDao; @Inject TaskDao taskDao; private AlarmService alarmService; @@ -39,7 +39,7 @@ public class AlarmJobServiceTest extends InjectingTestCase { @Before public void before() { jobs = mock(JobQueue.class); - alarmService = new AlarmService(metadataDao, jobs); + alarmService = new AlarmService(alarmDao, jobs); } @After @@ -54,12 +54,8 @@ public class AlarmJobServiceTest extends InjectingTestCase { taskDao.persist(task); DateTime alarmTime = new DateTime(2017, 9, 24, 19, 57); - Metadata alarm = new Metadata(); - alarm.setTask(task.getId()); - alarm.setKey(AlarmFields.METADATA_KEY); - alarm.setValue(AlarmFields.TYPE, AlarmFields.TYPE_SINGLE); - alarm.setValue(AlarmFields.TIME, alarmTime.getMillis()); - metadataDao.persist(alarm); + Alarm alarm = new Alarm(task.getId(), alarmTime.getMillis()); + alarm.setId(alarmDao.insert(alarm)); alarmService.scheduleAllAlarms(); @@ -75,12 +71,7 @@ public class AlarmJobServiceTest extends InjectingTestCase { taskDao.persist(task); - Metadata alarm = new Metadata(); - alarm.setTask(task.getId()); - alarm.setKey(AlarmFields.METADATA_KEY); - alarm.setValue(AlarmFields.TYPE, AlarmFields.TYPE_SINGLE); - alarm.setValue(AlarmFields.TIME, alarmTime.getMillis()); - metadataDao.persist(alarm); + alarmDao.insert(new Alarm(task.getId(), alarmTime.getMillis())); alarmService.scheduleAllAlarms(); diff --git a/app/src/androidTest/java/com/todoroo/astrid/dao/MetadataDaoTests.java b/app/src/androidTest/java/com/todoroo/astrid/dao/MetadataDaoTests.java deleted file mode 100644 index bf2f8a2b8..000000000 --- a/app/src/androidTest/java/com/todoroo/astrid/dao/MetadataDaoTests.java +++ /dev/null @@ -1,169 +0,0 @@ -/** - * Copyright (c) 2012 Todoroo Inc - * - * See the file "LICENSE" for the full license governing this code. - */ -package com.todoroo.astrid.dao; - -import android.support.test.runner.AndroidJUnit4; - -import com.todoroo.andlib.data.Property; -import com.todoroo.andlib.sql.Query; -import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria; -import com.todoroo.astrid.data.Metadata; -import com.todoroo.astrid.data.Task; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.tasks.injection.InjectingTestCase; -import org.tasks.injection.TestComponent; - -import java.util.List; - -import javax.inject.Inject; - -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertNotNull; -import static junit.framework.Assert.assertNotSame; -import static junit.framework.Assert.assertNull; -import static junit.framework.Assert.assertTrue; -import static junit.framework.Assert.fail; - -@RunWith(AndroidJUnit4.class) -public class MetadataDaoTests extends InjectingTestCase { - - @Inject MetadataDao metadataDao; - @Inject TaskDao taskDao; - - private Metadata metadata; - - public static Property[] KEYS = new Property[] { Metadata.ID, Metadata.KEY }; - - @Override - public void setUp() { - super.setUp(); - metadata = new Metadata(); - } - - @Override - protected void inject(TestComponent component) { - component.inject(this); - } - - /** - * Test basic creation, fetch, and save - */ - @Test - public void testCrud() throws Exception { - assertTrue(metadataDao.toList(Query.select(Metadata.ID)).isEmpty()); - - // create "happy" - Metadata metadata = new Metadata(); - metadata.setTask(1L); - metadata.setKey("happy"); - assertTrue(metadataDao.persist(metadata)); - assertEquals(1, metadataDao.toList(Query.select(Metadata.ID)).size()); - long happyId = metadata.getId(); - assertNotSame(Metadata.NO_ID, happyId); - metadata = metadataDao.fetch(happyId); - assertEquals("happy", metadata.getKey()); - - // create "sad" - metadata = new Metadata(); - metadata.setTask(1L); - metadata.setKey("sad"); - assertTrue(metadataDao.persist(metadata)); - assertEquals(2, metadataDao.toList(Query.select(Metadata.ID)).size()); - - // rename sad to melancholy - long sadId = metadata.getId(); - assertNotSame(Metadata.NO_ID, sadId); - metadata.setKey("melancholy"); - assertTrue(metadataDao.persist(metadata)); - assertEquals(2, metadataDao.toList(Query.select(Metadata.ID)).size()); - - // check state - metadata = metadataDao.fetch(happyId); - assertEquals("happy", metadata.getKey()); - metadata = metadataDao.fetch(sadId); - assertEquals("melancholy", metadata.getKey()); - - // delete sad - assertTrue(metadataDao.delete(sadId)); - List metadataList = metadataDao.toList(Query.select(KEYS)); - assertEquals(1, metadataList.size()); - assertEquals("happy", metadataList.get(0).getKey()); - } - - /** - * Test metadata bound to task - */ - @Test - public void testMetadataConditions() { - // create "happy" - Metadata metadata = new Metadata(); - metadata.setKey("with1"); - metadata.setTask(1L); - assertTrue(metadataDao.persist(metadata)); - - metadata = new Metadata(); - metadata.setKey("with2"); - metadata.setTask(2L); - assertTrue(metadataDao.persist(metadata)); - - metadata = new Metadata(); - metadata.setKey("with1"); - metadata.setTask(1L); - assertTrue(metadataDao.persist(metadata)); - - List metadataList = metadataDao.toList(Query.select(KEYS).where(MetadataCriteria.byTask(1))); - assertEquals(2, metadataList.size()); - assertEquals("with1", metadataList.get(0).getKey()); - assertEquals("with1", metadataList.get(1).getKey()); - - assertTrue(metadataDao.toList(Query.select(KEYS).where(MetadataCriteria.byTask(3))).isEmpty()); - - assertEquals(2, metadataDao.deleteWhere(MetadataCriteria.byTask(1))); - assertEquals(1, metadataDao.toList(Query.select(KEYS)).size()); - } - - @Test - public void testDontSaveMetadataWithoutTaskId() { - try { - metadataDao.persist(metadata); - fail("expected exception"); - } catch(IllegalArgumentException e) { - assertTrue(e.getMessage().startsWith("metadata needs to be attached to a task")); - } - } - - @Test - public void testSaveMetadata() { - metadata.setTask(1L); - metadataDao.persist(metadata); - - assertNotNull(metadataDao.fetch(metadata.getId())); - } - - @Test - public void testDontDeleteValidMetadata() { - final Task task = new Task(); - taskDao.save(task); - metadata.setTask(task.getId()); - metadataDao.persist(metadata); - - metadataDao.removeDanglingMetadata(); - - assertNotNull(metadataDao.fetch(metadata.getId())); - } - - @Test - public void testDeleteDangling() { - metadata.setTask(1L); - metadataDao.persist(metadata); - - metadataDao.removeDanglingMetadata(); - - assertNull(metadataDao.fetch(1)); - } -} diff --git a/app/src/androidTest/java/com/todoroo/astrid/repeats/NewRepeatTests.java b/app/src/androidTest/java/com/todoroo/astrid/repeats/NewRepeatTests.java index d28cd028f..b63b3f54e 100644 --- a/app/src/androidTest/java/com/todoroo/astrid/repeats/NewRepeatTests.java +++ b/app/src/androidTest/java/com/todoroo/astrid/repeats/NewRepeatTests.java @@ -213,32 +213,32 @@ public class NewRepeatTests { return new DateTime(computeNextDueDate(task, task.sanitizedRecurrence(), task.repeatAfterCompletion())); } - private Task newFromDue(Frequency frequency, int interval, DateTime dueDate) { + private Task newFromDue(Frequency frequency, int interval, DateTime dueDateTime) { return new Task() {{ setRecurrence(getRecurrenceRule(frequency, interval, false)); - setDueDate(dueDate.getMillis()); + setDueDate(dueDateTime.getMillis()); }}; } - private Task newWeeklyFromDue(int interval, DateTime dueDate, WeekdayNum... weekdays) { + private Task newWeeklyFromDue(int interval, DateTime dueDateTime, WeekdayNum... weekdays) { return new Task() {{ setRecurrence(getRecurrenceRule(Frequency.WEEKLY, interval, false, weekdays)); - setDueDate(dueDate.getMillis()); + setDueDate(dueDateTime.getMillis()); }}; } - private Task newFromCompleted(Frequency frequency, int interval, DateTime dueDate, DateTime completionDate) { + private Task newFromCompleted(Frequency frequency, int interval, DateTime dueDateTime, DateTime completionDate) { return new Task() {{ setRecurrence(getRecurrenceRule(frequency, interval, true)); - setDueDate(dueDate.getMillis()); + setDueDate(dueDateTime.getMillis()); setCompletionDate(completionDate.getMillis()); }}; } - private Task newWeeklyFromCompleted(int interval, DateTime dueDate, DateTime completionDate, WeekdayNum... weekdays) { + private Task newWeeklyFromCompleted(int interval, DateTime dueDateTime, DateTime completionDate, WeekdayNum... weekdays) { return new Task() {{ setRecurrence(getRecurrenceRule(Frequency.WEEKLY, interval, true, weekdays)); - setDueDate(dueDate.getMillis()); + setDueDate(dueDateTime.getMillis()); setCompletionDate(completionDate.getMillis()); }}; } diff --git a/app/src/androidTest/java/org/tasks/injection/TestModule.java b/app/src/androidTest/java/org/tasks/injection/TestModule.java index e318d2c9e..52209a9d8 100644 --- a/app/src/androidTest/java/org/tasks/injection/TestModule.java +++ b/app/src/androidTest/java/org/tasks/injection/TestModule.java @@ -9,7 +9,10 @@ import com.todoroo.astrid.dao.TagDataDao; import com.todoroo.astrid.dao.TaskListMetadataDao; import com.todoroo.astrid.dao.UserActivityDao; -import org.tasks.db.Migrations; +import org.tasks.data.AlarmDao; +import org.tasks.data.GoogleTaskDao; +import org.tasks.data.LocationDao; +import org.tasks.data.TagDao; import org.tasks.notifications.NotificationDao; import org.tasks.preferences.PermissionChecker; import org.tasks.preferences.PermissivePermissionChecker; @@ -30,7 +33,6 @@ public class TestModule { public Database getDatabase() { return Room.inMemoryDatabaseBuilder(context, Database.class) .fallbackToDestructiveMigration() - .addCallback(Migrations.ON_CREATE) .build(); } @@ -59,6 +61,26 @@ public class TestModule { return database.getStoreObjectDao(); } + @Provides + public AlarmDao getAlarmDao(Database database) { + return database.getAlarmDao(); + } + + @Provides + public GoogleTaskDao getGoogleTaskDao(Database database) { + return database.getGoogleTaskDao(); + } + + @Provides + public TagDao getTagDao(Database database) { + return database.getTagDao(); + } + + @Provides + public LocationDao getLocationDao(Database database) { + return database.getLocationDao(); + } + @ApplicationScope @Provides @ForApplication diff --git a/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksIndentActionTest.java b/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksIndentActionTest.java index ba3ba0e79..3daa23484 100644 --- a/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksIndentActionTest.java +++ b/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksIndentActionTest.java @@ -8,13 +8,13 @@ package com.todoroo.astrid.gtasks; import android.support.test.runner.AndroidJUnit4; import com.google.api.services.tasks.model.TaskList; -import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.TaskDao; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.Task; import org.junit.Test; import org.junit.runner.RunWith; +import org.tasks.data.GoogleTask; +import org.tasks.data.GoogleTaskDao; import org.tasks.injection.InjectingTestCase; import org.tasks.injection.TestComponent; @@ -32,9 +32,8 @@ public class GtasksIndentActionTest extends InjectingTestCase { @Inject GtasksListService gtasksListService; @Inject GtasksTaskListUpdater gtasksTaskListUpdater; - @Inject MetadataDao metadataDao; - @Inject GtasksMetadata gtasksMetadata; @Inject TaskDao taskDao; + @Inject GoogleTaskDao googleTaskDao; private Task task; private GtasksList storeList; @@ -176,12 +175,10 @@ public class GtasksIndentActionTest extends InjectingTestCase { private Task taskWithMetadata(long order, int indentation) { Task newTask = new Task(); taskDao.save(newTask); - Metadata metadata = gtasksMetadata.createEmptyMetadata(newTask.getId()); - metadata.setValue(GtasksMetadata.INDENT, indentation); - metadata.setValue(GtasksMetadata.ORDER, order); - metadata.setValue(GtasksMetadata.LIST_ID, "list"); - metadata.setTask(newTask.getId()); - metadataDao.persist(metadata); + GoogleTask metadata = new GoogleTask(newTask.getId(), "list"); + metadata.setIndent(indentation); + metadata.setOrder(order); + googleTaskDao.insert(metadata); return newTask; } @@ -190,9 +187,9 @@ public class GtasksIndentActionTest extends InjectingTestCase { } private void thenExpectIndentationLevel(Task targetTask, int expected) { - Metadata metadata = metadataDao.getFirstActiveByTaskAndKey(targetTask.getId(), GtasksMetadata.METADATA_KEY); + GoogleTask metadata = googleTaskDao.getByTaskId(targetTask.getId()); assertNotNull("task has metadata", metadata); - int indentation = metadata.getValue(GtasksMetadata.INDENT); + int indentation = metadata.getIndent(); assertTrue("indentation: " + indentation, indentation == expected); } diff --git a/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksListServiceTest.java b/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksListServiceTest.java index 5da7d7663..119d44398 100644 --- a/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksListServiceTest.java +++ b/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksListServiceTest.java @@ -4,14 +4,13 @@ import android.support.test.runner.AndroidJUnit4; import com.google.api.client.util.DateTime; import com.google.api.services.tasks.model.TaskList; -import com.todoroo.astrid.dao.Database; -import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.StoreObjectDao; import com.todoroo.astrid.service.TaskDeleter; import org.junit.Test; import org.junit.runner.RunWith; import org.tasks.LocalBroadcastManager; +import org.tasks.data.GoogleTaskDao; import org.tasks.data.TaskListDataProvider; import org.tasks.injection.InjectingTestCase; import org.tasks.injection.TestComponent; @@ -35,11 +34,10 @@ import static org.tasks.time.DateTimeUtils.currentTimeMillis; @RunWith(AndroidJUnit4.class) public class GtasksListServiceTest extends InjectingTestCase { - @Inject Database database; @Inject TaskListDataProvider taskListDataProvider; @Inject TaskDeleter taskDeleter; - @Inject MetadataDao metadataDao; @Inject LocalBroadcastManager localBroadcastManager; + @Inject GoogleTaskDao googleTaskDao; @Inject StoreObjectDao storeObjectDao; private GtasksListService gtasksListService; @@ -48,7 +46,7 @@ public class GtasksListServiceTest extends InjectingTestCase { public void setUp() { super.setUp(); gtasksListService = new GtasksListService(storeObjectDao, taskListDataProvider, taskDeleter, - metadataDao, localBroadcastManager); + localBroadcastManager, googleTaskDao); } @Override diff --git a/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksMetadataServiceTest.java b/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksMetadataServiceTest.java index 2e9ba2971..28d73d9e4 100644 --- a/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksMetadataServiceTest.java +++ b/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksMetadataServiceTest.java @@ -8,13 +8,13 @@ package com.todoroo.astrid.gtasks; import android.content.Context; import android.support.test.runner.AndroidJUnit4; -import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.TaskDao; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.Task; import org.junit.Test; import org.junit.runner.RunWith; +import org.tasks.data.GoogleTask; +import org.tasks.data.GoogleTaskDao; import org.tasks.injection.InjectingTestCase; import org.tasks.injection.TestComponent; import org.tasks.preferences.Preferences; @@ -58,12 +58,11 @@ public class GtasksMetadataServiceTest extends InjectingTestCase { } @Inject GtasksTestPreferenceService preferences; - @Inject MetadataDao metadataDao; - @Inject GtasksMetadata gtasksMetadata; @Inject TaskDao taskDao; + @Inject GoogleTaskDao googleTaskDao; private Task task; - private Metadata metadata; + private GoogleTask metadata; @Override public void setUp() { @@ -110,18 +109,19 @@ public class GtasksMetadataServiceTest extends InjectingTestCase { } private void whenSearchForMetadata() { - metadata = metadataDao.getFirstActiveByTaskAndKey(task.getId(), GtasksMetadata.METADATA_KEY); + metadata = googleTaskDao.getByTaskId(task.getId()); } private Task taskWithMetadata(String id) { Task task = new Task(); task.setTitle("cats"); taskDao.save(task); - Metadata metadata = gtasksMetadata.createEmptyMetadata(task.getId()); - if (id != null) - metadata.setValue(GtasksMetadata.ID, id); + GoogleTask metadata = new GoogleTask(task.getId(), ""); + if (id != null) { + metadata.setRemoteId(id); + } metadata.setTask(task.getId()); - metadataDao.persist(metadata); + googleTaskDao.insert(metadata); return task; } diff --git a/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksTaskListUpdaterTest.java b/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksTaskListUpdaterTest.java index 8b5971b60..fcc55c874 100644 --- a/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksTaskListUpdaterTest.java +++ b/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksTaskListUpdaterTest.java @@ -8,14 +8,14 @@ package com.todoroo.astrid.gtasks; import android.support.test.runner.AndroidJUnit4; import com.google.api.services.tasks.model.TaskList; -import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.TaskDao; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.Task; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; +import org.tasks.data.GoogleTask; +import org.tasks.data.GoogleTaskDao; import org.tasks.injection.InjectingTestCase; import org.tasks.injection.TestComponent; @@ -35,9 +35,8 @@ public class GtasksTaskListUpdaterTest extends InjectingTestCase { @Inject GtasksTaskListUpdater gtasksTaskListUpdater; @Inject GtasksListService gtasksListService; - @Inject MetadataDao metadataDao; @Inject TaskDao taskDao; - @Inject GtasksMetadata gtasksMetadata; + @Inject GoogleTaskDao googleTaskDao; @Test public void testBasicParentComputation() { @@ -102,15 +101,15 @@ public class GtasksTaskListUpdaterTest extends InjectingTestCase { // --- helpers private void thenExpectMetadataIndentAndOrder(Task task, long order, int indent) { - Metadata metadata = metadataDao.getFirstActiveByTaskAndKey(task.getId(), GtasksMetadata.METADATA_KEY); + GoogleTask metadata = googleTaskDao.getByTaskId(task.getId()); assertNotNull("metadata was found", metadata); - assertEquals("order", order, metadata.getValue(GtasksMetadata.ORDER).longValue()); - assertEquals("indentation", indent, (int)metadata.getValue(GtasksMetadata.INDENT)); + assertEquals("order", order, metadata.getOrder()); + assertEquals("indentation", indent, metadata.getIndent()); } private void thenExpectMetadataParent(Task task, Task expectedParent) { - Metadata metadata = metadataDao.getFirstActiveByTaskAndKey(task.getId(), GtasksMetadata.METADATA_KEY); - long parent = metadata.getValue(GtasksMetadata.PARENT_TASK); + GoogleTask metadata = googleTaskDao.getByTaskId(task.getId()); + long parent = metadata.getParent(); if(expectedParent == null) assertEquals("Task " + task.getTitle() + " parent none", 0, parent); else @@ -185,13 +184,14 @@ public class GtasksTaskListUpdaterTest extends InjectingTestCase { Task task = new Task(); task.setTitle(title); taskDao.save(task); - Metadata metadata = gtasksMetadata.createEmptyMetadata(task.getId()); - metadata.setValue(GtasksMetadata.LIST_ID, "1"); - if(order != VALUE_UNSET) - metadata.setValue(GtasksMetadata.ORDER, order); - if(indent != VALUE_UNSET) - metadata.setValue(GtasksMetadata.INDENT, indent); - metadataDao.persist(metadata); + GoogleTask metadata = new GoogleTask(task.getId(), "1"); + if(order != VALUE_UNSET) { + metadata.setOrder(order); + } + if(indent != VALUE_UNSET) { + metadata.setIndent(indent); + } + googleTaskDao.insert(metadata); return task; } } diff --git a/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksTaskMovingTest.java b/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksTaskMovingTest.java index e33738260..364ef1827 100644 --- a/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksTaskMovingTest.java +++ b/app/src/androidTestGoogleplay/java/com/todoroo/astrid/gtasks/GtasksTaskMovingTest.java @@ -8,13 +8,13 @@ package com.todoroo.astrid.gtasks; import android.support.test.runner.AndroidJUnit4; import com.google.api.services.tasks.model.TaskList; -import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.TaskDao; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.Task; import org.junit.Test; import org.junit.runner.RunWith; +import org.tasks.data.GoogleTask; +import org.tasks.data.GoogleTaskDao; import org.tasks.injection.InjectingTestCase; import org.tasks.injection.TestComponent; @@ -34,9 +34,8 @@ public class GtasksTaskMovingTest extends InjectingTestCase { @Inject GtasksListService gtasksListService; @Inject GtasksTaskListUpdater gtasksTaskListUpdater; - @Inject MetadataDao metadataDao; @Inject TaskDao taskDao; - @Inject GtasksMetadata gtasksMetadata; + @Inject GoogleTaskDao googleTaskDao; private Task A, B, C, D, E, F; private GtasksList list; @@ -255,10 +254,10 @@ public class GtasksTaskMovingTest extends InjectingTestCase { } private void thenExpectMetadataOrderAndIndent(Task task, long order, int indent) { - Metadata metadata = metadataDao.getFirstActiveByTaskAndKey(task.getId(), GtasksMetadata.METADATA_KEY); + GoogleTask metadata = googleTaskDao.getByTaskId(task.getId()); assertNotNull("metadata was found", metadata); - assertEquals("order", order, metadata.getValue(GtasksMetadata.ORDER).longValue()); - assertEquals("indentation", indent, (int)metadata.getValue(GtasksMetadata.INDENT)); + assertEquals("order", order, metadata.getOrder()); + assertEquals("indentation", indent, metadata.getIndent()); } @Override @@ -301,13 +300,14 @@ public class GtasksTaskMovingTest extends InjectingTestCase { Task task = new Task(); task.setTitle(title); taskDao.save(task); - Metadata metadata = gtasksMetadata.createEmptyMetadata(task.getId()); - metadata.setValue(GtasksMetadata.LIST_ID, "1"); - if(order != VALUE_UNSET) - metadata.setValue(GtasksMetadata.ORDER, order); - if(indent != VALUE_UNSET) - metadata.setValue(GtasksMetadata.INDENT, indent); - metadataDao.persist(metadata); + GoogleTask metadata = new GoogleTask(task.getId(), "1"); + if(order != VALUE_UNSET) { + metadata.setOrder(order); + } + if(indent != VALUE_UNSET) { + metadata.setIndent(indent); + } + googleTaskDao.insert(metadata); return task; } } diff --git a/app/src/androidTestGoogleplay/java/org/tasks/injection/TestComponent.java b/app/src/androidTestGoogleplay/java/org/tasks/injection/TestComponent.java index dbfe95eae..642db7ed1 100644 --- a/app/src/androidTestGoogleplay/java/org/tasks/injection/TestComponent.java +++ b/app/src/androidTestGoogleplay/java/org/tasks/injection/TestComponent.java @@ -1,7 +1,6 @@ package org.tasks.injection; import com.todoroo.astrid.alarms.AlarmJobServiceTest; -import com.todoroo.astrid.dao.MetadataDaoTests; import com.todoroo.astrid.dao.TaskDaoTests; import com.todoroo.astrid.gtasks.GtasksIndentActionTest; import com.todoroo.astrid.gtasks.GtasksListServiceTest; @@ -42,8 +41,6 @@ public interface TestComponent { void inject(TaskDaoTests taskDaoTests); - void inject(MetadataDaoTests metadataDaoTests); - void inject(NewSyncTestCase newSyncTestCase); void inject(SubtasksTestCase subtasksTestCase); diff --git a/app/src/generic/java/org/tasks/location/GeofenceApi.java b/app/src/generic/java/org/tasks/location/GeofenceApi.java index d7a406d82..1c07156eb 100644 --- a/app/src/generic/java/org/tasks/location/GeofenceApi.java +++ b/app/src/generic/java/org/tasks/location/GeofenceApi.java @@ -1,5 +1,7 @@ package org.tasks.location; +import org.tasks.data.Location; + import java.util.List; import javax.inject.Inject; @@ -12,15 +14,15 @@ public class GeofenceApi { } - public void register(List activeGeofences) { + public void register(List activeGeofences) { } - public void cancel(Geofence geofence) { + public void cancel(Location geofence) { } - public void cancel(List geofences) { + public void cancel(List geofences) { } } diff --git a/app/src/generic/java/org/tasks/location/PlacePicker.java b/app/src/generic/java/org/tasks/location/PlacePicker.java index 187568317..0cc390a42 100644 --- a/app/src/generic/java/org/tasks/location/PlacePicker.java +++ b/app/src/generic/java/org/tasks/location/PlacePicker.java @@ -4,6 +4,7 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; +import org.tasks.data.Location; import org.tasks.preferences.Preferences; public class PlacePicker { @@ -11,7 +12,7 @@ public class PlacePicker { return null; } - public static Geofence getPlace(Context context, Intent data, Preferences preferences) { + public static Location getPlace(Context context, Intent data, Preferences preferences) { return null; } } diff --git a/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksListService.java b/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksListService.java index 7422771e6..a7b064745 100644 --- a/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksListService.java +++ b/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksListService.java @@ -7,12 +7,12 @@ package com.todoroo.astrid.gtasks; import com.google.api.services.tasks.model.TaskList; import com.todoroo.astrid.api.GtasksFilter; -import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.StoreObjectDao; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.service.TaskDeleter; import org.tasks.LocalBroadcastManager; +import org.tasks.data.GoogleTaskDao; import org.tasks.data.TaskListDataProvider; import java.util.HashSet; @@ -32,18 +32,18 @@ public class GtasksListService { private final StoreObjectDao storeObjectDao; private final TaskListDataProvider taskListDataProvider; private final TaskDeleter taskDeleter; - private final MetadataDao metadataDao; private LocalBroadcastManager localBroadcastManager; + private final GoogleTaskDao googleTaskDao; @Inject public GtasksListService(StoreObjectDao storeObjectDao, TaskListDataProvider taskListDataProvider, - TaskDeleter taskDeleter, MetadataDao metadataDao, - LocalBroadcastManager localBroadcastManager) { + TaskDeleter taskDeleter, LocalBroadcastManager localBroadcastManager, + GoogleTaskDao googleTaskDao) { this.storeObjectDao = storeObjectDao; this.taskListDataProvider = taskListDataProvider; this.taskDeleter = taskDeleter; - this.metadataDao = metadataDao; this.localBroadcastManager = localBroadcastManager; + this.googleTaskDao = googleTaskDao; } public List getLists() { @@ -104,10 +104,9 @@ public class GtasksListService { .constructCursor(new GtasksFilter(gtasksList), Task.PROPERTIES) .toList(); for (Task task : tasks) { - metadataDao.deleteWhere(MetadataDao.MetadataCriteria - .byTaskAndwithKey(task.getId(), GtasksMetadata.METADATA_KEY)); taskDeleter.delete(task); } + googleTaskDao.deleteList(gtasksList.getRemoteId()); storeObjectDao.delete(gtasksList.getId()); } diff --git a/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksPreferences.java b/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksPreferences.java index ac45c9389..a34c493fb 100644 --- a/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksPreferences.java +++ b/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksPreferences.java @@ -12,13 +12,12 @@ import android.preference.Preference; import android.support.annotation.NonNull; import com.todoroo.andlib.utility.DateUtilities; -import com.todoroo.astrid.dao.MetadataDao; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.gtasks.auth.GtasksLoginActivity; import org.tasks.R; import org.tasks.analytics.Tracker; import org.tasks.analytics.Tracking; +import org.tasks.data.GoogleTaskDao; import org.tasks.dialogs.DialogBuilder; import org.tasks.gtasks.GoogleTaskListSelectionHandler; import org.tasks.gtasks.PlayServicesAvailability; @@ -46,7 +45,7 @@ public class GtasksPreferences extends InjectingPreferenceActivity implements Go @Inject SyncAdapterHelper syncAdapterHelper; @Inject PlayServicesAvailability playServicesAvailability; @Inject DialogBuilder dialogBuilder; - @Inject MetadataDao metadataDao; + @Inject GoogleTaskDao googleTaskDao; @Override public void onCreate(Bundle savedInstanceState) { @@ -85,7 +84,7 @@ public class GtasksPreferences extends InjectingPreferenceActivity implements Go .setPositiveButton(android.R.string.ok, (dialog, which) -> { gtasksPreferenceService.clearLastSyncDate(); gtasksPreferenceService.setUserName(null); - metadataDao.deleteWhere(Metadata.KEY.eq(GtasksMetadata.METADATA_KEY)); + googleTaskDao.deleteAll(); syncAdapterHelper.enableSynchronization(false); tracker.reportEvent(Tracking.Events.GTASK_LOGOUT); gtaskPreference.setChecked(false); diff --git a/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksSubtaskListFragment.java b/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksSubtaskListFragment.java index 73b41521f..6a3492724 100644 --- a/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksSubtaskListFragment.java +++ b/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksSubtaskListFragment.java @@ -16,6 +16,7 @@ import com.todoroo.astrid.adapter.TaskAdapter; import com.todoroo.astrid.api.GtasksFilter; import com.todoroo.astrid.data.Task; +import org.tasks.data.GoogleTask; import org.tasks.injection.ForApplication; import org.tasks.injection.FragmentComponent; import org.tasks.tasklist.GtasksListFragment; @@ -56,8 +57,8 @@ public class GtasksSubtaskListFragment extends GtasksListFragment { public Property[] taskProperties() { Property[] baseProperties = TaskAdapter.PROPERTIES; ArrayList> properties = new ArrayList<>(Arrays.asList(baseProperties)); - properties.add(GtasksMetadata.INDENT); - properties.add(GtasksMetadata.ORDER); + properties.add(GoogleTask.INDENT); + properties.add(GoogleTask.ORDER); return properties.toArray(new Property[properties.size()]); } diff --git a/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksTaskListUpdater.java b/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksTaskListUpdater.java index 7147f5de5..25b0a007d 100644 --- a/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksTaskListUpdater.java +++ b/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksTaskListUpdater.java @@ -5,17 +5,13 @@ */ package com.todoroo.astrid.gtasks; -import com.todoroo.andlib.sql.Criterion; -import com.todoroo.andlib.sql.Functions; -import com.todoroo.andlib.sql.Order; -import com.todoroo.andlib.sql.Query; import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.GtasksFilter; -import com.todoroo.astrid.dao.MetadataDao; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.gtasks.sync.GtasksSyncService; +import org.tasks.data.GoogleTask; +import org.tasks.data.GoogleTaskDao; import org.tasks.injection.ApplicationScope; import java.util.ArrayList; @@ -41,12 +37,12 @@ public class GtasksTaskListUpdater { final HashMap siblings = new HashMap<>(); private final GtasksSyncService gtasksSyncService; - private final MetadataDao metadataDao; + private final GoogleTaskDao googleTaskDao; @Inject - public GtasksTaskListUpdater(GtasksSyncService gtasksSyncService, MetadataDao metadataDao) { + public GtasksTaskListUpdater(GtasksSyncService gtasksSyncService, GoogleTaskDao googleTaskDao) { this.gtasksSyncService = gtasksSyncService; - this.metadataDao = metadataDao; + this.googleTaskDao = googleTaskDao; } public void initialize(Filter filter) { @@ -56,14 +52,8 @@ public class GtasksTaskListUpdater { // --- overrides - Metadata getTaskMetadata(long taskId) { - return metadataDao.getFirstActiveByTaskAndKey(taskId, GtasksMetadata.METADATA_KEY); - } - - private Metadata createEmptyMetadata(GtasksList list, long taskId) { - Metadata metadata = GtasksMetadata.createEmptyMetadataWithoutList(taskId); - metadata.setValue(GtasksMetadata.LIST_ID, list.getRemoteId()); - return metadata; + GoogleTask getTaskMetadata(long taskId) { + return googleTaskDao.getByTaskId(taskId); } private void iterateThroughList(GtasksList list, OrderedListIterator iterator) { @@ -71,8 +61,8 @@ public class GtasksTaskListUpdater { gtasksSyncService.iterateThroughList(listId, iterator, 0, false); } - private void onMovedOrIndented(Metadata metadata) { - gtasksSyncService.triggerMoveForMetadata(metadata); + private void onMovedOrIndented(GoogleTask googleTask) { + gtasksSyncService.triggerMoveForMetadata(googleTask); } // --- used during synchronization @@ -83,16 +73,11 @@ public class GtasksTaskListUpdater { } private void orderAndIndentHelper(final String listId, final AtomicLong order, final long parent, final int indentLevel, final Set alreadyChecked) { - Query query = Query.select(Metadata.PROPERTIES).where(Criterion.and( - Metadata.KEY.eq(GtasksMetadata.METADATA_KEY), - GtasksMetadata.LIST_ID.eq(listId), - GtasksMetadata.PARENT_TASK.eq(parent))) - .orderBy(Order.asc(Functions.cast(GtasksMetadata.GTASKS_ORDER, "INTEGER"))); - for (Metadata curr : metadataDao.toList(query)) { + for (GoogleTask curr : googleTaskDao.byRemoteOrder(listId, parent)) { if (!alreadyChecked.contains(curr.getTask())) { - curr.setValue(GtasksMetadata.INDENT, indentLevel); - curr.setValue(GtasksMetadata.ORDER, order.getAndIncrement()); - metadataDao.saveExisting(curr); + curr.setIndent(indentLevel); + curr.setOrder(order.getAndIncrement()); + googleTaskDao.update(curr); alreadyChecked.add(curr.getTask()); orderAndIndentHelper(listId, order, curr.getTask(), indentLevel + 1, alreadyChecked); @@ -105,7 +90,7 @@ public class GtasksTaskListUpdater { final AtomicInteger previousIndent = new AtomicInteger(-1); iterateThroughList(list, (taskId, metadata) -> { - int indent = metadata.getValue(GtasksMetadata.INDENT); + int indent = metadata.getIndent(); try { long parent, sibling; @@ -139,7 +124,7 @@ public class GtasksTaskListUpdater { } public interface OrderedListIterator { - void processTask(long taskId, Metadata metadata); + void processTask(long taskId, GoogleTask googleTask); } /** @@ -157,49 +142,40 @@ public class GtasksTaskListUpdater { final AtomicLong previousTask = new AtomicLong(Task.NO_ID); final AtomicLong globalOrder = new AtomicLong(-1); - iterateThroughList(list, (taskId, metadata) -> { - if(!metadata.isSaved()) { - metadata = createEmptyMetadata(list, taskId); - } - int indent = metadata.containsNonNullValue(GtasksMetadata.INDENT) ? - metadata.getValue(GtasksMetadata.INDENT) : 0; + iterateThroughList(list, (taskId, googleTask) -> { + int indent = googleTask.getIndent(); long order = globalOrder.incrementAndGet(); - metadata.setValue(GtasksMetadata.ORDER, order); + googleTask.setOrder(order); if(targetTaskId == taskId) { // if indenting is warranted, indent me and my children if(indent + delta <= previousIndent.get() + 1 && indent + delta >= 0) { targetTaskIndent.set(indent); - metadata.setValue(GtasksMetadata.INDENT, indent + delta); - - if(GtasksMetadata.PARENT_TASK != null) { - long newParent = computeNewParent(list, - taskId, indent + delta - 1); - if (newParent == taskId) { - metadata.setValue(GtasksMetadata.PARENT_TASK, Task.NO_ID); - } else { - metadata.setValue(GtasksMetadata.PARENT_TASK, newParent); - } + googleTask.setIndent(indent + delta); + + long newParent = computeNewParent(list, taskId, indent + delta - 1); + if (newParent == taskId) { + googleTask.setParent(Task.NO_ID); + } else { + googleTask.setParent(newParent); } - saveAndUpdateModifiedDate(metadata); + saveAndUpdateModifiedDate(googleTask); } } else if(targetTaskIndent.get() > -1) { // found first task that is not beneath target if(indent <= targetTaskIndent.get()) { targetTaskIndent.set(-1); } else { - metadata.setValue(GtasksMetadata.INDENT, indent + delta); - saveAndUpdateModifiedDate(metadata); + googleTask.setIndent(indent + delta); + saveAndUpdateModifiedDate(googleTask); } } else { previousIndent.set(indent); previousTask.set(taskId); } - if(!metadata.isSaved()) { - saveAndUpdateModifiedDate(metadata); - } + saveAndUpdateModifiedDate(googleTask); }); onMovedOrIndented(getTaskMetadata(targetTaskId)); } @@ -214,12 +190,12 @@ public class GtasksTaskListUpdater { final AtomicLong lastPotentialParent = new AtomicLong(Task.NO_ID); final AtomicBoolean computedParent = new AtomicBoolean(false); - iterateThroughList(list, (taskId, metadata) -> { + iterateThroughList(list, (taskId, googleTask) -> { if (targetTask.get() == taskId) { computedParent.set(true); } - int indent = metadata.getValue(GtasksMetadata.INDENT); + int indent = googleTask.getIndent(); if (!computedParent.get() && indent == desiredParentIndent.get()) { lastPotentialParent.set(taskId); } @@ -295,21 +271,20 @@ public class GtasksTaskListUpdater { private void traverseTreeAndWriteValues(GtasksList list, Node node, AtomicLong order, int indent) { if(node.taskId != Task.NO_ID) { - Metadata metadata = getTaskMetadata(node.taskId); - if(metadata == null) { - metadata = createEmptyMetadata(list, node.taskId); + GoogleTask googleTask = getTaskMetadata(node.taskId); + if(googleTask == null) { + googleTask = new GoogleTask(node.taskId, list.getRemoteId()); } - metadata.setValue(GtasksMetadata.ORDER, order.getAndIncrement()); - metadata.setValue(GtasksMetadata.INDENT, indent); + googleTask.setOrder(order.getAndIncrement()); + googleTask.setIndent(indent); boolean parentChanged = false; - if(GtasksMetadata.PARENT_TASK != null && metadata.getValue(GtasksMetadata.PARENT_TASK) != - node.parent.taskId) { + if(googleTask.getParent() != node.parent.taskId) { parentChanged = true; - metadata.setValue(GtasksMetadata.PARENT_TASK, node.parent.taskId); + googleTask.setParent(node.parent.taskId); } - saveAndUpdateModifiedDate(metadata); + saveAndUpdateModifiedDate(googleTask); if(parentChanged) { - onMovedOrIndented(metadata); + onMovedOrIndented(googleTask); } } @@ -336,8 +311,8 @@ public class GtasksTaskListUpdater { final AtomicInteger previoustIndent = new AtomicInteger(-1); final AtomicReference currentNode = new AtomicReference<>(root); - iterateThroughList(list, (taskId, metadata) -> { - int indent = metadata.getValue(GtasksMetadata.INDENT); + iterateThroughList(list, (taskId, googleTask) -> { + int indent = googleTask.getIndent(); int previousIndentValue = previoustIndent.get(); if(indent == previousIndentValue) { // sibling @@ -366,11 +341,8 @@ public class GtasksTaskListUpdater { return root; } - private void saveAndUpdateModifiedDate(Metadata metadata) { - if(metadata.getSetValues().size() == 0) { - return; - } - metadataDao.persist(metadata); + private void saveAndUpdateModifiedDate(GoogleTask googleTask) { + googleTaskDao.update(googleTask); } // --- task cascading operations diff --git a/app/src/googleplay/java/com/todoroo/astrid/gtasks/OrderedMetadataListFragmentHelper.java b/app/src/googleplay/java/com/todoroo/astrid/gtasks/OrderedMetadataListFragmentHelper.java index 84701c894..22e1b5c87 100644 --- a/app/src/googleplay/java/com/todoroo/astrid/gtasks/OrderedMetadataListFragmentHelper.java +++ b/app/src/googleplay/java/com/todoroo/astrid/gtasks/OrderedMetadataListFragmentHelper.java @@ -14,11 +14,12 @@ import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.astrid.activity.TaskListFragment; import com.todoroo.astrid.adapter.TaskAdapter; import com.todoroo.astrid.api.Filter; -import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.TaskDao; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.Task; +import org.tasks.data.GoogleTask; +import org.tasks.data.GoogleTaskDao; + import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -31,19 +32,19 @@ import timber.log.Timber; class OrderedMetadataListFragmentHelper { private final GtasksTaskListUpdater updater; + private final GoogleTaskDao googleTaskDao; private final TaskDao taskDao; - private final MetadataDao metadataDao; private DraggableTaskAdapter taskAdapter; private TaskListFragment fragment; private GtasksList list; @Inject - OrderedMetadataListFragmentHelper(TaskDao taskDao, MetadataDao metadataDao, GtasksTaskListUpdater updater) { + OrderedMetadataListFragmentHelper(TaskDao taskDao, GtasksTaskListUpdater updater, GoogleTaskDao googleTaskDao) { this.taskDao = taskDao; - this.metadataDao = metadataDao; this.updater = updater; + this.googleTaskDao = googleTaskDao; } void setTaskListFragment(TaskListFragment fragment) { @@ -70,13 +71,13 @@ class OrderedMetadataListFragmentHelper { @Override public int getIndent(Task task) { - return task.getValue(GtasksMetadata.INDENT); + return task.getValue(GoogleTask.INDENT); } @Override public boolean canIndent(int position, Task task) { Task parent = taskAdapter.getTask(position - 1); - return parent != null && getIndent(task) <= parent.getValue(GtasksMetadata.INDENT); + return parent != null && getIndent(task) <= parent.getValue(GoogleTask.INDENT); } @Override @@ -144,13 +145,13 @@ class OrderedMetadataListFragmentHelper { } final ArrayList chained = new ArrayList<>(); - final int parentIndent = item.getValue(GtasksMetadata.INDENT); + final int parentIndent = item.getValue(GoogleTask.INDENT); updater.applyToChildren(list, itemId, node -> { Task childTask = taskDao.fetch(node.taskId); if(!TextUtils.isEmpty(childTask.getRecurrence())) { - Metadata metadata = updater.getTaskMetadata(node.taskId); - metadata.setValue(GtasksMetadata.INDENT, parentIndent); - metadataDao.persist(metadata); + GoogleTask googleTask = updater.getTaskMetadata(node.taskId); + googleTask.setIndent(parentIndent); + googleTaskDao.update(googleTask); } model.setId(node.taskId); diff --git a/app/src/googleplay/java/com/todoroo/astrid/gtasks/sync/GtasksSyncService.java b/app/src/googleplay/java/com/todoroo/astrid/gtasks/sync/GtasksSyncService.java index 92256e136..1cc50bde4 100644 --- a/app/src/googleplay/java/com/todoroo/astrid/gtasks/sync/GtasksSyncService.java +++ b/app/src/googleplay/java/com/todoroo/astrid/gtasks/sync/GtasksSyncService.java @@ -8,28 +8,22 @@ package com.todoroo.astrid.gtasks.sync; import android.text.TextUtils; import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException; -import com.todoroo.andlib.sql.Criterion; -import com.todoroo.andlib.sql.Field; -import com.todoroo.andlib.sql.Functions; -import com.todoroo.andlib.sql.Order; -import com.todoroo.andlib.sql.Query; import com.todoroo.andlib.utility.AndroidUtilities; -import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.TaskDao; -import com.todoroo.astrid.data.Metadata; -import com.todoroo.astrid.data.SyncFlags; import com.todoroo.astrid.data.Task; -import com.todoroo.astrid.gtasks.GtasksMetadata; import com.todoroo.astrid.gtasks.GtasksPreferenceService; import com.todoroo.astrid.gtasks.GtasksTaskListUpdater; import com.todoroo.astrid.gtasks.api.GtasksInvoker; import com.todoroo.astrid.gtasks.api.MoveRequest; import org.tasks.analytics.Tracker; +import org.tasks.data.GoogleTask; +import org.tasks.data.GoogleTaskDao; import org.tasks.gtasks.SyncAdapterHelper; import org.tasks.injection.ApplicationScope; import java.io.IOException; +import java.util.List; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; @@ -42,25 +36,26 @@ import timber.log.Timber; @ApplicationScope public class GtasksSyncService { - private final MetadataDao metadataDao; private final TaskDao taskDao; private final GtasksPreferenceService gtasksPreferenceService; private final GtasksInvoker gtasksInvoker; private final LinkedBlockingQueue operationQueue = new LinkedBlockingQueue<>(); private final SyncAdapterHelper syncAdapterHelper; private final Tracker tracker; + private final GoogleTaskDao googleTaskDao; @Inject - public GtasksSyncService(MetadataDao metadataDao, TaskDao taskDao, + public GtasksSyncService(TaskDao taskDao, GtasksPreferenceService gtasksPreferenceService, GtasksInvoker gtasksInvoker, - SyncAdapterHelper syncAdapterHelper, Tracker tracker) { - this.metadataDao = metadataDao; + SyncAdapterHelper syncAdapterHelper, Tracker tracker, + GoogleTaskDao googleTaskDao) { this.taskDao = taskDao; this.gtasksPreferenceService = gtasksPreferenceService; this.gtasksInvoker = gtasksInvoker; this.syncAdapterHelper = syncAdapterHelper; this.tracker = tracker; + this.googleTaskDao = googleTaskDao; new OperationPushThread(operationQueue).start(); } @@ -69,15 +64,15 @@ public class GtasksSyncService { } private class MoveOp implements SyncOnSaveOperation { - final Metadata metadata; + final GoogleTask googleTask; - public MoveOp(Metadata metadata) { - this.metadata = metadata; + public MoveOp(GoogleTask googleTask) { + this.googleTask = googleTask; } @Override public void op(GtasksInvoker invoker) throws IOException { - pushMetadataOnSave(metadata, invoker); + pushMetadataOnSave(googleTask, invoker); } } @@ -127,15 +122,12 @@ public class GtasksSyncService { operationQueue.offer(new ClearOp(listId)); } - public void triggerMoveForMetadata(final Metadata metadata) { - if (metadata == null) { + public void triggerMoveForMetadata(final GoogleTask googleTask) { + if (googleTask == null) { return; } - if (metadata.checkAndClearTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC)) { - return; - } - if (!metadata.getKey().equals(GtasksMetadata.METADATA_KEY)) //Don't care about non-gtasks metadata - { + if (googleTask.isSuppressSync()) { + googleTask.setSuppressSync(false); return; } if (gtasksPreferenceService.isOngoing()) //Don't try and sync changes that occur during a normal sync @@ -146,61 +138,47 @@ public class GtasksSyncService { return; } - operationQueue.offer(new MoveOp(metadata)); + operationQueue.offer(new MoveOp(googleTask)); } - private void pushMetadataOnSave(Metadata model, GtasksInvoker invoker) throws IOException { + private void pushMetadataOnSave(GoogleTask model, GtasksInvoker invoker) throws IOException { AndroidUtilities.sleepDeep(1000L); - String taskId = model.getValue(GtasksMetadata.ID); - String listId = model.getValue(GtasksMetadata.LIST_ID); + String taskId = model.getRemoteId(); + String listId = model.getListId(); String parent = getRemoteParentId(model); String priorSibling = getRemoteSiblingId(listId, model); MoveRequest move = new MoveRequest(invoker, taskId, listId, parent, priorSibling); com.google.api.services.tasks.model.Task result = move.push(); - // Update order metadata from result + // Update order googleTask from result if (result != null) { - model.setValue(GtasksMetadata.GTASKS_ORDER, Long.parseLong(result.getPosition())); - model.putTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC, true); - metadataDao.saveExisting(model); + model.setRemoteOrder(Long.parseLong(result.getPosition())); + model.setSuppressSync(true); + googleTaskDao.update(model); } } public void iterateThroughList(String listId, final GtasksTaskListUpdater.OrderedListIterator iterator, long startAtOrder, boolean reverse) { - Field orderField = Functions.cast(GtasksMetadata.ORDER, "LONG"); - Order order = reverse ? Order.desc(orderField) : Order.asc(orderField); - Criterion startAtCriterion = reverse ? Functions.cast(GtasksMetadata.ORDER, "LONG").lt(startAtOrder) : - Functions.cast(GtasksMetadata.ORDER, "LONG").gt(startAtOrder - 1); - - Query query = Query.select(Metadata.PROPERTIES).where(Criterion.and( - MetadataDao.MetadataCriteria.withKey(GtasksMetadata.METADATA_KEY), - GtasksMetadata.LIST_ID.eq(listId), - startAtCriterion)). - orderBy(order); - - for (Metadata entry : metadataDao.toList(query)) { - long taskId = entry.getValue(Metadata.TASK); - Metadata metadata = metadataDao.getFirstActiveByTaskAndKey(taskId, GtasksMetadata.METADATA_KEY); - if(metadata != null) { - iterator.processTask(taskId, metadata); - } + List tasks = reverse + ? googleTaskDao.getTasksFromReverse(listId, startAtOrder) + : googleTaskDao.getTasksFrom(listId, startAtOrder); + for (GoogleTask entry : tasks) { + iterator.processTask(entry.getTask(), entry); } } /** * Gets the remote id string of the parent task */ - public String getRemoteParentId(Metadata gtasksMetadata) { + public String getRemoteParentId(GoogleTask googleTask) { String parent = null; - if (gtasksMetadata.containsNonNullValue(GtasksMetadata.PARENT_TASK)) { - long parentId = gtasksMetadata.getValue(GtasksMetadata.PARENT_TASK); - Metadata parentMetadata = metadataDao.getFirstActiveByTaskAndKey(parentId, GtasksMetadata.METADATA_KEY); - if (parentMetadata != null && parentMetadata.containsNonNullValue(GtasksMetadata.ID)) { - parent = parentMetadata.getValue(GtasksMetadata.ID); - if (TextUtils.isEmpty(parent)) { - parent = null; - } + long parentId = googleTask.getParent(); + GoogleTask parentTask = googleTaskDao.getByTaskId(parentId); + if (parentTask != null) { + parent = parentTask.getRemoteId(); + if (TextUtils.isEmpty(parent)) { + parent = null; } } return parent; @@ -209,26 +187,26 @@ public class GtasksSyncService { /** * Gets the remote id string of the previous sibling task */ - public String getRemoteSiblingId(String listId, Metadata gtasksMetadata) { - final AtomicInteger indentToMatch = new AtomicInteger(gtasksMetadata.getValue(GtasksMetadata.INDENT)); - final AtomicLong parentToMatch = new AtomicLong(gtasksMetadata.getValue(GtasksMetadata.PARENT_TASK)); + public String getRemoteSiblingId(String listId, GoogleTask gtasksMetadata) { + final AtomicInteger indentToMatch = new AtomicInteger(gtasksMetadata.getIndent()); + final AtomicLong parentToMatch = new AtomicLong(gtasksMetadata.getParent()); final AtomicReference sibling = new AtomicReference<>(); - GtasksTaskListUpdater.OrderedListIterator iterator = (taskId, metadata) -> { + GtasksTaskListUpdater.OrderedListIterator iterator = (taskId, googleTask) -> { Task t = taskDao.fetch(taskId); if (t == null || t.isDeleted()) { return; } - int currIndent = metadata.getValue(GtasksMetadata.INDENT); - long currParent = metadata.getValue(GtasksMetadata.PARENT_TASK); + int currIndent = googleTask.getIndent(); + long currParent = googleTask.getParent(); if (currIndent == indentToMatch.get() && currParent == parentToMatch.get()) { if (sibling.get() == null) { - sibling.set(metadata.getValue(GtasksMetadata.ID)); + sibling.set(googleTask.getRemoteId()); } } }; - iterateThroughList(listId, iterator, gtasksMetadata.getValue(GtasksMetadata.ORDER), true); + iterateThroughList(listId, iterator, gtasksMetadata.getOrder(), true); return sibling.get(); } } diff --git a/app/src/googleplay/java/com/todoroo/astrid/gtasks/sync/GtasksTaskContainer.java b/app/src/googleplay/java/com/todoroo/astrid/gtasks/sync/GtasksTaskContainer.java index 2027e51a1..cbda4e439 100644 --- a/app/src/googleplay/java/com/todoroo/astrid/gtasks/sync/GtasksTaskContainer.java +++ b/app/src/googleplay/java/com/todoroo/astrid/gtasks/sync/GtasksTaskContainer.java @@ -7,22 +7,22 @@ package com.todoroo.astrid.gtasks.sync; import com.google.api.client.util.DateTime; import com.todoroo.andlib.utility.DateUtilities; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.Task; -import com.todoroo.astrid.gtasks.GtasksMetadata; import com.todoroo.astrid.gtasks.api.GtasksApiUtilities; +import org.tasks.data.GoogleTask; + import java.util.ArrayList; public class GtasksTaskContainer { public final Task task; - public final ArrayList metadata; + public final ArrayList metadata; - public Metadata gtaskMetadata; + public GoogleTask gtaskMetadata; private final long updateTime; - public GtasksTaskContainer(com.google.api.services.tasks.model.Task remoteTask, String listId, Metadata metadata) { + public GtasksTaskContainer(com.google.api.services.tasks.model.Task remoteTask, String listId, GoogleTask metadata) { this.task = new Task(); this.metadata = new ArrayList<>(); this.gtaskMetadata = metadata; @@ -44,8 +44,8 @@ public class GtasksTaskContainer { task.setDueDate(createdDate); task.setNotes(remoteTask.getNotes()); - gtaskMetadata.setValue(GtasksMetadata.ID, remoteTask.getId()); - gtaskMetadata.setValue(GtasksMetadata.LIST_ID, listId); + gtaskMetadata.setRemoteId(remoteTask.getId()); + gtaskMetadata.setListId(listId); DateTime updated = remoteTask.getUpdated(); updateTime = updated == null ? 0 : updated.getValue(); diff --git a/app/src/googleplay/java/org/tasks/gtasks/GoogleTaskSyncAdapter.java b/app/src/googleplay/java/org/tasks/gtasks/GoogleTaskSyncAdapter.java index 916d9d032..91d7dd4c6 100644 --- a/app/src/googleplay/java/org/tasks/gtasks/GoogleTaskSyncAdapter.java +++ b/app/src/googleplay/java/org/tasks/gtasks/GoogleTaskSyncAdapter.java @@ -31,20 +31,19 @@ import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecovera import com.google.api.services.tasks.model.TaskList; import com.google.api.services.tasks.model.TaskLists; import com.google.api.services.tasks.model.Tasks; +import com.google.common.base.Strings; import com.todoroo.andlib.data.AbstractModel; import com.todoroo.andlib.sql.Criterion; +import com.todoroo.andlib.sql.Field; import com.todoroo.andlib.sql.Join; import com.todoroo.andlib.sql.Query; import com.todoroo.andlib.utility.DateUtilities; -import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.StoreObjectDao; import com.todoroo.astrid.dao.TaskDao; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.SyncFlags; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.gtasks.GtasksList; import com.todoroo.astrid.gtasks.GtasksListService; -import com.todoroo.astrid.gtasks.GtasksMetadata; import com.todoroo.astrid.gtasks.GtasksPreferenceService; import com.todoroo.astrid.gtasks.GtasksTaskListUpdater; import com.todoroo.astrid.gtasks.api.GtasksApiUtilities; @@ -57,6 +56,8 @@ import com.todoroo.astrid.utility.Constants; import org.tasks.LocalBroadcastManager; import org.tasks.R; import org.tasks.analytics.Tracker; +import org.tasks.data.GoogleTask; +import org.tasks.data.GoogleTaskDao; import org.tasks.injection.InjectingAbstractThreadedSyncAdapter; import org.tasks.injection.SyncAdapterComponent; import org.tasks.notifications.NotificationManager; @@ -66,9 +67,7 @@ import org.tasks.time.DateTime; import java.io.IOException; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; import javax.inject.Inject; @@ -98,10 +97,9 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter @Inject Preferences preferences; @Inject GtasksInvoker gtasksInvoker; @Inject TaskDao taskDao; - @Inject MetadataDao metadataDao; - @Inject GtasksMetadata gtasksMetadataFactory; @Inject Tracker tracker; @Inject NotificationManager notificationManager; + @Inject GoogleTaskDao googleTaskDao; public GoogleTaskSyncAdapter(Context context, boolean autoInitialize) { super(context, autoInitialize); @@ -190,8 +188,11 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter private void pushLocalChanges() throws UserRecoverableAuthIOException { List tasks = taskDao.toList(Query.select(Task.PROPERTIES) - .join(Join.left(Metadata.TABLE, Criterion.and(MetadataDao.MetadataCriteria.withKey(GtasksMetadata.METADATA_KEY), Task.ID.eq(Metadata.TASK)))) - .where(Criterion.or(Task.MODIFICATION_DATE.gt(GtasksMetadata.LAST_SYNC), GtasksMetadata.ID.eq(""), Metadata.ID.isNull()))); + .join(Join.left(GoogleTask.TABLE.as("gt"), Task.ID.eq(Field.field("gt.task")))) + .where(Criterion.or( + Task.MODIFICATION_DATE.gt(Field.field("gt.last_sync")), + Field.field("gt.remote_id").eq(""), + Field.field("gt.remote_id").isNull()))); for (Task task : tasks) { try { pushTask(task, task.getMergedValues(), gtasksInvoker); @@ -207,12 +208,12 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter * Synchronize with server when data changes */ private void pushTask(Task task, ContentValues values, GtasksInvoker invoker) throws IOException { - for (Metadata deleted : getDeleted(task.getId())) { - gtasksInvoker.deleteGtask(deleted.getValue(GtasksMetadata.LIST_ID), deleted.getValue(GtasksMetadata.ID)); - metadataDao.delete(deleted.getId()); + for (GoogleTask deleted : googleTaskDao.getDeletedByTaskId(task.getId())) { + gtasksInvoker.deleteGtask(deleted.getListId(), deleted.getRemoteId()); + googleTaskDao.delete(deleted); } - Metadata gtasksMetadata = metadataDao.getFirstActiveByTaskAndKey(task.getId(), GtasksMetadata.METADATA_KEY); + GoogleTask gtasksMetadata = googleTaskDao.getByTaskId(task.getId()); com.google.api.services.tasks.model.Task remoteModel; boolean newlyCreated = false; @@ -228,20 +229,16 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter } } - if (gtasksMetadata == null || !gtasksMetadata.containsNonNullValue(GtasksMetadata.ID) || - TextUtils.isEmpty(gtasksMetadata.getValue(GtasksMetadata.ID))) { //Create case + if (gtasksMetadata == null || Strings.isNullOrEmpty(gtasksMetadata.getRemoteId())) { //Create case if (gtasksMetadata == null) { - gtasksMetadata = gtasksMetadataFactory.createEmptyMetadata(task.getId()); + gtasksMetadata = new GoogleTask(task.getId(), listId); } - if (gtasksMetadata.containsNonNullValue(GtasksMetadata.LIST_ID)) { - listId = gtasksMetadata.getValue(GtasksMetadata.LIST_ID); - } - + listId = gtasksMetadata.getListId(); remoteModel = new com.google.api.services.tasks.model.Task(); newlyCreated = true; } else { //update case - remoteId = gtasksMetadata.getValue(GtasksMetadata.ID); - listId = gtasksMetadata.getValue(GtasksMetadata.LIST_ID); + remoteId = gtasksMetadata.getRemoteId(); + listId = gtasksMetadata.getListId(); remoteModel = new com.google.api.services.tasks.model.Task(); remoteModel.setId(remoteId); } @@ -283,7 +280,7 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter invoker.updateGtask(listId, remoteModel); } catch(HttpNotFoundException e) { Timber.e(e, e.getMessage()); - metadataDao.delete(gtasksMetadata.getId()); + googleTaskDao.delete(gtasksMetadata); return; } } else { @@ -294,26 +291,20 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter if (created != null) { //Update the metadata for the newly created task - gtasksMetadata.setValue(GtasksMetadata.ID, created.getId()); - gtasksMetadata.setValue(GtasksMetadata.LIST_ID, listId); + gtasksMetadata.setRemoteId(created.getId()); + gtasksMetadata.setListId(listId); } else { return; } } task.setModificationDate(DateUtilities.now()); - gtasksMetadata.setValue(GtasksMetadata.LAST_SYNC, DateUtilities.now() + 1000L); - metadataDao.persist(gtasksMetadata); + gtasksMetadata.setLastSync(DateUtilities.now() + 1000L); + googleTaskDao.update(gtasksMetadata); task.putTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC, true); taskDao.saveExistingWithSqlConstraintCheck(task); } - private List getDeleted(long taskId) { - return metadataDao.toList(Criterion.and( - MetadataDao.MetadataCriteria.byTaskAndwithKey(taskId, GtasksMetadata.METADATA_KEY), - MetadataDao.MetadataCriteria.isDeleted())); - } - private synchronized void fetchAndApplyRemoteChanges(GtasksList list) throws UserRecoverableAuthIOException { String listId = list.getRemoteId(); long lastSyncDate = list.getLastSync(); @@ -337,11 +328,11 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter if (!tasks.isEmpty()) { for (com.google.api.services.tasks.model.Task t : tasks) { - GtasksTaskContainer container = new GtasksTaskContainer(t, listId, GtasksMetadata.createEmptyMetadataWithoutList(AbstractModel.NO_ID)); + GtasksTaskContainer container = new GtasksTaskContainer(t, listId, new GoogleTask(0, "")); findLocalMatch(container); - container.gtaskMetadata.setValue(GtasksMetadata.GTASKS_ORDER, Long.parseLong(t.getPosition())); - container.gtaskMetadata.setValue(GtasksMetadata.PARENT_TASK, localIdForGtasksId(t.getParent())); - container.gtaskMetadata.setValue(GtasksMetadata.LAST_SYNC, DateUtilities.now() + 1000L); + container.gtaskMetadata.setRemoteOrder(Long.parseLong(t.getPosition())); + container.gtaskMetadata.setParent(localIdForGtasksId(t.getParent())); + container.gtaskMetadata.setLastSync(DateUtilities.now() + 1000L); write(container); lastSyncDate = Math.max(lastSyncDate, container.getUpdateTime()); } @@ -357,7 +348,7 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter } private long localIdForGtasksId(String gtasksId) { - Metadata metadata = getMetadataByGtaskId(gtasksId); + GoogleTask metadata = getMetadataByGtaskId(gtasksId); return metadata == null ? AbstractModel.NO_ID : metadata.getTask(); } @@ -365,18 +356,16 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter if(remoteTask.task.getId() != Task.NO_ID) { return; } - Metadata metadata = getMetadataByGtaskId(remoteTask.gtaskMetadata.getValue(GtasksMetadata.ID)); - if (metadata != null) { - remoteTask.task.setId(metadata.getValue(Metadata.TASK)); + GoogleTask googleTask = getMetadataByGtaskId(remoteTask.gtaskMetadata.getRemoteId()); + if (googleTask != null) { + remoteTask.task.setId(googleTask.getTask()); remoteTask.task.setUuid(taskDao.uuidFromLocalId(remoteTask.task.getId())); - remoteTask.gtaskMetadata = metadata; + remoteTask.gtaskMetadata = googleTask; } } - private Metadata getMetadataByGtaskId(String gtaskId) { - return metadataDao.getFirst(Query.select(Metadata.PROPERTIES).where(Criterion.and( - Metadata.KEY.eq(GtasksMetadata.METADATA_KEY), - GtasksMetadata.ID.eq(gtaskId)))); + private GoogleTask getMetadataByGtaskId(String gtaskId) { + return googleTaskDao.getByRemoteId(gtaskId); } private void write(GtasksTaskContainer task) { @@ -408,7 +397,7 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter private void saveTaskAndMetadata(GtasksTaskContainer task) { task.prepareForSaving(); taskDao.save(task.task); - synchronizeMetadata(task.task.getId(), task.metadata, GtasksMetadata.METADATA_KEY); + synchronizeMetadata(task.task.getId(), task.metadata); } /** @@ -418,35 +407,30 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter * * @param taskId id of task to perform synchronization on * @param metadata list of new metadata items to save - * @param metadataKey metadata key */ - private void synchronizeMetadata(long taskId, ArrayList metadata, String metadataKey) { - final Set newMetadataValues = new HashSet<>(); - for(Metadata metadatum : metadata) { + private void synchronizeMetadata(long taskId, ArrayList metadata) { + for(GoogleTask metadatum : metadata) { metadatum.setTask(taskId); - metadatum.clearValue(Metadata.ID); - newMetadataValues.add(metadatum.getMergedValues()); + metadatum.setId(0); } - for (Metadata item : metadataDao.byTaskAndKey(taskId, metadataKey)) { + for (GoogleTask item : googleTaskDao.getAllByTaskId(taskId)) { long id = item.getId(); // clear item id when matching with incoming values - item.clearValue(Metadata.ID); - ContentValues itemMergedValues = item.getMergedValues(); - if(newMetadataValues.contains(itemMergedValues)) { - newMetadataValues.remove(itemMergedValues); + item.setId(0); + if(metadata.contains(item)) { + metadata.remove(item); } else { // not matched. cut it - metadataDao.delete(id); + item.setId(id); + googleTaskDao.delete(item); } } // everything that remains shall be written - for(ContentValues values : newMetadataValues) { - Metadata item = new Metadata(); - item.mergeWith(values); - metadataDao.persist(item); + for(GoogleTask values : metadata) { + googleTaskDao.insert(values); } } diff --git a/app/src/googleplay/java/org/tasks/ui/GoogleTaskListFragment.java b/app/src/googleplay/java/org/tasks/ui/GoogleTaskListFragment.java index 2aca815c6..8e79e0024 100644 --- a/app/src/googleplay/java/org/tasks/ui/GoogleTaskListFragment.java +++ b/app/src/googleplay/java/org/tasks/ui/GoogleTaskListFragment.java @@ -7,20 +7,18 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import com.todoroo.astrid.dao.MetadataDao; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.StoreObject; import com.todoroo.astrid.data.SyncFlags; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.gtasks.GtasksList; import com.todoroo.astrid.gtasks.GtasksListService; -import com.todoroo.astrid.gtasks.GtasksMetadata; import com.todoroo.astrid.gtasks.GtasksPreferenceService; import org.tasks.R; -import org.tasks.activities.SupportGoogleTaskListPicker; import org.tasks.analytics.Tracker; import org.tasks.analytics.Tracking; +import org.tasks.data.GoogleTask; +import org.tasks.data.GoogleTaskDao; import org.tasks.injection.FragmentComponent; import javax.inject.Inject; @@ -44,7 +42,7 @@ public class GoogleTaskListFragment extends TaskEditControlFragment { @Inject GtasksPreferenceService gtasksPreferenceService; @Inject GtasksListService gtasksListService; - @Inject MetadataDao metadataDao; + @Inject GoogleTaskDao googleTaskDao; @Inject Tracker tracker; private long taskId; @@ -67,9 +65,9 @@ public class GoogleTaskListFragment extends TaskEditControlFragment { selectedList = new GtasksList(selectedStoreObject); } } else { - Metadata metadata = metadataDao.getFirstActiveByTaskAndKey(taskId, GtasksMetadata.METADATA_KEY); - if (metadata != null) { - originalList = gtasksListService.getList(metadata.getValue(GtasksMetadata.LIST_ID)); + GoogleTask googleTask = googleTaskDao.getByTaskId(taskId); + if (googleTask != null) { + originalList = gtasksListService.getList(googleTask.getListId()); } if (originalList == null) { originalList = gtasksListService.getList(gtasksPreferenceService.getDefaultList()); @@ -126,18 +124,16 @@ public class GoogleTaskListFragment extends TaskEditControlFragment { return; } - Metadata taskMetadata = metadataDao.getFirstActiveByTaskAndKey(task.getId(), GtasksMetadata.METADATA_KEY); - if (taskMetadata == null) { - taskMetadata = GtasksMetadata.createEmptyMetadataWithoutList(task.getId()); - } else if (!taskMetadata.getValue(GtasksMetadata.LIST_ID).equals(selectedList.getRemoteId())) { + GoogleTask googleTask = googleTaskDao.getByTaskId(task.getId()); + if (googleTask == null) { + googleTaskDao.insert(new GoogleTask(task.getId(), selectedList.getRemoteId())); + } else if (!googleTask.getListId().equals(selectedList.getRemoteId())) { tracker.reportEvent(Tracking.Events.GTASK_MOVE); task.putTransitory(SyncFlags.FORCE_SYNC, true); - taskMetadata.setDeletionDate(now()); - metadataDao.persist(taskMetadata); - taskMetadata = GtasksMetadata.createEmptyMetadataWithoutList(task.getId()); + googleTask.setDeleted(now()); + googleTaskDao.update(googleTask); + googleTaskDao.insert(new GoogleTask(task.getId(), selectedList.getRemoteId())); } - taskMetadata.setValue(GtasksMetadata.LIST_ID, selectedList.getRemoteId()); - metadataDao.persist(taskMetadata); } @Override 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 a0111a817..135b957e8 100644 --- a/app/src/main/java/com/todoroo/astrid/api/GtasksFilter.java +++ b/app/src/main/java/com/todoroo/astrid/api/GtasksFilter.java @@ -1,28 +1,22 @@ package com.todoroo.astrid.api; -import android.content.ContentValues; import android.os.Parcel; import android.os.Parcelable; -import com.todoroo.andlib.data.AbstractModel; import com.todoroo.andlib.sql.Criterion; -import com.todoroo.andlib.sql.Functions; +import com.todoroo.andlib.sql.Field; import com.todoroo.andlib.sql.Join; -import com.todoroo.andlib.sql.Order; import com.todoroo.andlib.sql.QueryTemplate; -import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.TaskDao; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.gtasks.GtasksList; -import com.todoroo.astrid.gtasks.GtasksMetadata; import org.tasks.R; +import org.tasks.data.GoogleTask; +import java.util.HashMap; import java.util.Map; -import static com.todoroo.andlib.utility.AndroidUtilities.mapFromContentValues; - public class GtasksFilter extends Filter { private static final int CLOUD = R.drawable.ic_cloud_black_24dp; @@ -42,7 +36,7 @@ public class GtasksFilter extends Filter { public static String toManualOrder(String query) { query = query.replaceAll("ORDER BY .*", ""); - query = query + String.format(" ORDER BY %s", Order.asc(Functions.cast(GtasksMetadata.ORDER, "LONG"))); + query = query + " ORDER BY `order` ASC"; return query.replace( TaskDao.TaskCriteria.activeAndVisible().toString(), TaskDao.TaskCriteria.notDeleted().toString()); @@ -53,20 +47,16 @@ public class GtasksFilter extends Filter { } private static QueryTemplate getQueryTemplate(GtasksList list) { - Criterion fullCriterion = Criterion.and( - MetadataDao.MetadataCriteria.withKey(GtasksMetadata.METADATA_KEY), - TaskDao.TaskCriteria.activeAndVisible(), - GtasksMetadata.LIST_ID.eq(list.getRemoteId())); - return new QueryTemplate().join(Join.left(Metadata.TABLE, Task.ID.eq(Metadata.TASK))) - .where(fullCriterion); + return new QueryTemplate() + .join(Join.left(GoogleTask.TABLE, Task.ID.eq(Field.field("google_tasks.task")))) + .where(Criterion.and( + TaskDao.TaskCriteria.activeAndVisible(), + Field.field("list_id").eq(list.getRemoteId()))); } private static Map getValuesForNewTasks(GtasksList list) { - ContentValues contentValues = GtasksMetadata.createEmptyMetadataWithoutList(AbstractModel.NO_ID).getMergedValues(); - Map values = mapFromContentValues(contentValues); - values.remove(Metadata.TASK.name); - values.put(GtasksMetadata.LIST_ID.name, list.getRemoteId()); - values.put(GtasksMetadata.ORDER.name, PermaSql.VALUE_NOW); + Map values = new HashMap<>(); + values.put(GoogleTask.KEY, list.getRemoteId()); return values; } diff --git a/app/src/main/java/com/todoroo/astrid/backup/BackupConstants.java b/app/src/main/java/com/todoroo/astrid/backup/BackupConstants.java index 9ac9df26b..8f6566ef2 100755 --- a/app/src/main/java/com/todoroo/astrid/backup/BackupConstants.java +++ b/app/src/main/java/com/todoroo/astrid/backup/BackupConstants.java @@ -43,6 +43,8 @@ class BackupConstants { public static final String TAG_TAG = "tag"; + public static final String GOOGLE_TASKS_TAG = "googletasks"; + /** Tag containing a tagdata item */ public static final String TAGDATA_TAG = "tagdata"; diff --git a/app/src/main/java/com/todoroo/astrid/backup/TasksXmlExporter.java b/app/src/main/java/com/todoroo/astrid/backup/TasksXmlExporter.java index 89cab5439..c9ce7709b 100755 --- a/app/src/main/java/com/todoroo/astrid/backup/TasksXmlExporter.java +++ b/app/src/main/java/com/todoroo/astrid/backup/TasksXmlExporter.java @@ -20,11 +20,9 @@ import com.todoroo.andlib.sql.Order; import com.todoroo.andlib.sql.Query; import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DialogUtilities; -import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.TagDataDao; import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.dao.UserActivityDao; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.TagData; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.UserActivity; @@ -33,6 +31,8 @@ import org.tasks.R; import org.tasks.backup.XmlWriter; import org.tasks.data.Alarm; import org.tasks.data.AlarmDao; +import org.tasks.data.GoogleTask; +import org.tasks.data.GoogleTaskDao; import org.tasks.data.Location; import org.tasks.data.LocationDao; import org.tasks.data.Tag; @@ -66,10 +66,10 @@ public class TasksXmlExporter { // --- implementation private final TagDataDao tagDataDao; - private final MetadataDao metadataDao; private final AlarmDao alarmDao; private final LocationDao locationDao; private final TagDao tagDao; + private final GoogleTaskDao googleTaskDao; private final TaskDao taskDao; private UserActivityDao userActivityDao; private final Preferences preferences; @@ -98,16 +98,17 @@ public class TasksXmlExporter { } @Inject - public TasksXmlExporter(TagDataDao tagDataDao, MetadataDao metadataDao, TaskDao taskDao, UserActivityDao userActivityDao, - Preferences preferences, AlarmDao alarmDao, LocationDao locationDao, TagDao tagDao) { + public TasksXmlExporter(TagDataDao tagDataDao, TaskDao taskDao, UserActivityDao userActivityDao, + Preferences preferences, AlarmDao alarmDao, LocationDao locationDao, + TagDao tagDao, GoogleTaskDao googleTaskDao) { this.tagDataDao = tagDataDao; - this.metadataDao = metadataDao; this.taskDao = taskDao; this.userActivityDao = userActivityDao; this.preferences = preferences; this.alarmDao = alarmDao; this.locationDao = locationDao; this.tagDao = tagDao; + this.googleTaskDao = googleTaskDao; } public void exportTasks(final Context context, final ExportType exportType, @Nullable final ProgressDialog progressDialog) { @@ -218,15 +219,6 @@ public class TasksXmlExporter { } private synchronized void serializeMetadata(Task task) { - for (Metadata metadata : metadataDao.byTask(task.getId())) { - try { - xml.startTag(null, BackupConstants.METADATA_TAG); - serializeModel(metadata, Metadata.PROPERTIES, Metadata.ID, Metadata.TASK); - xml.endTag(null, BackupConstants.METADATA_TAG); - } catch (IOException e) { - throw new RuntimeException(e); - } - } XmlWriter writer = new XmlWriter(xml); for (Alarm alarm : alarmDao.getAlarms(task.getId())) { try { @@ -255,6 +247,15 @@ public class TasksXmlExporter { throw new RuntimeException(e); } } + for (GoogleTask googleTask : googleTaskDao.getAllByTaskId(task.getId())) { + try { + xml.startTag(null, BackupConstants.GOOGLE_TASKS_TAG); + googleTask.writeToXml(writer); + xml.endTag(null, BackupConstants.GOOGLE_TASKS_TAG); + } catch (IOException e) { + throw new RuntimeException(e); + } + } } /** diff --git a/app/src/main/java/com/todoroo/astrid/backup/TasksXmlImporter.java b/app/src/main/java/com/todoroo/astrid/backup/TasksXmlImporter.java index 69cad5186..c9999e93d 100755 --- a/app/src/main/java/com/todoroo/astrid/backup/TasksXmlImporter.java +++ b/app/src/main/java/com/todoroo/astrid/backup/TasksXmlImporter.java @@ -17,11 +17,9 @@ import com.todoroo.andlib.data.Property.PropertyVisitor; import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Query; import com.todoroo.andlib.utility.DialogUtilities; -import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.TagDataDao; import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.dao.UserActivityDao; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.TagData; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.UserActivity; @@ -31,6 +29,8 @@ import org.tasks.R; import org.tasks.backup.XmlReader; import org.tasks.data.Alarm; import org.tasks.data.AlarmDao; +import org.tasks.data.GoogleTask; +import org.tasks.data.GoogleTaskDao; import org.tasks.data.Location; import org.tasks.data.LocationDao; import org.tasks.data.Tag; @@ -50,13 +50,13 @@ import timber.log.Timber; public class TasksXmlImporter { private final TagDataDao tagDataDao; - private final MetadataDao metadataDao; private final UserActivityDao userActivityDao; private final DialogBuilder dialogBuilder; private final TaskDao taskDao; - private LocalBroadcastManager localBroadcastManager; + private final LocalBroadcastManager localBroadcastManager; private final AlarmDao alarmDao; private final TagDao tagDao; + private GoogleTaskDao googleTaskDao; private final LocationDao locationDao; private Activity activity; @@ -73,11 +73,11 @@ public class TasksXmlImporter { } @Inject - public TasksXmlImporter(TagDataDao tagDataDao, MetadataDao metadataDao, UserActivityDao userActivityDao, + public TasksXmlImporter(TagDataDao tagDataDao, UserActivityDao userActivityDao, DialogBuilder dialogBuilder, TaskDao taskDao, LocationDao locationDao, - LocalBroadcastManager localBroadcastManager, AlarmDao alarmDao, TagDao tagDao) { + LocalBroadcastManager localBroadcastManager, AlarmDao alarmDao, + TagDao tagDao, GoogleTaskDao googleTaskDao) { this.tagDataDao = tagDataDao; - this.metadataDao = metadataDao; this.userActivityDao = userActivityDao; this.dialogBuilder = dialogBuilder; this.taskDao = taskDao; @@ -85,6 +85,7 @@ public class TasksXmlImporter { this.localBroadcastManager = localBroadcastManager; this.alarmDao = alarmDao; this.tagDao = tagDao; + this.googleTaskDao = googleTaskDao; } public void importTasks(Activity activity, String input, ProgressDialog progressDialog) { @@ -165,7 +166,6 @@ public class TasksXmlImporter { XmlPullParser xpp; final Task currentTask = new Task(); - final Metadata metadata = new Metadata(); public Format2TaskImporter() { } public Format2TaskImporter(XmlPullParser xpp) throws XmlPullParserException, IOException { @@ -235,7 +235,6 @@ public class TasksXmlImporter { } UserActivity userActivity = new UserActivity(new XmlReader(xpp)); - userActivityDao.createNew(userActivity); } @@ -245,7 +244,7 @@ public class TasksXmlImporter { } Alarm alarm = new Alarm(new XmlReader(xpp)); - + alarm.setTask(currentTask.getId()); alarmDao.insert(alarm); } @@ -255,7 +254,7 @@ public class TasksXmlImporter { } Location location = new Location(new XmlReader(xpp)); - + location.setTask(currentTask.getId()); locationDao.insert(location); } @@ -265,32 +264,42 @@ public class TasksXmlImporter { } Tag tag = new Tag(new XmlReader(xpp)); - + tag.setTask(currentTask.getId()); tagDao.insert(tag); } + void parseGoogleTask() { + if (!currentTask.isSaved()) { + return; + } + + GoogleTask googleTask = new GoogleTask(new XmlReader(xpp)); + googleTask.setTask(currentTask.getId()); + googleTaskDao.insert(googleTask); + } + void parseMetadata(int format) { if(!currentTask.isSaved()) { return; } - metadata.clear(); - deserializeModel(metadata, Metadata.PROPERTIES); - if (metadata.getKey().equals("alarm")) { + XmlReader xml = new XmlReader(xpp); + String key = xml.readString("key"); + if ("alarm".equals(key)) { Alarm alarm = new Alarm(); alarm.setTask(currentTask.getId()); - alarm.setTime(Long.valueOf(metadata.getValue(Metadata.VALUE1))); + alarm.setTime(xml.readLong("value")); alarmDao.insert(alarm); - } else if (metadata.getKey().equals("geofence")) { + } else if ("geofence".equals(key)) { Location location = new Location(); location.setTask(currentTask.getId()); - location.setName(metadata.getValue(Metadata.VALUE1)); - location.setLatitude(Double.valueOf(metadata.getValue(Metadata.VALUE2))); - location.setLongitude(Double.valueOf(metadata.getValue(Metadata.VALUE3))); - location.setRadius(Integer.valueOf(metadata.getValue(Metadata.VALUE4))); + location.setName(xml.readString("value")); + location.setLatitude(xml.readDouble("value2")); + location.setLongitude(xml.readDouble("value3")); + location.setRadius(xml.readInteger("value4")); locationDao.insert(location); - } else if (metadata.getKey().equals("tags-tag")) { - String tagUid = metadata.getValue(Metadata.VALUE2); - String name = metadata.getValue(Metadata.VALUE1); + } else if ("tags-tag".equals(key)) { + String name = xml.readString("value"); + String tagUid = xml.readString("value2"); if (tagDao.getTagByTaskAndTagUid(currentTask.getId(), tagUid) == null) { tagDao.insert(new Tag(currentTask.getId(), currentTask.getUuid(), name, tagUid)); } @@ -305,10 +314,18 @@ public class TasksXmlImporter { tagDataDao.insert(tagData); } } - } else { - metadata.setId(Metadata.NO_ID); - metadata.setTask(currentTask.getId()); - metadataDao.persist(metadata); + } else if ("gtasks".equals(key)) { + GoogleTask googleTask = new GoogleTask(); + googleTask.setTask(currentTask.getId()); + googleTask.setRemoteId(xml.readString("value")); + googleTask.setListId(xml.readString("value2")); + googleTask.setParent(xml.readLong("value3")); + googleTask.setIndent(xml.readInteger("value4")); + googleTask.setOrder(xml.readLong("value5")); + googleTask.setRemoteOrder(xml.readLong("value6")); + googleTask.setLastSync(xml.readLong("value7")); + googleTask.setDeleted(xml.readLong("deleted")); + googleTaskDao.insert(googleTask); } } @@ -410,6 +427,9 @@ public class TasksXmlImporter { case BackupConstants.TAG_TAG: parseTag(); break; + case BackupConstants.GOOGLE_TASKS_TAG: + parseGoogleTask(); + break; } } catch (Exception e) { errorCount++; diff --git a/app/src/main/java/com/todoroo/astrid/core/OldTaskPreferences.java b/app/src/main/java/com/todoroo/astrid/core/OldTaskPreferences.java index 3323f10cf..f48a1f1a7 100644 --- a/app/src/main/java/com/todoroo/astrid/core/OldTaskPreferences.java +++ b/app/src/main/java/com/todoroo/astrid/core/OldTaskPreferences.java @@ -10,7 +10,6 @@ import android.os.Bundle; import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Query; import com.todoroo.astrid.dao.Database; -import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.data.Task; @@ -29,7 +28,6 @@ import javax.inject.Inject; public class OldTaskPreferences extends InjectingPreferenceActivity { @Inject DialogBuilder dialogBuilder; - @Inject MetadataDao metadataDao; @Inject Preferences preferences; @Inject Database database; @Inject TaskDao taskDao; @@ -76,10 +74,9 @@ public class OldTaskPreferences extends InjectingPreferenceActivity { .where(Criterion.and(Task.DELETION_DATE.gt(0))); for (Task task : taskDao.toList(query)) { calendarEventProvider.deleteEvent(task); + taskDao.delete(task.getId()); } - int result = taskDao.deleteWhere(Task.DELETION_DATE.gt(0)); - metadataDao.removeDanglingMetadata(); - return result; + return taskDao.deleteWhere(Task.DELETION_DATE.gt(0)); } @Override diff --git a/app/src/main/java/com/todoroo/astrid/dao/Database.java b/app/src/main/java/com/todoroo/astrid/dao/Database.java index 5ea258a9f..f77f160be 100644 --- a/app/src/main/java/com/todoroo/astrid/dao/Database.java +++ b/app/src/main/java/com/todoroo/astrid/dao/Database.java @@ -15,7 +15,6 @@ import android.database.sqlite.SQLiteDatabase; import com.todoroo.andlib.data.AbstractModel; import com.todoroo.andlib.data.Table; import com.todoroo.andlib.utility.AndroidUtilities; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.StoreObject; import com.todoroo.astrid.data.TagData; import com.todoroo.astrid.data.Task; @@ -25,6 +24,8 @@ import com.todoroo.astrid.data.UserActivity; import org.tasks.data.Alarm; import org.tasks.data.AlarmDao; +import org.tasks.data.GoogleTask; +import org.tasks.data.GoogleTaskDao; import org.tasks.data.Location; import org.tasks.data.LocationDao; import org.tasks.data.Tag; @@ -51,12 +52,12 @@ import timber.log.Timber; TaskListMetadata.class, StoreObject.class, Task.class, - Metadata.class, Alarm.class, Location.class, - Tag.class + Tag.class, + GoogleTask.class }, - version = 49) + version = 50) public abstract class Database extends RoomDatabase { public abstract NotificationDao notificationDao(); @@ -66,14 +67,14 @@ public abstract class Database extends RoomDatabase { public abstract TaskListMetadataDao getTaskListMetadataDao(); public abstract StoreObjectDao getStoreObjectDao(); public abstract AlarmDao getAlarmDao(); - public abstract LocationDao getGeofenceDao(); + public abstract LocationDao getLocationDao(); public abstract TagDao getTagDao(); + public abstract GoogleTaskDao getGoogleTaskDao(); public static final String NAME = "database"; public static final Table[] TABLES = new Table[] { - Task.TABLE, - Metadata.TABLE + Task.TABLE }; private SupportSQLiteDatabase database; diff --git a/app/src/main/java/com/todoroo/astrid/dao/MetadataDao.java b/app/src/main/java/com/todoroo/astrid/dao/MetadataDao.java deleted file mode 100644 index c21e614d7..000000000 --- a/app/src/main/java/com/todoroo/astrid/dao/MetadataDao.java +++ /dev/null @@ -1,139 +0,0 @@ -/** - * Copyright (c) 2012 Todoroo Inc - * - * See the file "LICENSE" for the full license governing this code. - */ -package com.todoroo.astrid.dao; - -import com.todoroo.andlib.data.DatabaseDao; -import com.todoroo.andlib.sql.Criterion; -import com.todoroo.andlib.sql.Join; -import com.todoroo.andlib.sql.Query; -import com.todoroo.andlib.utility.DateUtilities; -import com.todoroo.astrid.data.Metadata; -import com.todoroo.astrid.data.Task; - -import org.tasks.injection.ApplicationScope; - -import java.util.List; - -import javax.inject.Inject; - -/** - * Data Access layer for {@link Metadata}-related operations. - * - * @author Tim Su - * - */ -@ApplicationScope -public class MetadataDao { - - private final DatabaseDao dao; - - @Inject - public MetadataDao(Database database) { - dao = new DatabaseDao<>(database, Metadata.class); - } - - public Metadata getFirst(Query query) { - return dao.getFirst(query); - } - - public Metadata getFirstActiveByTaskAndKey(long taskId, String key) { - return getFirst(Query.select(Metadata.PROPERTIES).where(Criterion.and( - MetadataCriteria.byTaskAndwithKey(taskId, key), - MetadataCriteria.isActive()))); - } - - public int update(Criterion where, Metadata template) { - return dao.update(where, template); - } - - public void createNew(Metadata metadata) { - dao.createNew(metadata); - } - - public List toList(Criterion criterion) { - return toList(Query.select(Metadata.PROPERTIES).where(criterion)); - } - - public List toList(Query where) { - return dao.toList(where); - } - - public int deleteWhere(Criterion criterion) { - return dao.deleteWhere(criterion); - } - - public boolean delete(long id) { - return dao.delete(id); - } - - public void saveExisting(Metadata metadata) { - dao.saveExisting(metadata); - } - - public Metadata fetch(long id) { - return dao.fetch(id, Metadata.PROPERTIES); - } - - // --- SQL clause generators - - /** - * Generates SQL clauses - */ - public static class MetadataCriteria { - - /** Returns all metadata associated with a given task */ - public static Criterion byTask(long taskId) { - return Metadata.TASK.eq(taskId); - } - - /** Returns all metadata associated with a given key */ - public static Criterion withKey(String key) { - return Metadata.KEY.eq(key); - } - - /** Returns all metadata associated with a given key */ - public static Criterion byTaskAndwithKey(long taskId, String key) { - return Criterion.and(withKey(key), byTask(taskId)); - } - - public static Criterion isActive() { - return Metadata.DELETION_DATE.eq(0); - } - - public static Criterion isDeleted() { - return Metadata.DELETION_DATE.gt(0); - } - } - - public boolean persist(Metadata item) { - if(!item.containsNonNullValue(Metadata.TASK)) { - throw new IllegalArgumentException("metadata needs to be attached to a task: " + item.getMergedValues()); //$NON-NLS-1$ - } - if(!item.containsValue(Metadata.CREATION_DATE)) { - item.setCreationDate(DateUtilities.now()); - } - - return dao.persist(item); - } - - /** - * Clean up metadata. Typically called on startup - */ - public void removeDanglingMetadata() { - dao.deleteWhere(Metadata.ID.in(Query.select(Metadata.ID).from(Metadata.TABLE).join(Join.left(Task.TABLE, - Metadata.TASK.eq(Task.ID))).where(Task.TITLE.isNull()))); - } - - public List byTask(long taskId) { - return toList(MetadataCriteria.byTask(taskId)); - } - - public List byTaskAndKey(long taskId, String key) { - return dao.toList(Query.select(Metadata.PROPERTIES).where( - Criterion.and(Metadata.TASK.eq(taskId), Metadata.KEY.eq(key)))); - } -} - diff --git a/app/src/main/java/com/todoroo/astrid/dao/TaskDao.java b/app/src/main/java/com/todoroo/astrid/dao/TaskDao.java index 9ab249eba..babeb74cd 100644 --- a/app/src/main/java/com/todoroo/astrid/dao/TaskDao.java +++ b/app/src/main/java/com/todoroo/astrid/dao/TaskDao.java @@ -18,7 +18,6 @@ import com.todoroo.andlib.sql.Query; import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.PermaSql; -import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria; import com.todoroo.astrid.data.RemoteModel; import com.todoroo.astrid.data.SyncFlags; import com.todoroo.astrid.data.Task; @@ -26,6 +25,10 @@ import com.todoroo.astrid.data.TaskApiDao; import org.tasks.LocalBroadcastManager; import org.tasks.R; +import org.tasks.data.AlarmDao; +import org.tasks.data.GoogleTaskDao; +import org.tasks.data.LocationDao; +import org.tasks.data.TagDao; import org.tasks.injection.ApplicationScope; import org.tasks.injection.ForApplication; import org.tasks.jobs.AfterSaveIntentService; @@ -52,16 +55,25 @@ public class TaskDao { private final RemoteModelDao dao; private final LocalBroadcastManager localBroadcastManager; - private final MetadataDao metadataDao; + private final Database database; private final Preferences preferences; + private final AlarmDao alarmDao; + private final TagDao tagDao; + private final LocationDao locationDao; + private final GoogleTaskDao googleTaskDao; private final Context context; @Inject - public TaskDao(@ForApplication Context context, Database database, MetadataDao metadataDao, - Preferences preferences, LocalBroadcastManager localBroadcastManager) { + public TaskDao(@ForApplication Context context, Database database, + Preferences preferences, LocalBroadcastManager localBroadcastManager, + AlarmDao alarmDao, TagDao tagDao, LocationDao locationDao, GoogleTaskDao googleTaskDao) { this.context = context; + this.database = database; this.preferences = preferences; - this.metadataDao = metadataDao; + this.alarmDao = alarmDao; + this.tagDao = tagDao; + this.locationDao = locationDao; + this.googleTaskDao = googleTaskDao; this.localBroadcastManager = localBroadcastManager; dao = new RemoteModelDao<>(database, Task.class); } @@ -188,7 +200,10 @@ public class TaskDao { } // delete all metadata - metadataDao.deleteWhere(MetadataCriteria.byTask(id)); + alarmDao.deleteByTaskId(id); + locationDao.deleteByTaskId(id); + tagDao.deleteByTaskId(id); + googleTaskDao.deleteByTaskId(id); localBroadcastManager.broadcastRefresh(); diff --git a/app/src/main/java/com/todoroo/astrid/data/Metadata.java b/app/src/main/java/com/todoroo/astrid/data/Metadata.java deleted file mode 100644 index 0ecb2172c..000000000 --- a/app/src/main/java/com/todoroo/astrid/data/Metadata.java +++ /dev/null @@ -1,179 +0,0 @@ -/** - * Copyright (c) 2012 Todoroo Inc - * - * See the file "LICENSE" for the full license governing this code. - */ -package com.todoroo.astrid.data; - - -import android.arch.persistence.room.ColumnInfo; -import android.arch.persistence.room.Entity; -import android.arch.persistence.room.Ignore; -import android.arch.persistence.room.Index; -import android.arch.persistence.room.PrimaryKey; -import android.content.ContentValues; - -import com.todoroo.andlib.data.AbstractModel; -import com.todoroo.andlib.data.Property; -import com.todoroo.andlib.data.Property.LongProperty; -import com.todoroo.andlib.data.Property.StringProperty; -import com.todoroo.andlib.data.Table; - -/** - * Data Model which represents a piece of metadata associated with a task - * - * @author Tim Su - * - */ -@Entity(tableName = "metadata", - indices = { - @Index(name = "md_tid", value = "task"), - @Index(name = "md_tkid", value = {"task", "key"}) - }) -public class Metadata extends AbstractModel { - - // --- table - - /** table for this model */ - public static final Table TABLE = new Table("metadata", Metadata.class); - - // --- properties - - /** ID */ - @PrimaryKey(autoGenerate = true) - @ColumnInfo(name = "_id") - public Long id; - public static final LongProperty ID = new LongProperty( - TABLE, ID_PROPERTY_NAME); - - /** Associated Task */ - @ColumnInfo(name = "task") - public Long task; - public static final LongProperty TASK = new LongProperty( - TABLE, "task"); - - /** Metadata Key */ - @ColumnInfo(name = "key") - public String key; - public static final StringProperty KEY = new StringProperty( - TABLE, "key"); - - /** Metadata Text Value Column 1 */ - @ColumnInfo(name = "value") - public String value1; - public static final StringProperty VALUE1 = new StringProperty( - TABLE, "value"); - - /** Metadata Text Value Column 2 */ - @ColumnInfo(name = "value2") - public String value2; - public static final StringProperty VALUE2 = new StringProperty( - TABLE, "value2"); - - /** Metadata Text Value Column 3 */ - @ColumnInfo(name = "value3") - public String value3; - public static final StringProperty VALUE3 = new StringProperty( - TABLE, "value3"); - - /** Metadata Text Value Column 4 */ - @ColumnInfo(name = "value4") - public String value4; - public static final StringProperty VALUE4 = new StringProperty( - TABLE, "value4"); - - /** Metadata Text Value Column 5 */ - @ColumnInfo(name = "value5") - public String value5; - public static final StringProperty VALUE5 = new StringProperty( - TABLE, "value5"); - - @ColumnInfo(name = "value6") - public String value6; - public static final StringProperty VALUE6 = new StringProperty( - TABLE, "value6"); - - @ColumnInfo(name = "value7") - public String value7; - public static final StringProperty VALUE7 = new StringProperty( - TABLE, "value7"); - - /** Unixtime Metadata was created */ - @ColumnInfo(name = "created") - public Long created; - public static final LongProperty CREATION_DATE = new LongProperty( - TABLE, "created"); - - /** Unixtime metadata was deleted/tombstoned */ - @ColumnInfo(name = "deleted") - public Long deleted = 0L; - public static final LongProperty DELETION_DATE = new LongProperty( - TABLE, "deleted"); - - /** List of all properties for this model */ - public static final Property[] PROPERTIES = generateProperties(Metadata.class); - - // --- defaults - - /** Default values container */ - private static final ContentValues defaultValues = new ContentValues(); - - static { - defaultValues.put(DELETION_DATE.name, 0L); - } - - public Metadata() { - super(); - } - - @Ignore - public Metadata(Metadata metadata) { - super(metadata); - } - - @Override - public ContentValues getDefaultValues() { - return defaultValues; - } - - @Override - public long getId() { - return getIdHelper(ID); - } - - // --- parcelable helpers - - private static final Creator CREATOR = new ModelCreator<>(Metadata.class); - - public Long getDeletionDate() { - return getValue(DELETION_DATE); - } - - public void setDeletionDate(Long deletionDate) { - setValue(DELETION_DATE, deletionDate); - } - - public Long getTask() { - return getValue(TASK); - } - - public void setTask(Long task) { - setValue(TASK, task); - } - - public Long getCreationDate() { - return getValue(CREATION_DATE); - } - - public void setCreationDate(Long creationDate) { - setValue(CREATION_DATE, creationDate); - } - - public String getKey() { - return getValue(KEY); - } - - public void setKey(String key) { - setValue(KEY, key); - } -} diff --git a/app/src/main/java/com/todoroo/astrid/data/TagData.java b/app/src/main/java/com/todoroo/astrid/data/TagData.java index 5b6808123..366f10e0c 100644 --- a/app/src/main/java/com/todoroo/astrid/data/TagData.java +++ b/app/src/main/java/com/todoroo/astrid/data/TagData.java @@ -13,7 +13,7 @@ import org.tasks.backup.XmlWriter; import java.io.Serializable; @Entity(tableName = "tagdata") -public final class TagData implements Parcelable, Serializable { +public final class TagData implements Parcelable { @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "_id") diff --git a/app/src/main/java/com/todoroo/astrid/gtasks/GtasksMetadata.java b/app/src/main/java/com/todoroo/astrid/gtasks/GtasksMetadata.java deleted file mode 100644 index 87b31cc15..000000000 --- a/app/src/main/java/com/todoroo/astrid/gtasks/GtasksMetadata.java +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Copyright (c) 2012 Todoroo Inc - * - * See the file "LICENSE" for the full license governing this code. - */ -package com.todoroo.astrid.gtasks; - -import com.todoroo.andlib.data.AbstractModel; -import com.todoroo.andlib.data.Property.IntegerProperty; -import com.todoroo.andlib.data.Property.LongProperty; -import com.todoroo.andlib.data.Property.StringProperty; -import com.todoroo.andlib.utility.DateUtilities; -import com.todoroo.astrid.data.Metadata; - -import javax.inject.Inject; - -/** - * Metadata entries for a GTasks Task - * @author Tim Su - * - */ -public class GtasksMetadata { - - /** metadata key */ - public static final String METADATA_KEY = "gtasks"; //$NON-NLS-1$ - - /** task id in google */ - public static final StringProperty ID = new StringProperty(Metadata.TABLE, - Metadata.VALUE1.name); - - public static final StringProperty LIST_ID = new StringProperty(Metadata.TABLE, - Metadata.VALUE2.name); - - /** parent task id, or 0 if top level task */ - public static final LongProperty PARENT_TASK = new LongProperty(Metadata.TABLE, - Metadata.VALUE3.name); - - public static final IntegerProperty INDENT = new IntegerProperty(Metadata.TABLE, - Metadata.VALUE4.name); - - public static final LongProperty ORDER = new LongProperty(Metadata.TABLE, - Metadata.VALUE5.name); - - public static final LongProperty GTASKS_ORDER = new LongProperty(Metadata.TABLE, - Metadata.VALUE6.name); - - public static final LongProperty LAST_SYNC = new LongProperty(Metadata.TABLE, - Metadata.VALUE7.name); - private final GtasksPreferenceService gtasksPreferenceService; - - @Inject - public GtasksMetadata(GtasksPreferenceService gtasksPreferenceService) { - this.gtasksPreferenceService = gtasksPreferenceService; - } - - /** - * Creates default GTasks metadata item - * @param taskId if > 0, will set metadata task field - */ - public Metadata createEmptyMetadata(long taskId) { - Metadata metadata = createEmptyMetadataWithoutList(taskId); - String defaultList = gtasksPreferenceService.getDefaultList(); - if(defaultList == null) { - defaultList = "@default"; //$NON-NLS-1$ - } - metadata.setValue(LIST_ID, defaultList); - return metadata; - } - - public static Metadata createEmptyMetadataWithoutList(long taskId) { - Metadata metadata = new Metadata(); - metadata.setKey(GtasksMetadata.METADATA_KEY); - metadata.setValue(ID, ""); //$NON-NLS-1$ - metadata.setValue(PARENT_TASK, AbstractModel.NO_ID); - metadata.setValue(INDENT, 0); - metadata.setValue(ORDER, DateUtilities.now()); - if(taskId > AbstractModel.NO_ID) { - metadata.setTask(taskId); - } - return metadata; - } -} diff --git a/app/src/main/java/com/todoroo/astrid/service/StartupService.java b/app/src/main/java/com/todoroo/astrid/service/StartupService.java index afd6c8a9b..4c8962b25 100644 --- a/app/src/main/java/com/todoroo/astrid/service/StartupService.java +++ b/app/src/main/java/com/todoroo/astrid/service/StartupService.java @@ -14,7 +14,6 @@ import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ListMultimap; import com.google.common.collect.Multimaps; import com.todoroo.astrid.dao.Database; -import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.TagDataDao; import com.todoroo.astrid.data.TagData; import com.todoroo.astrid.tags.TagService; @@ -48,7 +47,6 @@ public class StartupService { private final Tracker tracker; private final TagDataDao tagDataDao; private final TagService tagService; - private final MetadataDao metadataDao; private final LocalBroadcastManager localBroadcastManager; private final Context context; private final TagDao tagDao; @@ -56,7 +54,7 @@ public class StartupService { @Inject public StartupService(Database database, Preferences preferences, TaskDeleter taskDeleter, Tracker tracker, TagDataDao tagDataDao, TagService tagService, - MetadataDao metadataDao, LocalBroadcastManager localBroadcastManager, + LocalBroadcastManager localBroadcastManager, @ForApplication Context context, TagDao tagDao) { this.database = database; this.preferences = preferences; @@ -64,7 +62,6 @@ public class StartupService { this.tracker = tracker; this.tagDataDao = tagDataDao; this.tagService = tagService; - this.metadataDao = metadataDao; this.localBroadcastManager = localBroadcastManager; this.context = context; this.tagDao = tagDao; @@ -158,7 +155,7 @@ public class StartupService { for (Long key : metadataByTask.keySet()) { ImmutableList tagData = metadataByTask.get(key); for (int i = 1 ; i < tagData.size() ; i++) { - metadataDao.delete(tagData.get(i).getId()); + tagDao.deleteById(tagData.get(i).getId()); } } } diff --git a/app/src/main/java/com/todoroo/astrid/service/TaskCreator.java b/app/src/main/java/com/todoroo/astrid/service/TaskCreator.java index 47f83013d..551a5ca03 100644 --- a/app/src/main/java/com/todoroo/astrid/service/TaskCreator.java +++ b/app/src/main/java/com/todoroo/astrid/service/TaskCreator.java @@ -4,13 +4,10 @@ import android.content.ContentValues; import android.net.Uri; import android.text.TextUtils; -import com.todoroo.andlib.data.Property; import com.todoroo.andlib.utility.AndroidUtilities; import com.todoroo.astrid.api.PermaSql; -import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.TagDataDao; import com.todoroo.astrid.dao.TaskDao; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.SyncFlags; import com.todoroo.astrid.data.TagData; import com.todoroo.astrid.data.Task; @@ -18,6 +15,8 @@ import com.todoroo.astrid.gcal.GCalHelper; import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.utility.TitleParser; +import org.tasks.data.GoogleTask; +import org.tasks.data.GoogleTaskDao; import org.tasks.data.Tag; import org.tasks.data.TagDao; import org.tasks.preferences.Preferences; @@ -33,22 +32,22 @@ public class TaskCreator { private final GCalHelper gcalHelper; private final Preferences preferences; - private final MetadataDao metadataDao; private final TagDao tagDao; + private final GoogleTaskDao googleTaskDao; private final TagDataDao tagDataDao; private final TaskDao taskDao; private final TagService tagService; @Inject - public TaskCreator(GCalHelper gcalHelper, Preferences preferences, MetadataDao metadataDao, - TagDataDao tagDataDao, TaskDao taskDao, TagService tagService, TagDao tagDao) { + public TaskCreator(GCalHelper gcalHelper, Preferences preferences, TagDataDao tagDataDao, + TaskDao taskDao, TagService tagService, TagDao tagDao, GoogleTaskDao googleTaskDao) { this.gcalHelper = gcalHelper; this.preferences = preferences; - this.metadataDao = metadataDao; this.tagDataDao = tagDataDao; this.taskDao = taskDao; this.tagService = tagService; this.tagDao = tagDao; + this.googleTaskDao = googleTaskDao; } public Task basicQuickAddTask(String title) { @@ -90,14 +89,12 @@ public class TaskCreator { Timber.e(e, e.getMessage()); } - ContentValues forMetadata = null; if (values != null && values.size() > 0) { ContentValues forTask = new ContentValues(); - forMetadata = new ContentValues(); - outer: for (Map.Entry item : values.entrySet()) { + for (Map.Entry item : values.entrySet()) { String key = item.getKey(); Object value = item.getValue(); - if (key.equals(Tag.KEY)) { + if (key.equals(Tag.KEY) || key.equals(GoogleTask.KEY)) { continue; } @@ -105,13 +102,6 @@ public class TaskCreator { value = PermaSql.replacePlaceholders((String) value); } - for (Property property : Metadata.PROPERTIES) { - if (property.name.equals(key)) { - AndroidUtilities.putInto(forMetadata, key, value); - continue outer; - } - } - AndroidUtilities.putInto(forTask, key, value); } task.mergeWithoutReplacement(forTask); @@ -119,21 +109,20 @@ public class TaskCreator { saveWithoutPublishingFilterUpdate(task); - if (values != null && values.containsKey(Tag.KEY)) { - createLink(task, (String) values.get(Tag.KEY)); + if (values != null) { + if (values.containsKey(Tag.KEY)) { + createLink(task, (String) values.get(Tag.KEY)); + } + if (values.containsKey(GoogleTask.KEY)) { + GoogleTask googleTask = new GoogleTask(task.getId(), (String) values.get(GoogleTask.KEY)); + googleTaskDao.insert(googleTask); + } } for(String tag : tags) { createLink(task, tag); } - if (forMetadata != null && forMetadata.size() > 0) { - Metadata metadata = new Metadata(); - metadata.setTask(task.getId()); - metadata.mergeWith(forMetadata); - metadataDao.persist(metadata); - } - return task; } diff --git a/app/src/main/java/com/todoroo/astrid/service/TaskDuplicator.java b/app/src/main/java/com/todoroo/astrid/service/TaskDuplicator.java index d95b79983..01b8aa4db 100644 --- a/app/src/main/java/com/todoroo/astrid/service/TaskDuplicator.java +++ b/app/src/main/java/com/todoroo/astrid/service/TaskDuplicator.java @@ -2,15 +2,14 @@ package com.todoroo.astrid.service; import com.google.common.collect.Lists; import com.todoroo.andlib.utility.DateUtilities; -import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.TaskDao; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.SyncFlags; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.gcal.GCalHelper; -import com.todoroo.astrid.gtasks.GtasksMetadata; import org.tasks.LocalBroadcastManager; +import org.tasks.data.GoogleTask; +import org.tasks.data.GoogleTaskDao; import org.tasks.data.Tag; import org.tasks.data.TagDao; @@ -19,36 +18,34 @@ import java.util.List; import javax.inject.Inject; -import timber.log.Timber; - public class TaskDuplicator { private final GCalHelper gcalHelper; - private final MetadataDao metadataDao; private final TaskDao taskDao; private final TagDao tagDao; + private final GoogleTaskDao googleTaskDao; private final LocalBroadcastManager localBroadcastManager; @Inject - public TaskDuplicator(GCalHelper gcalHelper, MetadataDao metadataDao, TaskDao taskDao, - LocalBroadcastManager localBroadcastManager, TagDao tagDao) { + public TaskDuplicator(GCalHelper gcalHelper, TaskDao taskDao, LocalBroadcastManager localBroadcastManager, + TagDao tagDao, GoogleTaskDao googleTaskDao) { this.gcalHelper = gcalHelper; - this.metadataDao = metadataDao; this.taskDao = taskDao; this.localBroadcastManager = localBroadcastManager; this.tagDao = tagDao; + this.googleTaskDao = googleTaskDao; } public List duplicate(List tasks) { List result = new ArrayList<>(); for (Task task : tasks) { - result.add(clone(taskDao.fetch(task.getId()), true)); + result.add(clone(taskDao.fetch(task.getId()))); } localBroadcastManager.broadcastRefresh(); return result; } - private Task clone(Task original, boolean suppressRefresh) { + private Task clone(Task original) { Task clone = new Task(original); clone.setCreationDate(DateUtilities.now()); clone.setCompletionDate(0L); @@ -57,13 +54,11 @@ public class TaskDuplicator { clone.clearValue(Task.ID); clone.clearValue(Task.UUID); - List metadataList = metadataDao.byTask(original.getId()); - if (!metadataList.isEmpty()) { + GoogleTask googleTask = googleTaskDao.getByTaskId(original.getId()); + if (googleTask != null) { clone.putTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC, true); } - if (suppressRefresh) { - clone.putTransitory(TaskDao.TRANS_SUPPRESS_REFRESH, true); - } + clone.putTransitory(TaskDao.TRANS_SUPPRESS_REFRESH, true); taskDao.save(clone); @@ -71,16 +66,8 @@ public class TaskDuplicator { tagDao.getTagsForTask(original.getId()), tag -> new Tag(clone.getId(), clone.getUuid(), tag.getName(), tag.getTagUid()))); - for (Metadata oldMetadata : metadataList) { - if(!oldMetadata.containsNonNullValue(Metadata.KEY)) { - continue; - } - Timber.d("Cloning %s", oldMetadata); - if(GtasksMetadata.METADATA_KEY.equals(oldMetadata.getKey())) { - Metadata gtaskMetadata = GtasksMetadata.createEmptyMetadataWithoutList(clone.getId()); - gtaskMetadata.setValue(GtasksMetadata.LIST_ID, oldMetadata.getValue(GtasksMetadata.LIST_ID)); - metadataDao.createNew(gtaskMetadata); - } + if (googleTask != null) { + googleTaskDao.insert(new GoogleTask(clone.getId(), googleTask.getListId())); } gcalHelper.createTaskEventIfEnabled(clone); diff --git a/app/src/main/java/com/todoroo/astrid/tags/TagsControlSet.java b/app/src/main/java/com/todoroo/astrid/tags/TagsControlSet.java index e8497a758..9f139b927 100644 --- a/app/src/main/java/com/todoroo/astrid/tags/TagsControlSet.java +++ b/app/src/main/java/com/todoroo/astrid/tags/TagsControlSet.java @@ -40,7 +40,6 @@ import com.google.common.collect.Ordering; import com.google.common.collect.Sets; import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.astrid.dao.TagDataDao; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.RemoteModel; import com.todoroo.astrid.data.TagData; import com.todoroo.astrid.data.Task; @@ -410,9 +409,6 @@ public final class TagsControlSet extends TaskEditControlFragment { * Delete all links between the specified task and the list of tags */ private void deleteLinks(long taskId, Iterable tags) { - Metadata deleteTemplate = new Metadata(); - deleteTemplate.setTask(taskId); // Need this for recording changes in outstanding table - deleteTemplate.setDeletionDate(DateUtilities.now()); for (TagData tag : tags) { // TODO: Right now this is in a loop because each deleteTemplate needs the individual tagUuid in order to record // the outstanding entry correctly. If possible, this should be improved to a single query diff --git a/app/src/main/java/org/tasks/backup/XmlReader.java b/app/src/main/java/org/tasks/backup/XmlReader.java index bdfd04dc1..e6ab27ab9 100644 --- a/app/src/main/java/org/tasks/backup/XmlReader.java +++ b/app/src/main/java/org/tasks/backup/XmlReader.java @@ -4,6 +4,8 @@ import com.todoroo.astrid.backup.TasksXmlExporter; import org.xmlpull.v1.XmlPullParser; +import static com.todoroo.astrid.backup.TasksXmlExporter.XML_NULL; + public class XmlReader { public interface ValueWriter { @@ -16,34 +18,50 @@ public class XmlReader { this.xpp = xpp; } - public void readLong(String name, ValueWriter writer) { + public Long readLong(String name) { String value = xpp.getAttributeValue(null, name); + return value == null || XML_NULL.equals(value) ? null : Long.parseLong(value); + } + + public void readLong(String name, ValueWriter writer) { + Long value = readLong(name); if(value != null) { - writer.write(TasksXmlExporter.XML_NULL.equals(value) ? - null : Long.parseLong(value)); + writer.write(value); } } - public void readInteger(String name, ValueWriter writer) { + public Integer readInteger(String name) { String value = xpp.getAttributeValue(null, name); + return value == null || XML_NULL.equals(value) ? null : Integer.parseInt(value); + } + + public void readInteger(String name, ValueWriter writer) { + Integer value = readInteger(name); if(value != null) { - writer.write(TasksXmlExporter.XML_NULL.equals(value) ? - null : Integer.parseInt(value)); + writer.write(value); } } + public String readString(String name) { + return xpp.getAttributeValue(null, name); + } + public void readString(String name, ValueWriter writer) { - String value = xpp.getAttributeValue(null, name); + String value = readString(name); if (value != null) { writer.write(value); } } - public void readDouble(String name, ValueWriter writer) { + public Double readDouble(String name) { String value = xpp.getAttributeValue(null, name); + return value == null || XML_NULL.equals(value) ? null : Double.parseDouble(value); + } + + public void readDouble(String name, ValueWriter writer) { + Double value = readDouble(name); if (value != null) { - writer.write(TasksXmlExporter.XML_NULL.equals(value) ? - null : Double.parseDouble(value)); + writer.write(value); } } } diff --git a/app/src/main/java/org/tasks/data/Alarm.java b/app/src/main/java/org/tasks/data/Alarm.java index 4c179bd3a..570b6c1d3 100644 --- a/app/src/main/java/org/tasks/data/Alarm.java +++ b/app/src/main/java/org/tasks/data/Alarm.java @@ -25,14 +25,18 @@ public class Alarm { } + @Ignore + public Alarm(long task, long time) { + this.task = task; + this.time = time; + } + @Ignore public Alarm(XmlReader xml) { - xml.readLong("task", this::setTask); xml.readLong("time", this::setTime); } public void writeToXml(XmlWriter writer) { - writer.writeLong("task", task); writer.writeLong("time", time); } diff --git a/app/src/main/java/org/tasks/data/AlarmDao.java b/app/src/main/java/org/tasks/data/AlarmDao.java index 124ff3951..e5b6e1239 100644 --- a/app/src/main/java/org/tasks/data/AlarmDao.java +++ b/app/src/main/java/org/tasks/data/AlarmDao.java @@ -26,5 +26,8 @@ public interface AlarmDao { void delete(Alarm alarm); @Insert - void insert(Alarm alarm); + long insert(Alarm alarm); + + @Query("DELETE FROM alarms WHERE task = :taskId") + void deleteByTaskId(long taskId); } diff --git a/app/src/main/java/org/tasks/data/GoogleTask.java b/app/src/main/java/org/tasks/data/GoogleTask.java new file mode 100644 index 000000000..18fa21f60 --- /dev/null +++ b/app/src/main/java/org/tasks/data/GoogleTask.java @@ -0,0 +1,200 @@ +package org.tasks.data; + +import android.arch.persistence.room.ColumnInfo; +import android.arch.persistence.room.Entity; +import android.arch.persistence.room.Ignore; +import android.arch.persistence.room.PrimaryKey; + +import com.todoroo.andlib.data.Property; +import com.todoroo.andlib.data.Table; +import com.todoroo.andlib.utility.DateUtilities; + +import org.tasks.backup.XmlReader; +import org.tasks.backup.XmlWriter; + +@Entity(tableName = "google_tasks") +public class GoogleTask { + + public static final String KEY = "gtasks"; //$NON-NLS-1$ + + @Deprecated + public static final Table TABLE = new Table("google_tasks", null); + + @Deprecated + public static final Property.IntegerProperty INDENT = new Property.IntegerProperty(GoogleTask.TABLE, "indent"); + + @Deprecated + public static final Property.LongProperty ORDER = new Property.LongProperty(GoogleTask.TABLE, "`order`"); + + @PrimaryKey(autoGenerate = true) + @ColumnInfo(name = "_id") + private long id; + + @ColumnInfo(name = "task") + private long task; + + @ColumnInfo(name = "remote_id") + private String remoteId = ""; + + @ColumnInfo(name = "list_id") + private String listId = ""; + + @ColumnInfo(name = "parent") + private long parent; + + @ColumnInfo(name = "indent") + private int indent; + + @ColumnInfo(name = "order") + private long order; + + @ColumnInfo(name = "remote_order") + private long remoteOrder; + + @ColumnInfo(name = "last_sync") + private long lastSync; + + @ColumnInfo(name = "deleted") + private long deleted; + + @Ignore + private boolean suppressSync; + + public GoogleTask() { + + } + + @Ignore + public GoogleTask(long task, String listId) { + this.task = task; + this.order = DateUtilities.now(); + this.listId = listId; + } + + @Ignore + public GoogleTask(XmlReader xml) { + remoteId = xml.readString("remote_id"); + listId = xml.readString("list_id"); + parent = xml.readLong("parent"); + indent = xml.readInteger("indent"); + order = xml.readLong("order"); + remoteOrder = xml.readLong("remote_order"); + lastSync = xml.readLong("last_sync"); + deleted = xml.readLong("deleted"); + } + + public void writeToXml(XmlWriter xml) { + xml.writeString("remote_id", remoteId); + xml.writeString("list_id", listId); + xml.writeLong("parent", parent); + xml.writeInteger("indent", indent); + xml.writeLong("order", order); + xml.writeLong("remote_order", remoteOrder); + xml.writeLong("last_sync", lastSync); + xml.writeLong("deleted", deleted); + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public long getTask() { + return task; + } + + public void setTask(long task) { + this.task = task; + } + + public String getRemoteId() { + return remoteId; + } + + public void setRemoteId(String remoteId) { + this.remoteId = remoteId; + } + + public String getListId() { + return listId; + } + + public void setListId(String listId) { + this.listId = listId; + } + + public long getParent() { + return parent; + } + + public void setParent(long parent) { + this.parent = parent; + } + + public int getIndent() { + return indent; + } + + public void setIndent(int indent) { + this.indent = indent; + } + + public long getOrder() { + return order; + } + + public void setOrder(long order) { + this.order = order; + } + + public long getRemoteOrder() { + return remoteOrder; + } + + public void setRemoteOrder(long remoteOrder) { + this.remoteOrder = remoteOrder; + } + + public long getLastSync() { + return lastSync; + } + + public void setLastSync(long lastSync) { + this.lastSync = lastSync; + } + + public long getDeleted() { + return deleted; + } + + public void setDeleted(long deleted) { + this.deleted = deleted; + } + + public boolean isSuppressSync() { + return suppressSync; + } + + public void setSuppressSync(boolean suppressSync) { + this.suppressSync = suppressSync; + } + + @Override + public String toString() { + return "GoogleTask{" + + "id=" + id + + ", task=" + task + + ", remoteId='" + remoteId + '\'' + + ", listId='" + listId + '\'' + + ", parent=" + parent + + ", indent=" + indent + + ", order=" + order + + ", remoteOrder=" + remoteOrder + + ", lastSync=" + lastSync + + ", deleted=" + deleted + + '}'; + } +} diff --git a/app/src/main/java/org/tasks/data/GoogleTaskDao.java b/app/src/main/java/org/tasks/data/GoogleTaskDao.java new file mode 100644 index 000000000..cae171549 --- /dev/null +++ b/app/src/main/java/org/tasks/data/GoogleTaskDao.java @@ -0,0 +1,51 @@ +package org.tasks.data; + +import android.arch.persistence.room.Dao; +import android.arch.persistence.room.Delete; +import android.arch.persistence.room.Insert; +import android.arch.persistence.room.Query; +import android.arch.persistence.room.Update; + +import java.util.List; + +@Dao +public interface GoogleTaskDao { + @Query("DELETE FROM google_tasks WHERE list_id = :remoteId") + void deleteList(String remoteId); + + @Insert + void insert(GoogleTask task); + + @Query("SELECT * FROM google_tasks WHERE task = :taskId AND deleted = 0 LIMIT 1") + GoogleTask getByTaskId(long taskId); + + @Update + void update(GoogleTask googleTask); + + @Query("SELECT * FROM google_tasks WHERE list_id = :listId AND parent = :parent ORDER BY remote_order ASC") + List byRemoteOrder(String listId, long parent); + + @Query("SELECT * FROM google_tasks WHERE list_id = :listId AND `order` > :startAtOrder - 1 ORDER BY `order` ASC ") + List getTasksFrom(String listId, long startAtOrder); + + @Query("SELECT * FROM google_tasks WHERE list_id = :listId AND `order` < :startAtOrder ORDER BY `order` DESC") + List getTasksFromReverse(String listId, long startAtOrder); + + @Query("DELETE FROM google_tasks WHERE task = :taskId") + void deleteByTaskId(long taskId); + + @Delete + void delete(GoogleTask deleted); + + @Query("SELECT * FROM google_tasks WHERE remote_id = :remoteId LIMIT 1") + GoogleTask getByRemoteId(String remoteId); + + @Query("SELECT * FROM google_tasks WHERE task = :taskId AND deleted > 0") + List getDeletedByTaskId(long taskId); + + @Query("SELECT * FROM google_tasks WHERE task = :taskId") + List getAllByTaskId(long taskId); + + @Query("DELETE FROM google_tasks") + void deleteAll(); +} diff --git a/app/src/main/java/org/tasks/data/Location.java b/app/src/main/java/org/tasks/data/Location.java index 51c0b3582..4c5084d68 100644 --- a/app/src/main/java/org/tasks/data/Location.java +++ b/app/src/main/java/org/tasks/data/Location.java @@ -49,7 +49,6 @@ public class Location implements Serializable, Parcelable { @Ignore public Location(XmlReader xml) { - xml.readLong("task", this::setTask); xml.readString("name", this::setName); xml.readDouble("latitude", this::setLatitude); xml.readDouble("longitude", this::setLongitude); @@ -57,7 +56,6 @@ public class Location implements Serializable, Parcelable { } public void writeToXml(XmlWriter xmlWriter) { - xmlWriter.writeLong("task", task); xmlWriter.writeString("name", name); xmlWriter.writeDouble("latitude", latitude); xmlWriter.writeDouble("longitude", longitude); diff --git a/app/src/main/java/org/tasks/data/LocationDao.java b/app/src/main/java/org/tasks/data/LocationDao.java index 0ed741b97..58b7bb7e2 100644 --- a/app/src/main/java/org/tasks/data/LocationDao.java +++ b/app/src/main/java/org/tasks/data/LocationDao.java @@ -27,4 +27,7 @@ public interface LocationDao { @Insert void insert(Location location); + + @Query("DELETE FROM locations WHERE task = :taskId") + void deleteByTaskId(long taskId); } diff --git a/app/src/main/java/org/tasks/data/Tag.java b/app/src/main/java/org/tasks/data/Tag.java index e429fd2ac..5f57ed39b 100644 --- a/app/src/main/java/org/tasks/data/Tag.java +++ b/app/src/main/java/org/tasks/data/Tag.java @@ -49,14 +49,12 @@ public class Tag { @Ignore public Tag(XmlReader xmlReader) { - xmlReader.readLong("task", this::setTask); xmlReader.readString("name", this::setName); xmlReader.readString("tag_uid", this::setTagUid); xmlReader.readString("task_uid", this::setTaskUid); } public void writeToXml(XmlWriter xmlWriter) { - xmlWriter.writeLong("task", task); xmlWriter.writeString("name", name); xmlWriter.writeString("tag_uid", tagUid); xmlWriter.writeString("task_uid", taskUid); diff --git a/app/src/main/java/org/tasks/data/TagDao.java b/app/src/main/java/org/tasks/data/TagDao.java index 0b0fb8eb7..4b4636402 100644 --- a/app/src/main/java/org/tasks/data/TagDao.java +++ b/app/src/main/java/org/tasks/data/TagDao.java @@ -40,4 +40,10 @@ public interface TagDao { @Query("SELECT * FROM tags WHERE task = :taskId AND tag_uid = :tagUid") Tag getTagByTaskAndTagUid(long taskId, String tagUid); + + @Query("DELETE FROM tags WHERE task = :taskId") + void deleteByTaskId(long taskId); + + @Query("DELETE FROM tags WHERE _id = :id") + void deleteById(long id); } diff --git a/app/src/main/java/org/tasks/db/Migrations.java b/app/src/main/java/org/tasks/db/Migrations.java index a118c0f59..ab38da993 100644 --- a/app/src/main/java/org/tasks/db/Migrations.java +++ b/app/src/main/java/org/tasks/db/Migrations.java @@ -63,6 +63,16 @@ public class Migrations { } }; + private static final Migration MIGRATION_49_50 = new Migration(49, 50) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase database) { + database.execSQL("CREATE TABLE IF NOT EXISTS `google_tasks` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `remote_id` TEXT, `list_id` TEXT, `parent` INTEGER NOT NULL, `indent` INTEGER NOT NULL, `order` INTEGER NOT NULL, `remote_order` INTEGER NOT NULL, `last_sync` INTEGER NOT NULL, `deleted` INTEGER NOT NULL)"); + database.execSQL("INSERT INTO `google_tasks` (`task`, `remote_id`, `list_id`, `parent`, `indent`, `order`, `remote_order`, `last_sync`, `deleted`) " + + "SELECT `task`, `value`, `value2`, `value3`, `value4`, `value5`, `value6`, `value7`, `deleted` FROM `metadata` WHERE `key` = 'gtasks'"); + database.execSQL("DROP TABLE IF EXISTS `metadata`"); + } + }; + private static Migration NOOP(int from, int to) { return new Migration(from, to) { @Override @@ -86,6 +96,7 @@ public class Migrations { NOOP(45, 46), MIGRATION_46_47, MIGRATION_47_48, - MIGRATION_48_49 + MIGRATION_48_49, + MIGRATION_49_50 }; } diff --git a/app/src/main/java/org/tasks/filters/FilterCriteriaProvider.java b/app/src/main/java/org/tasks/filters/FilterCriteriaProvider.java index 964cb9971..d48d53430 100644 --- a/app/src/main/java/org/tasks/filters/FilterCriteriaProvider.java +++ b/app/src/main/java/org/tasks/filters/FilterCriteriaProvider.java @@ -1,10 +1,8 @@ package org.tasks.filters; -import android.content.ContentValues; import android.content.Context; import android.content.res.Resources; -import com.todoroo.andlib.data.AbstractModel; import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Field; import com.todoroo.andlib.sql.Join; @@ -13,17 +11,15 @@ import com.todoroo.astrid.api.CustomFilterCriterion; import com.todoroo.astrid.api.MultipleSelectCriterion; import com.todoroo.astrid.api.PermaSql; import com.todoroo.astrid.api.TextInputCriterion; -import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.TaskDao; -import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.TagData; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.gtasks.GtasksList; import com.todoroo.astrid.gtasks.GtasksListService; -import com.todoroo.astrid.gtasks.GtasksMetadata; import com.todoroo.astrid.tags.TagService; import org.tasks.R; +import org.tasks.data.GoogleTask; import org.tasks.data.Tag; import org.tasks.gtasks.SyncAdapterHelper; import org.tasks.injection.ForApplication; @@ -37,7 +33,6 @@ import javax.inject.Inject; import static com.google.common.collect.Iterables.transform; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Sets.newLinkedHashSet; -import static com.todoroo.andlib.utility.AndroidUtilities.mapFromContentValues; public class FilterCriteriaProvider { @@ -51,18 +46,15 @@ public class FilterCriteriaProvider { private final Context context; private final TagService tagService; private final GtasksListService gtasksListService; - private final GtasksMetadata gtasksMetadata; private final Resources r; private final SyncAdapterHelper syncAdapterHelper; @Inject public FilterCriteriaProvider(@ForApplication Context context, TagService tagService, - GtasksListService gtasksListService, - GtasksMetadata gtasksMetadata, SyncAdapterHelper syncAdapterHelper) { + GtasksListService gtasksListService, SyncAdapterHelper syncAdapterHelper) { this.context = context; this.tagService = tagService; this.gtasksListService = gtasksListService; - this.gtasksMetadata = gtasksMetadata; this.syncAdapterHelper = syncAdapterHelper; r = context.getResources(); @@ -186,21 +178,17 @@ public class FilterCriteriaProvider { listIds[i] = lists.get(i).getRemoteId(); } - ContentValues contentValues = gtasksMetadata.createEmptyMetadata(AbstractModel.NO_ID).getMergedValues(); - Map values = mapFromContentValues(contentValues); - values.remove(Metadata.TASK.name); - values.put(GtasksMetadata.LIST_ID.name, "?"); + Map values = new HashMap<>(); + values.put(GoogleTask.KEY, "?"); return new MultipleSelectCriterion( IDENTIFIER_GTASKS, context.getString(R.string.CFC_gtasks_list_text), - - Query.select(Metadata.TASK).from(Metadata.TABLE).join(Join.inner( - Task.TABLE, Metadata.TASK.eq(Task.ID))).where(Criterion.and( - TaskDao.TaskCriteria.activeAndVisible(), - MetadataDao.MetadataCriteria.withKey(GtasksMetadata.METADATA_KEY), - GtasksMetadata.LIST_ID.eq("?"))).toString(), - + Query.select(Field.field("task")).from(GoogleTask.TABLE) + .join(Join.inner(Task.TABLE, Field.field("task").eq(Task.ID))) + .where(Criterion.and( + TaskDao.TaskCriteria.activeAndVisible(), + Field.field("list_id").eq("?"))).toString(), values, listNames, listIds, diff --git a/app/src/main/java/org/tasks/injection/ApplicationModule.java b/app/src/main/java/org/tasks/injection/ApplicationModule.java index 20b3f56f3..ded58c423 100644 --- a/app/src/main/java/org/tasks/injection/ApplicationModule.java +++ b/app/src/main/java/org/tasks/injection/ApplicationModule.java @@ -9,12 +9,12 @@ import com.todoroo.astrid.dao.TagDataDao; import com.todoroo.astrid.dao.TaskAttachmentDao; import com.todoroo.astrid.dao.TaskListMetadataDao; import com.todoroo.astrid.dao.UserActivityDao; -import com.todoroo.astrid.data.TagData; import com.todoroo.astrid.provider.Astrid2TaskProvider; import org.tasks.ErrorReportingSingleThreadExecutor; import org.tasks.analytics.Tracker; import org.tasks.data.AlarmDao; +import org.tasks.data.GoogleTaskDao; import org.tasks.data.LocationDao; import org.tasks.data.TagDao; import org.tasks.db.Migrations; @@ -95,6 +95,11 @@ public class ApplicationModule { return database.getStoreObjectDao(); } + @Provides + public GoogleTaskDao getGoogleTaskDao(Database database) { + return database.getGoogleTaskDao(); + } + @Provides public AlarmDao getAlarmDao(Database database) { return database.getAlarmDao(); @@ -102,7 +107,7 @@ public class ApplicationModule { @Provides public LocationDao getGeofenceDao(Database database) { - return database.getGeofenceDao(); + return database.getLocationDao(); } @Provides diff --git a/app/src/main/java/org/tasks/tasklist/TagListFragment.java b/app/src/main/java/org/tasks/tasklist/TagListFragment.java index ed9d685f3..d6f2d80bf 100644 --- a/app/src/main/java/org/tasks/tasklist/TagListFragment.java +++ b/app/src/main/java/org/tasks/tasklist/TagListFragment.java @@ -3,7 +3,6 @@ package org.tasks.tasklist; import android.app.Activity; import android.content.Intent; import android.os.Bundle; -import android.os.Parcelable; import android.support.v7.widget.Toolbar; import android.view.MenuItem; @@ -52,7 +51,7 @@ public class TagListFragment extends TaskListFragment { switch (item.getItemId()) { case R.id.menu_tag_settings: Intent intent = new Intent(getActivity(), TagSettingsActivity.class); - intent.putExtra(TagSettingsActivity.EXTRA_TAG_DATA, (Parcelable) tagData); + intent.putExtra(TagSettingsActivity.EXTRA_TAG_DATA, tagData); startActivityForResult(intent, REQUEST_EDIT_TAG); return true; default: