mirror of https://github.com/tasks/tasks
Remove old upgrade code
parent
0e4e7ee50e
commit
dc51647447
@ -1,130 +0,0 @@
|
|||||||
package com.todoroo.astrid.subtasks;
|
|
||||||
|
|
||||||
import com.todoroo.andlib.utility.Preferences;
|
|
||||||
import com.todoroo.astrid.core.PluginServices;
|
|
||||||
import com.todoroo.astrid.data.Metadata;
|
|
||||||
import com.todoroo.astrid.data.TagData;
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public class SubtasksMigrationTest extends SubtasksTestCase {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
|
|
||||||
Preferences.clear(SubtasksUpdater.ACTIVE_TASKS_ORDER);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Starting basic state (see SubtasksTestCase):
|
|
||||||
*
|
|
||||||
* A
|
|
||||||
* B
|
|
||||||
* C
|
|
||||||
* D
|
|
||||||
* E
|
|
||||||
* F
|
|
||||||
*/
|
|
||||||
private void createBasicMetadata(TagData tagData) {
|
|
||||||
createSubtasksMetadata(tagData, 1, 1, 0);
|
|
||||||
createSubtasksMetadata(tagData, 2, 2, 1);
|
|
||||||
createSubtasksMetadata(tagData, 3, 3, 1);
|
|
||||||
createSubtasksMetadata(tagData, 4, 4, 2);
|
|
||||||
createSubtasksMetadata(tagData, 5, 5, 0);
|
|
||||||
createSubtasksMetadata(tagData, 6, 6, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createSubtasksMetadata(TagData tagData, long taskId, long order, int indent) {
|
|
||||||
Metadata m = new Metadata();
|
|
||||||
m.setValue(Metadata.KEY, SubtasksMetadata.METADATA_KEY);
|
|
||||||
m.setValue(Metadata.TASK, taskId);
|
|
||||||
String tagString = (tagData == null ? SubtasksMetadata.LIST_ACTIVE_TASKS : "td:"+tagData.getId());
|
|
||||||
m.setValue(SubtasksMetadata.TAG, tagString);
|
|
||||||
m.setValue(SubtasksMetadata.ORDER, order);
|
|
||||||
m.setValue(SubtasksMetadata.INDENT, indent);
|
|
||||||
PluginServices.getMetadataService().save(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void basicTest(TagData tagData) {
|
|
||||||
createBasicMetadata(tagData);
|
|
||||||
SubtasksMetadataMigration migrator = new SubtasksMetadataMigration();
|
|
||||||
migrator.performMigration();
|
|
||||||
|
|
||||||
String newSerializedTree = getSerializedTree(tagData);
|
|
||||||
String expectedSerializedTree = DEFAULT_SERIALIZED_TREE_STRING;
|
|
||||||
|
|
||||||
assertEquals(expectedSerializedTree, newSerializedTree);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getSerializedTree(TagData tagData) {
|
|
||||||
if (tagData == null)
|
|
||||||
return Preferences.getStringValue(SubtasksUpdater.ACTIVE_TASKS_ORDER).replaceAll("\\s", "");
|
|
||||||
tagData = PluginServices.getTagDataService().fetchById(tagData.getId(), TagData.ID, TagData.TAG_ORDERING);
|
|
||||||
return tagData.getValue(TagData.TAG_ORDERING).replaceAll("\\s", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testMigrationForActiveTasks() {
|
|
||||||
basicTest(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testMigrationForTagData() {
|
|
||||||
TagData td = new TagData();
|
|
||||||
td.setValue(TagData.NAME, "tag");
|
|
||||||
PluginServices.getTagDataService().save(td);
|
|
||||||
|
|
||||||
basicTest(td);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Starting advanced state
|
|
||||||
*
|
|
||||||
* For active tasks
|
|
||||||
*
|
|
||||||
* A
|
|
||||||
* B
|
|
||||||
* C
|
|
||||||
* D
|
|
||||||
* E
|
|
||||||
* F
|
|
||||||
*
|
|
||||||
* For tag data
|
|
||||||
*
|
|
||||||
* F
|
|
||||||
* E
|
|
||||||
* B
|
|
||||||
* D
|
|
||||||
* C
|
|
||||||
* A
|
|
||||||
*/
|
|
||||||
|
|
||||||
private static final String ACTIVE_TASKS_TREE = "[\"-1\", [\"1\", \"2\"], [\"3\", [\"4\", \"5\"], \"6\"]]".replaceAll("\\s", "");
|
|
||||||
private static final String TAG_DATA_TREE = "[\"-1\", \"6\", [\"5\", \"2\", [\"4\",\"3\"]], \"1\"]".replaceAll("\\s", "");
|
|
||||||
|
|
||||||
private void createAdvancedMetadata(TagData tagData) {
|
|
||||||
createSubtasksMetadata(tagData, 6, 1, 0);
|
|
||||||
createSubtasksMetadata(tagData, 5, 2, 0);
|
|
||||||
createSubtasksMetadata(tagData, 2, 3, 1);
|
|
||||||
createSubtasksMetadata(tagData, 4, 4, 1);
|
|
||||||
createSubtasksMetadata(tagData, 3, 5, 2);
|
|
||||||
createSubtasksMetadata(tagData, 1, 6, 0);
|
|
||||||
|
|
||||||
createSubtasksMetadata(null, 1, 1, 0);
|
|
||||||
createSubtasksMetadata(null, 2, 2, 1);
|
|
||||||
createSubtasksMetadata(null, 3, 3, 0);
|
|
||||||
createSubtasksMetadata(null, 4, 4, 1);
|
|
||||||
createSubtasksMetadata(null, 5, 5, 2);
|
|
||||||
createSubtasksMetadata(null, 6, 6, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testMigrationWithBothPresent() {
|
|
||||||
TagData td = new TagData();
|
|
||||||
td.setValue(TagData.NAME, "tag");
|
|
||||||
PluginServices.getTagDataService().save(td);
|
|
||||||
|
|
||||||
createAdvancedMetadata(td);
|
|
||||||
|
|
||||||
SubtasksMetadataMigration migrator = new SubtasksMetadataMigration();
|
|
||||||
migrator.performMigration();
|
|
||||||
|
|
||||||
assertEquals(TAG_DATA_TREE, getSerializedTree(td));
|
|
||||||
assertEquals(ACTIVE_TASKS_TREE, getSerializedTree(null));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,76 +0,0 @@
|
|||||||
package com.todoroo.astrid.actfm.sync;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.todoroo.andlib.data.TodorooCursor;
|
|
||||||
import com.todoroo.andlib.service.Autowired;
|
|
||||||
import com.todoroo.andlib.service.DependencyInjectionService;
|
|
||||||
import com.todoroo.andlib.sql.Criterion;
|
|
||||||
import com.todoroo.andlib.sql.Join;
|
|
||||||
import com.todoroo.andlib.sql.Query;
|
|
||||||
import com.todoroo.astrid.actfm.sync.messages.ConstructOutstandingTableFromMasterTable;
|
|
||||||
import com.todoroo.astrid.actfm.sync.messages.NameMaps;
|
|
||||||
import com.todoroo.astrid.dao.TaskAttachmentDao;
|
|
||||||
import com.todoroo.astrid.dao.TaskAttachmentOutstandingDao;
|
|
||||||
import com.todoroo.astrid.dao.TaskOutstandingDao;
|
|
||||||
import com.todoroo.astrid.data.Task;
|
|
||||||
import com.todoroo.astrid.data.TaskAttachment;
|
|
||||||
import com.todoroo.astrid.data.TaskAttachmentOutstanding;
|
|
||||||
import com.todoroo.astrid.data.TaskOutstanding;
|
|
||||||
|
|
||||||
public class EmptyTitleOutstandingEntryMigration {
|
|
||||||
|
|
||||||
private static final String ERROR_TAG = "empty-title-migrate"; //$NON-NLS-1$
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskOutstandingDao taskOutstandingDao;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskAttachmentDao taskAttachmentDao;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskAttachmentOutstandingDao taskAttachmentOutstandingDao;
|
|
||||||
|
|
||||||
public EmptyTitleOutstandingEntryMigration() {
|
|
||||||
DependencyInjectionService.getInstance().inject(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void performMigration() {
|
|
||||||
TodorooCursor<TaskOutstanding> outstandingWithTitle = null;
|
|
||||||
try {
|
|
||||||
outstandingWithTitle = taskOutstandingDao
|
|
||||||
.query(Query.select(TaskOutstanding.TASK_ID, Task.UUID)
|
|
||||||
.join(Join.left(Task.TABLE, Task.ID.eq(TaskOutstanding.TASK_ID)))
|
|
||||||
.where(Criterion.and(TaskOutstanding.COLUMN_STRING.eq(Task.TITLE.name),
|
|
||||||
Criterion.and(TaskOutstanding.VALUE_STRING.isNotNull(), TaskOutstanding.VALUE_STRING.neq("")))) //$NON-NLS-1$
|
|
||||||
.groupBy(TaskOutstanding.TASK_ID));
|
|
||||||
List<Long> ids = new ArrayList<Long>();
|
|
||||||
List<String> uuids = new ArrayList<String>();
|
|
||||||
for (outstandingWithTitle.moveToFirst(); !outstandingWithTitle.isAfterLast(); outstandingWithTitle.moveToNext()) {
|
|
||||||
try {
|
|
||||||
ids.add(outstandingWithTitle.get(TaskOutstanding.TASK_ID));
|
|
||||||
uuids.add(outstandingWithTitle.get(Task.UUID));
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(ERROR_TAG, "Error reading from cursor", e); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
taskOutstandingDao.deleteWhere(Criterion.and(TaskOutstanding.TASK_ID.in(ids.toArray(new Long[ids.size()])),
|
|
||||||
TaskOutstanding.COLUMN_STRING.eq(Task.TITLE.name),
|
|
||||||
Criterion.or(TaskOutstanding.VALUE_STRING.isNull(), TaskOutstanding.VALUE_STRING.eq("")))); //$NON-NLS-1$
|
|
||||||
|
|
||||||
new ConstructOutstandingTableFromMasterTable<TaskAttachment, TaskAttachmentOutstanding>(NameMaps.TABLE_ID_ATTACHMENTS,
|
|
||||||
taskAttachmentDao, taskAttachmentOutstandingDao, TaskAttachment.CREATED_AT).execute(TaskAttachment.TASK_UUID.in(uuids.toArray(new String[uuids.size()])));
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(ERROR_TAG, "Unhandled exception", e); //$NON-NLS-1$
|
|
||||||
} finally {
|
|
||||||
if (outstandingWithTitle != null) {
|
|
||||||
outstandingWithTitle.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,99 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2012 Todoroo Inc
|
|
||||||
*
|
|
||||||
* See the file "LICENSE" for the full license governing this code.
|
|
||||||
*/
|
|
||||||
package com.todoroo.astrid.helper;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import com.todoroo.andlib.data.TodorooCursor;
|
|
||||||
import com.todoroo.andlib.service.Autowired;
|
|
||||||
import com.todoroo.andlib.service.DependencyInjectionService;
|
|
||||||
import com.todoroo.andlib.sql.Criterion;
|
|
||||||
import com.todoroo.andlib.sql.Functions;
|
|
||||||
import com.todoroo.andlib.sql.Query;
|
|
||||||
import com.todoroo.andlib.utility.Preferences;
|
|
||||||
import com.todoroo.astrid.dao.TaskDao;
|
|
||||||
import com.todoroo.astrid.data.SyncFlags;
|
|
||||||
import com.todoroo.astrid.data.Task;
|
|
||||||
|
|
||||||
public class DueDateTimeMigrator {
|
|
||||||
|
|
||||||
@Autowired TaskDao taskDao;
|
|
||||||
|
|
||||||
private static final String PREF_MIGRATED_DUE_TIMES = "migrated_due_times"; //$NON-NLS-1$
|
|
||||||
private static final String STRFTIME_FORMAT = "%H:%M:%S"; //$NON-NLS-1$
|
|
||||||
private static final String LEGACY_NO_TIME_STRING = "23:59:59"; //$NON-NLS-1$
|
|
||||||
|
|
||||||
public DueDateTimeMigrator() {
|
|
||||||
DependencyInjectionService.getInstance().inject(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private interface TaskDateAdjuster {
|
|
||||||
public void adjust(Date date);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void migrateDueTimes() {
|
|
||||||
if (!Preferences.getBoolean(PREF_MIGRATED_DUE_TIMES, false)) {
|
|
||||||
// Get tasks with due time (i.e. due date != 23:59:59)
|
|
||||||
TodorooCursor<Task> tasksWithDueTime = taskDao.query(Query.select(Task.ID, Task.DUE_DATE, Task.MODIFICATION_DATE).where(
|
|
||||||
Criterion.and(Task.DUE_DATE.gt(0),
|
|
||||||
Functions.strftime(Task.DUE_DATE, STRFTIME_FORMAT).neq(LEGACY_NO_TIME_STRING))));
|
|
||||||
try {
|
|
||||||
|
|
||||||
// Get tasks with no due time (i.e. due date = 23:59:59)
|
|
||||||
TodorooCursor<Task> tasksWithoutDueTime = taskDao.query(Query.select(Task.ID, Task.DUE_DATE, Task.MODIFICATION_DATE).where(
|
|
||||||
Criterion.and(Task.DUE_DATE.gt(0),
|
|
||||||
Functions.strftime(Task.DUE_DATE, STRFTIME_FORMAT).eq(LEGACY_NO_TIME_STRING))));
|
|
||||||
|
|
||||||
tasksWithoutDueTime.getCount();
|
|
||||||
tasksWithDueTime.getCount();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Set tasks without time to 12:00:00
|
|
||||||
processCursor(tasksWithoutDueTime, new TaskDateAdjuster() {
|
|
||||||
@Override
|
|
||||||
public void adjust(Date date) {
|
|
||||||
date.setHours(12);
|
|
||||||
date.setMinutes(0);
|
|
||||||
date.setSeconds(0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
tasksWithoutDueTime.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set tasks with time to have time HH:MM:01
|
|
||||||
processCursor(tasksWithDueTime, new TaskDateAdjuster() {
|
|
||||||
@Override
|
|
||||||
public void adjust(Date date) {
|
|
||||||
date.setSeconds(1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
tasksWithDueTime.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
Preferences.setBoolean(PREF_MIGRATED_DUE_TIMES, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processCursor(TodorooCursor<Task> cursor, TaskDateAdjuster adjuster) {
|
|
||||||
Task curr = new Task();
|
|
||||||
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
|
|
||||||
curr.readFromCursor(cursor);
|
|
||||||
long time = curr.getValue(Task.DUE_DATE) / 1000L * 1000L;
|
|
||||||
Date date = new Date(time);
|
|
||||||
adjuster.adjust(date);
|
|
||||||
curr.setValue(Task.DUE_DATE, date.getTime());
|
|
||||||
curr.getSetValues().put(Task.MODIFICATION_DATE.name, curr.getValue(Task.MODIFICATION_DATE)); // Don't change modification date
|
|
||||||
curr.putTransitory(SyncFlags.ACTFM_SUPPRESS_OUTSTANDING_ENTRIES, true);
|
|
||||||
curr.putTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC, true);
|
|
||||||
taskDao.save(curr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,126 +0,0 @@
|
|||||||
package com.todoroo.astrid.subtasks;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.todoroo.andlib.data.TodorooCursor;
|
|
||||||
import com.todoroo.andlib.service.Autowired;
|
|
||||||
import com.todoroo.andlib.service.DependencyInjectionService;
|
|
||||||
import com.todoroo.andlib.sql.Functions;
|
|
||||||
import com.todoroo.andlib.sql.Order;
|
|
||||||
import com.todoroo.andlib.sql.Query;
|
|
||||||
import com.todoroo.andlib.utility.Preferences;
|
|
||||||
import com.todoroo.astrid.actfm.sync.ActFmPreferenceService;
|
|
||||||
import com.todoroo.astrid.actfm.sync.ActFmSyncService;
|
|
||||||
import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria;
|
|
||||||
import com.todoroo.astrid.data.Metadata;
|
|
||||||
import com.todoroo.astrid.data.TagData;
|
|
||||||
import com.todoroo.astrid.service.MetadataService;
|
|
||||||
import com.todoroo.astrid.service.TagDataService;
|
|
||||||
import com.todoroo.astrid.subtasks.AstridOrderedListUpdater.Node;
|
|
||||||
|
|
||||||
public class SubtasksMetadataMigration {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TagDataService tagDataService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private MetadataService metadataService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ActFmPreferenceService actFmPreferenceService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ActFmSyncService actFmSyncService;
|
|
||||||
|
|
||||||
public SubtasksMetadataMigration() {
|
|
||||||
DependencyInjectionService.getInstance().inject(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void performMigration() {
|
|
||||||
TodorooCursor<Metadata> subtasksMetadata = metadataService.query(Query.select(Metadata.PROPERTIES)
|
|
||||||
.where(MetadataCriteria.withKey(SubtasksMetadata.METADATA_KEY))
|
|
||||||
.orderBy(Order.asc(SubtasksMetadata.TAG), Order.asc(Functions.cast(SubtasksMetadata.ORDER, "LONG")))); //$NON-NLS-1$
|
|
||||||
try {
|
|
||||||
Metadata m = new Metadata();
|
|
||||||
for (subtasksMetadata.moveToFirst(); !subtasksMetadata.isAfterLast(); subtasksMetadata.moveToNext()) {
|
|
||||||
m.readFromCursor(subtasksMetadata);
|
|
||||||
String tag = m.getValue(SubtasksMetadata.TAG);
|
|
||||||
processTag(tag, subtasksMetadata);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
subtasksMetadata.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processTag(String tag, TodorooCursor<Metadata> subtasksMetadata) {
|
|
||||||
Metadata item = new Metadata();
|
|
||||||
TagData td = null;
|
|
||||||
try {
|
|
||||||
if (!SubtasksMetadata.LIST_ACTIVE_TASKS.equals(tag)) {
|
|
||||||
String idString = tag.replace("td:", "");
|
|
||||||
long id = Long.parseLong(idString);
|
|
||||||
td = tagDataService.fetchById(id, TagData.ID);
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
Log.e("subtasks-migration", "Could not parse tag id from " + tag, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (td == null && !SubtasksMetadata.LIST_ACTIVE_TASKS.equals(tag)) {
|
|
||||||
for (; !subtasksMetadata.isAfterLast(); subtasksMetadata.moveToNext()) {
|
|
||||||
item.readFromCursor(subtasksMetadata);
|
|
||||||
if (!item.getValue(SubtasksMetadata.TAG).equals(tag)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
String newTree = buildTreeModelFromMetadata(tag, subtasksMetadata);
|
|
||||||
if (td != null) {
|
|
||||||
td.setValue(TagData.TAG_ORDERING, newTree);
|
|
||||||
tagDataService.save(td);
|
|
||||||
} else {
|
|
||||||
Preferences.setString(SubtasksUpdater.ACTIVE_TASKS_ORDER, newTree);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
subtasksMetadata.moveToPrevious(); // Move back one to undo the last iteration of the for loop
|
|
||||||
}
|
|
||||||
|
|
||||||
private String buildTreeModelFromMetadata(String tag, TodorooCursor<Metadata> cursor) {
|
|
||||||
Metadata item = new Metadata();
|
|
||||||
Node root = new Node("-1", null, -1); //$NON-NLS-1$
|
|
||||||
for (; !cursor.isAfterLast(); cursor.moveToNext()) {
|
|
||||||
item.clear();
|
|
||||||
item.readFromCursor(cursor);
|
|
||||||
if (!item.getValue(SubtasksMetadata.TAG).equals(tag)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int indent = 0;
|
|
||||||
if (item.containsNonNullValue(SubtasksMetadata.INDENT)) {
|
|
||||||
Integer i = item.getValue(SubtasksMetadata.INDENT);
|
|
||||||
if (i != null) {
|
|
||||||
indent = i.intValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Node parent = findNextParentForIndent(root, indent);
|
|
||||||
Node newNode = new Node(item.getValue(Metadata.TASK).toString(), parent, parent.indent + 1);
|
|
||||||
parent.children.add(newNode);
|
|
||||||
}
|
|
||||||
return AstridOrderedListUpdater.serializeTree(root);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Node findNextParentForIndent(Node root, int indent) {
|
|
||||||
if (indent <= 0) {
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<Node> children = root.children;
|
|
||||||
if (children.size() == 0) {
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
return findNextParentForIndent(children.get(children.size() - 1), indent - 1);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,182 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2012 Todoroo Inc
|
|
||||||
*
|
|
||||||
* See the file "LICENSE" for the full license governing this code.
|
|
||||||
*/
|
|
||||||
package com.todoroo.astrid.tags;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import com.todoroo.andlib.data.TodorooCursor;
|
|
||||||
import com.todoroo.andlib.service.Autowired;
|
|
||||||
import com.todoroo.andlib.service.DependencyInjectionService;
|
|
||||||
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.Preferences;
|
|
||||||
import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria;
|
|
||||||
import com.todoroo.astrid.data.Metadata;
|
|
||||||
import com.todoroo.astrid.data.TagData;
|
|
||||||
import com.todoroo.astrid.data.Task;
|
|
||||||
import com.todoroo.astrid.service.MetadataService;
|
|
||||||
import com.todoroo.astrid.service.TagDataService;
|
|
||||||
import com.todoroo.astrid.service.TaskService;
|
|
||||||
import com.todoroo.astrid.utility.Flags;
|
|
||||||
|
|
||||||
public class TagCaseMigrator {
|
|
||||||
|
|
||||||
@Autowired TaskService taskService;
|
|
||||||
@Autowired TagDataService tagDataService;
|
|
||||||
@Autowired MetadataService metadataService;
|
|
||||||
|
|
||||||
public static final String PREF_SHOW_MIGRATION_ALERT = "tag_case_migration_alert"; //$NON-NLS-1$
|
|
||||||
private static final String PREF_CASE_MIGRATION_PERFORMED = "tag_case_migration"; //$NON-NLS-1$
|
|
||||||
|
|
||||||
public TagCaseMigrator() {
|
|
||||||
DependencyInjectionService.getInstance().inject(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final HashMap<String, String> renameMap = new HashMap<String, String>();
|
|
||||||
private final HashMap<String, Long> nameToRemoteId = new HashMap<String, Long>();
|
|
||||||
private final HashMap<String, Integer> nameCountMap = new HashMap<String, Integer>();
|
|
||||||
|
|
||||||
public void performTagCaseMigration(Context context) {
|
|
||||||
if (!Preferences.getBoolean(PREF_CASE_MIGRATION_PERFORMED, false)) {
|
|
||||||
TagService.Tag[] allTagData = TagService.getInstance().getGroupedTags(
|
|
||||||
TagService.GROUPED_TAGS_BY_ALPHA, Criterion.all);
|
|
||||||
|
|
||||||
boolean shouldShowDialog = false;
|
|
||||||
for (int i = 0; i < allTagData.length - 1; i++) {
|
|
||||||
TagService.Tag first = allTagData[i];
|
|
||||||
TagService.Tag second = allTagData[i+1];
|
|
||||||
|
|
||||||
if (first.tag.equalsIgnoreCase(second.tag)) {
|
|
||||||
shouldShowDialog = true;
|
|
||||||
markForRenaming(first.tag, Long.parseLong(first.uuid));
|
|
||||||
markForRenaming(second.tag, Long.parseLong(second.uuid));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String key : renameMap.keySet()) {
|
|
||||||
renameCaseSensitive(key, renameMap.get(key));
|
|
||||||
updateTagData(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
Preferences.setBoolean(PREF_CASE_MIGRATION_PERFORMED, true);
|
|
||||||
Preferences.setBoolean(PREF_SHOW_MIGRATION_ALERT, shouldShowDialog);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String targetNameForTag(String tag) {
|
|
||||||
String targetName = tag.toLowerCase();
|
|
||||||
targetName = targetName.substring(0, 1).toUpperCase() + targetName.substring(1);
|
|
||||||
return targetName;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void markForRenaming(String tag, long remoteId) {
|
|
||||||
if (renameMap.containsKey(tag)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String targetName = targetNameForTag(tag);
|
|
||||||
|
|
||||||
int suffix = 1;
|
|
||||||
if (nameCountMap.containsKey(targetName)) {
|
|
||||||
suffix = nameCountMap.get(targetName);
|
|
||||||
}
|
|
||||||
|
|
||||||
String newName = targetName + "_" + suffix; //$NON-NLS-1$
|
|
||||||
nameCountMap.put(targetName, suffix + 1);
|
|
||||||
renameMap.put(tag, newName);
|
|
||||||
nameToRemoteId.put(tag, remoteId);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateTagData(String tag) {
|
|
||||||
long remoteId = nameToRemoteId.get(tag);
|
|
||||||
TodorooCursor<TagData> tagData = tagDataService.query(Query.select(TagData.NAME, TagData.UUID)
|
|
||||||
.where(Criterion.and(
|
|
||||||
TagData.NAME.eq(tag), TagData.UUID.eq(remoteId))));
|
|
||||||
try {
|
|
||||||
for (tagData.moveToFirst(); !tagData.isAfterLast(); tagData.moveToNext()) {
|
|
||||||
TagData curr = new TagData(tagData);
|
|
||||||
curr.setValue(TagData.NAME, renameMap.get(tag));
|
|
||||||
tagDataService.save(curr);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
tagData.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
addTasksToTargetTag(renameMap.get(tag), targetNameForTag(tag));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
private static Criterion tagEq(String tag, Criterion additionalCriterion) {
|
|
||||||
return Criterion.and(
|
|
||||||
MetadataCriteria.withKey(TaskToTagMetadata.KEY), TaskToTagMetadata.TAG_NAME.eq(tag),
|
|
||||||
additionalCriterion);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addTasksToTargetTag(String tag, String target) {
|
|
||||||
TodorooCursor<Task> tasks = taskService.query(Query.select(Task.ID).join(Join.inner(Metadata.TABLE,
|
|
||||||
Task.ID.eq(Metadata.TASK))).where(tagEq(tag, Criterion.all)));
|
|
||||||
try {
|
|
||||||
for (tasks.moveToFirst(); !tasks.isAfterLast(); tasks.moveToNext()) {
|
|
||||||
Task curr = new Task(tasks);
|
|
||||||
TodorooCursor<Metadata> tagMetadata = metadataService.query(Query.select(TaskToTagMetadata.TAG_NAME)
|
|
||||||
.where(Criterion.and(TaskToTagMetadata.TAG_NAME.eq(target), Metadata.KEY.eq(TaskToTagMetadata.KEY), Metadata.TASK.eq(curr.getId()))));
|
|
||||||
try {
|
|
||||||
if (tagMetadata.getCount() == 0) {
|
|
||||||
Metadata newTag = new Metadata();
|
|
||||||
newTag.setValue(Metadata.KEY, TaskToTagMetadata.KEY);
|
|
||||||
newTag.setValue(Metadata.TASK, curr.getId());
|
|
||||||
newTag.setValue(TaskToTagMetadata.TAG_NAME, target);
|
|
||||||
metadataService.save(newTag);
|
|
||||||
} // else already exists for some weird reason
|
|
||||||
} finally {
|
|
||||||
tagMetadata.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
tasks.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
private int renameCaseSensitive(String oldTag, String newTag) { // Need this for tag case migration process
|
|
||||||
return renameHelper(oldTag, newTag, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
private int renameHelper(String oldTag, String newTag, boolean caseSensitive) {
|
|
||||||
// First remove newTag from all tasks that have both oldTag and newTag.
|
|
||||||
metadataService.deleteWhere(
|
|
||||||
Criterion.and(
|
|
||||||
Metadata.VALUE1.eq(newTag),
|
|
||||||
Metadata.TASK.in(rowsWithTag(oldTag, Metadata.TASK))));
|
|
||||||
|
|
||||||
// Then rename all instances of oldTag to newTag.
|
|
||||||
Metadata metadata = new Metadata();
|
|
||||||
metadata.setValue(TaskToTagMetadata.TAG_NAME, newTag);
|
|
||||||
int ret;
|
|
||||||
if (caseSensitive) {
|
|
||||||
ret = metadataService.update(tagEq(oldTag, Criterion.all), metadata);
|
|
||||||
} else {
|
|
||||||
ret = metadataService.update(TagService.tagEqIgnoreCase(oldTag, Criterion.all), metadata);
|
|
||||||
}
|
|
||||||
invalidateTaskCache(newTag);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Query rowsWithTag(String tag, Field... projections) {
|
|
||||||
return Query.select(projections).from(Metadata.TABLE).where(Metadata.VALUE1.eq(tag));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void invalidateTaskCache(String tag) {
|
|
||||||
taskService.clearDetails(Task.ID.in(rowsWithTag(tag, Task.ID)));
|
|
||||||
Flags.set(Flags.REFRESH);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue