diff --git a/api/src/main/java/com/todoroo/andlib/data/AbstractModel.java b/api/src/main/java/com/todoroo/andlib/data/AbstractModel.java index 63d2f9e09..4938f25a5 100644 --- a/api/src/main/java/com/todoroo/andlib/data/AbstractModel.java +++ b/api/src/main/java/com/todoroo/andlib/data/AbstractModel.java @@ -209,13 +209,10 @@ public abstract class AbstractModel implements Parcelable, Cloneable { // resolve properties that were retrieved with a different type than accessed try { if(value instanceof String && property instanceof LongProperty) { - log.debug("{}={} stored as string instead of long", columnName, value); return (TYPE) Long.valueOf((String) value); } else if(value instanceof String && property instanceof IntegerProperty) { - log.debug("{}={} stored as string instead of int", columnName, value); return (TYPE) Integer.valueOf((String) value); } else if(value instanceof Integer && property instanceof LongProperty) { - log.debug("{}={} stored as int instead of long", columnName, value); return (TYPE) Long.valueOf(((Number) value).longValue()); } return (TYPE) value; diff --git a/api/src/main/java/com/todoroo/andlib/data/DatabaseDao.java b/api/src/main/java/com/todoroo/andlib/data/DatabaseDao.java index 4b0e6de8f..c5a39205f 100644 --- a/api/src/main/java/com/todoroo/andlib/data/DatabaseDao.java +++ b/api/src/main/java/com/todoroo/andlib/data/DatabaseDao.java @@ -11,6 +11,9 @@ import android.database.Cursor; import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Query; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; @@ -26,6 +29,8 @@ import java.util.concurrent.atomic.AtomicBoolean; */ public class DatabaseDao { + private static final Logger log = LoggerFactory.getLogger(DatabaseDao.class); + private final Class modelClass; private Table table; @@ -139,6 +144,7 @@ public class DatabaseDao { * @return # of deleted items */ public int deleteWhere(Criterion where) { + log.debug("deleteWhere({})", where); return database.delete(table.name, where.toString(), null); } diff --git a/astrid/src/main/java/com/todoroo/astrid/gtasks/GtasksBackgroundService.java b/astrid/src/main/java/com/todoroo/astrid/gtasks/GtasksBackgroundService.java index 62359f9af..2ae35d682 100644 --- a/astrid/src/main/java/com/todoroo/astrid/gtasks/GtasksBackgroundService.java +++ b/astrid/src/main/java/com/todoroo/astrid/gtasks/GtasksBackgroundService.java @@ -58,7 +58,7 @@ public class GtasksBackgroundService extends InjectingService { SyncV2Provider provider = gtasksSyncV2Provider; if (provider.isActive()) { - provider.synchronizeActiveTasks(false, new SyncResultCallback() { + provider.synchronizeActiveTasks(new SyncResultCallback() { @Override public void started() { } diff --git a/astrid/src/main/java/com/todoroo/astrid/gtasks/GtasksListFragment.java b/astrid/src/main/java/com/todoroo/astrid/gtasks/GtasksListFragment.java index 581dec19a..567702170 100644 --- a/astrid/src/main/java/com/todoroo/astrid/gtasks/GtasksListFragment.java +++ b/astrid/src/main/java/com/todoroo/astrid/gtasks/GtasksListFragment.java @@ -88,7 +88,7 @@ public class GtasksListFragment extends SubtasksListFragment { private void refreshData(final boolean manual) { ((TextView)getView().findViewById(android.R.id.empty)).setText(R.string.DLG_loading); - syncService.synchronizeList(list, manual, new IndeterminateProgressBarSyncResultCallback(getActivity(), new Runnable() { + syncService.synchronizeList(list, new IndeterminateProgressBarSyncResultCallback(getActivity(), new Runnable() { @Override public void run() { if (manual) { diff --git a/astrid/src/main/java/com/todoroo/astrid/gtasks/api/GtasksInvoker.java b/astrid/src/main/java/com/todoroo/astrid/gtasks/api/GtasksInvoker.java index eb87635f8..5c292ca7d 100644 --- a/astrid/src/main/java/com/todoroo/astrid/gtasks/api/GtasksInvoker.java +++ b/astrid/src/main/java/com/todoroo/astrid/gtasks/api/GtasksInvoker.java @@ -64,6 +64,8 @@ public class GtasksInvoker { } } else if (statusCode == 400 || statusCode == 500) { throw h; + } else if (statusCode == 404) { + throw new HttpNotFoundException(h); } else { log.error(statusCode + ": " + h.getStatusMessage(), e); } diff --git a/astrid/src/main/java/com/todoroo/astrid/gtasks/api/HttpNotFoundException.java b/astrid/src/main/java/com/todoroo/astrid/gtasks/api/HttpNotFoundException.java new file mode 100644 index 000000000..5223b441b --- /dev/null +++ b/astrid/src/main/java/com/todoroo/astrid/gtasks/api/HttpNotFoundException.java @@ -0,0 +1,11 @@ +package com.todoroo.astrid.gtasks.api; + +import com.google.api.client.http.HttpResponseException; + +import java.io.IOException; + +public class HttpNotFoundException extends IOException { + public HttpNotFoundException(HttpResponseException e) { + super(e.getMessage()); + } +} diff --git a/astrid/src/main/java/com/todoroo/astrid/gtasks/sync/GtasksSyncService.java b/astrid/src/main/java/com/todoroo/astrid/gtasks/sync/GtasksSyncService.java index 319599489..855eed6f7 100644 --- a/astrid/src/main/java/com/todoroo/astrid/gtasks/sync/GtasksSyncService.java +++ b/astrid/src/main/java/com/todoroo/astrid/gtasks/sync/GtasksSyncService.java @@ -23,6 +23,7 @@ import com.todoroo.astrid.gtasks.GtasksPreferenceService; import com.todoroo.astrid.gtasks.api.CreateRequest; import com.todoroo.astrid.gtasks.api.GtasksApiUtilities; import com.todoroo.astrid.gtasks.api.GtasksInvoker; +import com.todoroo.astrid.gtasks.api.HttpNotFoundException; import com.todoroo.astrid.gtasks.api.MoveRequest; import com.todoroo.astrid.gtasks.auth.GtasksTokenValidator; import com.todoroo.astrid.service.MetadataService; @@ -305,7 +306,13 @@ public class GtasksSyncService { } if (!newlyCreated) { - invoker.updateGtask(listId, remoteModel); + try { + invoker.updateGtask(listId, remoteModel); + } catch(HttpNotFoundException e) { + log.error("Received 404 response, deleting {}", gtasksMetadata); + metadataDao.delete(gtasksMetadata.getId()); + return; + } } else { String parent = gtasksMetadataService.getRemoteParentId(gtasksMetadata); String priorSibling = gtasksMetadataService.getRemoteSiblingId(listId, gtasksMetadata); diff --git a/astrid/src/main/java/com/todoroo/astrid/gtasks/sync/GtasksSyncV2Provider.java b/astrid/src/main/java/com/todoroo/astrid/gtasks/sync/GtasksSyncV2Provider.java index 58d3c75bf..d3a379f01 100644 --- a/astrid/src/main/java/com/todoroo/astrid/gtasks/sync/GtasksSyncV2Provider.java +++ b/astrid/src/main/java/com/todoroo/astrid/gtasks/sync/GtasksSyncV2Provider.java @@ -48,7 +48,6 @@ import org.tasks.sync.SyncExecutor; import java.io.IOException; import java.util.ArrayList; import java.util.Date; -import java.util.HashSet; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; @@ -121,10 +120,7 @@ public class GtasksSyncV2Provider extends SyncV2Provider { } @Override - public void synchronizeActiveTasks(final boolean manual, final SyncResultCallback callback) { - // TODO: Improve this logic. Should only be able to import from settings or something. - final boolean isImport = false; - + public void synchronizeActiveTasks(final SyncResultCallback callback) { callback.started(); gtasksPreferenceService.recordSyncStart(); @@ -152,7 +148,7 @@ public class GtasksSyncV2Provider extends SyncV2Provider { executor.execute(callback, new Runnable() { @Override public void run() { - synchronizeListHelper(list, invoker, manual, handler, isImport); + synchronizeListHelper(list, invoker, handler); if (finisher.decrementAndGet() == 0) { pushUpdated(invoker); finishSync(callback); @@ -190,7 +186,7 @@ public class GtasksSyncV2Provider extends SyncV2Provider { } @Override - public void synchronizeList(Object list, final boolean manual, final SyncResultCallback callback) { + public void synchronizeList(Object list, final SyncResultCallback callback) { if (!(list instanceof StoreObject)) { return; } @@ -199,8 +195,6 @@ public class GtasksSyncV2Provider extends SyncV2Provider { return; } - final boolean isImport = false; - callback.started(); executor.execute(callback, new Runnable() { @@ -210,7 +204,7 @@ public class GtasksSyncV2Provider extends SyncV2Provider { String authToken = getValidatedAuthToken(); gtasksSyncService.waitUntilEmpty(); final GtasksInvoker service = new GtasksInvoker(gtasksTokenValidator, authToken); - synchronizeListHelper(gtasksList, service, manual, null, isImport); + synchronizeListHelper(gtasksList, service, null); } finally { callback.finished(); } @@ -233,13 +227,11 @@ public class GtasksSyncV2Provider extends SyncV2Provider { } private synchronized void synchronizeListHelper(StoreObject list, GtasksInvoker invoker, - boolean manual, SyncExceptionHandler errorHandler, boolean isImport) { + SyncExceptionHandler errorHandler) { String listId = list.getValue(GtasksList.REMOTE_ID); - long lastSyncDate; - if (!manual && list.containsNonNullValue(GtasksList.LAST_SYNC)) { + long lastSyncDate = 0; + if (list.containsNonNullValue(GtasksList.LAST_SYNC)) { lastSyncDate = list.getValue(GtasksList.LAST_SYNC); - } else { - lastSyncDate = 0; } /** @@ -262,32 +254,16 @@ public class GtasksSyncV2Provider extends SyncV2Provider { includeDeletedAndHidden, lastSyncDate); List tasks = taskList.getItems(); if (tasks != null) { - HashSet localIds = new HashSet<>(tasks.size()); for (com.google.api.services.tasks.model.Task t : tasks) { GtasksTaskContainer container = parseRemoteTask(t, listId); gtasksMetadataService.findLocalMatch(container); - container.gtaskMetadata.setValue(GtasksMetadata.GTASKS_ORDER, - Long.parseLong(t.getPosition())); - container.gtaskMetadata.setValue(GtasksMetadata.PARENT_TASK, - gtasksMetadataService.localIdForGtasksId(t.getParent())); - container.gtaskMetadata.setValue(GtasksMetadata.LAST_SYNC, - DateUtilities.now() + 1000L); + container.gtaskMetadata.setValue(GtasksMetadata.GTASKS_ORDER, Long.parseLong(t.getPosition())); + container.gtaskMetadata.setValue(GtasksMetadata.PARENT_TASK, gtasksMetadataService.localIdForGtasksId(t.getParent())); + container.gtaskMetadata.setValue(GtasksMetadata.LAST_SYNC, DateUtilities.now() + 1000L); write(container); - localIds.add(container.task.getId()); } list.setValue(GtasksList.LAST_SYNC, DateUtilities.now()); storeObjectDao.persist(list); - - if(lastSyncDate == 0 && !isImport) { - Criterion delete = Criterion.and(Metadata.KEY.eq(GtasksMetadata.METADATA_KEY), - GtasksMetadata.LIST_ID.eq(listId), - Criterion.not(Metadata.TASK.in(localIds))); - taskDeleter.deleteWhere( - Task.ID.in(Query.select(Metadata.TASK).from(Metadata.TABLE). - where(delete))); - metadataService.deleteWhere(delete); - } - gtasksTaskListUpdater.correctOrderAndIndentForList(listId); } } catch (IOException e) { diff --git a/astrid/src/main/java/com/todoroo/astrid/helper/SyncActionHelper.java b/astrid/src/main/java/com/todoroo/astrid/helper/SyncActionHelper.java index a277f40b0..8927f96c9 100644 --- a/astrid/src/main/java/com/todoroo/astrid/helper/SyncActionHelper.java +++ b/astrid/src/main/java/com/todoroo/astrid/helper/SyncActionHelper.java @@ -137,7 +137,7 @@ public class SyncActionHelper { // --- sync logic protected void performSyncServiceV2Sync() { - boolean syncOccurred = syncService.synchronizeActiveTasks(false, syncResultCallback); + boolean syncOccurred = syncService.synchronizeActiveTasks(syncResultCallback); if (syncOccurred) { preferences.setLong(PREF_LAST_AUTO_SYNC, DateUtilities.now()); } @@ -215,7 +215,7 @@ public class SyncActionHelper { } } else { - syncService.synchronizeActiveTasks(true, syncResultCallback); + syncService.synchronizeActiveTasks(syncResultCallback); } } diff --git a/astrid/src/main/java/com/todoroo/astrid/service/MetadataService.java b/astrid/src/main/java/com/todoroo/astrid/service/MetadataService.java index c90d33711..1f5317464 100644 --- a/astrid/src/main/java/com/todoroo/astrid/service/MetadataService.java +++ b/astrid/src/main/java/com/todoroo/astrid/service/MetadataService.java @@ -70,13 +70,6 @@ public class MetadataService { return metadataDao.query(query); } - /** - * Delete from metadata table where rows match a certain condition - */ - public void deleteWhere(Criterion where) { - metadataDao.deleteWhere(where); - } - /** * Delete from metadata table where rows match a certain condition * @param where predicate for which rows to update diff --git a/astrid/src/main/java/com/todoroo/astrid/service/SyncV2Service.java b/astrid/src/main/java/com/todoroo/astrid/service/SyncV2Service.java index 566543fd4..487a82423 100644 --- a/astrid/src/main/java/com/todoroo/astrid/service/SyncV2Service.java +++ b/astrid/src/main/java/com/todoroo/astrid/service/SyncV2Service.java @@ -62,11 +62,10 @@ public class SyncV2Service { /** * Initiate synchronization of active tasks * - * @param manual if manual sync * @param callback result callback * @return true if any servide was logged in and initiated a sync */ - public boolean synchronizeActiveTasks(final boolean manual, SyncResultCallback callback) { + public boolean synchronizeActiveTasks(SyncResultCallback callback) { final List active = activeProviders(); if (active.size() == 0) { @@ -74,9 +73,9 @@ public class SyncV2Service { } if (active.size() > 1) { // This should never happen anymore--they can't be active at the same time, but if for some reason they both are, just use ActFm - active.get(1).synchronizeActiveTasks(manual, new WidgetUpdatingCallbackWrapper(context, callback)); + active.get(1).synchronizeActiveTasks(new WidgetUpdatingCallbackWrapper(context, callback)); } else if (active.size() == 1) { - active.get(0).synchronizeActiveTasks(manual, new WidgetUpdatingCallbackWrapper(context, callback)); + active.get(0).synchronizeActiveTasks(new WidgetUpdatingCallbackWrapper(context, callback)); } return true; @@ -86,13 +85,12 @@ public class SyncV2Service { * Initiate synchronization of task list * * @param list list object - * @param manual if manual sync * @param callback result callback */ - public void synchronizeList(Object list, boolean manual, SyncResultCallback callback) { + public void synchronizeList(Object list, SyncResultCallback callback) { for(SyncV2Provider provider : providers) { if(provider.isActive()) { - provider.synchronizeList(list, manual, new WidgetUpdatingCallbackWrapper(context, callback)); + provider.synchronizeList(list, new WidgetUpdatingCallbackWrapper(context, callback)); } } } diff --git a/astrid/src/main/java/com/todoroo/astrid/service/TaskDeleter.java b/astrid/src/main/java/com/todoroo/astrid/service/TaskDeleter.java index 26247618a..064feeb67 100644 --- a/astrid/src/main/java/com/todoroo/astrid/service/TaskDeleter.java +++ b/astrid/src/main/java/com/todoroo/astrid/service/TaskDeleter.java @@ -1,7 +1,6 @@ package com.todoroo.astrid.service; import com.todoroo.andlib.data.TodorooCursor; -import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Query; import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.astrid.dao.TaskDao; @@ -44,14 +43,7 @@ public class TaskDeleter { } public int purgeDeletedTasks() { - return deleteWhere(Task.DELETION_DATE.gt(0)); - } - - /** - * Delete all tasks matching a given criterion - */ - public int deleteWhere(Criterion criteria) { - return taskDao.deleteWhere(criteria); + return taskDao.deleteWhere(Task.DELETION_DATE.gt(0)); } /** diff --git a/astrid/src/main/java/com/todoroo/astrid/sync/SyncV2Provider.java b/astrid/src/main/java/com/todoroo/astrid/sync/SyncV2Provider.java index 5adc9f993..1f6b7ae87 100644 --- a/astrid/src/main/java/com/todoroo/astrid/sync/SyncV2Provider.java +++ b/astrid/src/main/java/com/todoroo/astrid/sync/SyncV2Provider.java @@ -37,15 +37,14 @@ abstract public class SyncV2Provider { * @param manual whether manually triggered * @param callback callback object */ - abstract public void synchronizeActiveTasks(boolean manual, SyncResultCallback callback); + abstract public void synchronizeActiveTasks(SyncResultCallback callback); /** * Synchronize a single list * @param list object representing list (TaskListActivity-dependent) - * @param manual whether was manually triggered * @param callback callback object */ - abstract public void synchronizeList(Object list, boolean manual, SyncResultCallback callback); + abstract public void synchronizeList(Object list, SyncResultCallback callback); /** * @return sync utility instance