diff --git a/app/schemas/com.todoroo.astrid.dao.Database/41.json b/app/schemas/com.todoroo.astrid.dao.Database/41.json new file mode 100644 index 000000000..6c366194f --- /dev/null +++ b/app/schemas/com.todoroo.astrid.dao.Database/41.json @@ -0,0 +1,172 @@ +{ + "formatVersion": 1, + "database": { + "version": 41, + "identityHash": "c6760f6f6fe7d106e61239bfa9189694", + "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": [] + } + ], + "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, \"c6760f6f6fe7d106e61239bfa9189694\")" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/com/todoroo/andlib/data/Property.java b/app/src/main/java/com/todoroo/andlib/data/Property.java index 04ef6312b..defaa2ca0 100644 --- a/app/src/main/java/com/todoroo/andlib/data/Property.java +++ b/app/src/main/java/com/todoroo/andlib/data/Property.java @@ -45,8 +45,6 @@ public abstract class Property extends Field implements Cloneable { public static final int PROP_FLAG_DATE = 1 << 1; /** Is this field a serialized JSON object? */ public static final int PROP_FLAG_JSON = 1 << 4; - /** Is this field for pictures? (usually as a json object containing "path" key or urls) */ - public static final int PROP_FLAG_PICTURE = 1 << 5; private int flags = 0; diff --git a/app/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java b/app/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java index 2a910e5f6..f3922354a 100755 --- a/app/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java +++ b/app/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java @@ -337,7 +337,7 @@ public final class TaskEditFragment extends InjectingFragment implements Toolbar userActivity.setMessage(message); userActivity.setAction(actionCode); userActivity.setTargetId(model.getUuid()); - userActivity.setCreatedAt(DateUtilities.now()); + userActivity.setCreated(DateUtilities.now()); if (picture != null) { userActivity.setPicture(picture); } 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 9cc075744..70da40d2a 100755 --- a/app/src/main/java/com/todoroo/astrid/backup/TasksXmlExporter.java +++ b/app/src/main/java/com/todoroo/astrid/backup/TasksXmlExporter.java @@ -199,7 +199,7 @@ public class TasksXmlExporter { private void writeComment(UserActivity userActivity) { try { xml.startTag(null, BackupConstants.COMMENT_TAG); - serializeModel(userActivity, UserActivity.PROPERTIES, Metadata.ID, Metadata.TASK); + userActivity.writeToXml(new XmlWriter(xml)); xml.endTag(null, BackupConstants.COMMENT_TAG); } catch (IOException e) { // ignore 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 e21de8ad3..817405f9c 100755 --- a/app/src/main/java/com/todoroo/astrid/backup/TasksXmlImporter.java +++ b/app/src/main/java/com/todoroo/astrid/backup/TasksXmlImporter.java @@ -156,7 +156,6 @@ public class TasksXmlImporter { XmlPullParser xpp; final Task currentTask = new Task(); - final UserActivity userActivity = new UserActivity(); final Metadata metadata = new Metadata(); public Format2TaskImporter() { } @@ -225,18 +224,8 @@ public class TasksXmlImporter { if (!currentTask.isSaved()) { return; } - userActivity.clear(); - - // We only want to import these fields. - // These are the fields that are sent in EditNoteActivity.addComment() when a user creates a comment. - final Property[] NEW_PROPERTIES = new Property[4]; - NEW_PROPERTIES[0] = UserActivity.MESSAGE; - NEW_PROPERTIES[1] = UserActivity.ACTION; - NEW_PROPERTIES[2] = UserActivity.TARGET_ID; - NEW_PROPERTIES[3] = UserActivity.CREATED_AT; - deserializeModel(userActivity, NEW_PROPERTIES); - - userActivity.setId(UserActivity.NO_ID); + + UserActivity userActivity = new UserActivity(new XmlReader(xpp)); userActivityDao.createNew(userActivity); } 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 272fb4570..193a9e028 100644 --- a/app/src/main/java/com/todoroo/astrid/dao/Database.java +++ b/app/src/main/java/com/todoroo/astrid/dao/Database.java @@ -39,13 +39,15 @@ import timber.log.Timber; @android.arch.persistence.room.Database( entities = { Notification.class, - TagData.class + TagData.class, + UserActivity.class }, - version = 40) + version = 41) public abstract class Database extends RoomDatabase { public abstract NotificationDao notificationDao(); public abstract TagDataDao getTagDataDao(); + public abstract UserActivityDao getUserActivityDao(); public static final String NAME = "database"; @@ -53,7 +55,6 @@ public abstract class Database extends RoomDatabase { Task.TABLE, Metadata.TABLE, StoreObject.TABLE, - UserActivity.TABLE, TaskAttachment.TABLE, TaskListMetadata.TABLE, }; @@ -67,8 +68,6 @@ public abstract class Database extends RoomDatabase { return NAME; } - - public Database setOnDatabaseUpdated(Runnable onDatabaseUpdated) { this.onDatabaseUpdated = onDatabaseUpdated; return this; diff --git a/app/src/main/java/com/todoroo/astrid/dao/UserActivityDao.java b/app/src/main/java/com/todoroo/astrid/dao/UserActivityDao.java index e2edb67de..bb9b7d422 100644 --- a/app/src/main/java/com/todoroo/astrid/dao/UserActivityDao.java +++ b/app/src/main/java/com/todoroo/astrid/dao/UserActivityDao.java @@ -1,36 +1,32 @@ package com.todoroo.astrid.dao; -import com.todoroo.andlib.sql.Criterion; -import com.todoroo.andlib.sql.Order; -import com.todoroo.andlib.sql.Query; +import android.arch.persistence.room.Dao; +import android.arch.persistence.room.Insert; +import android.arch.persistence.room.Query; + import com.todoroo.andlib.utility.DateUtilities; +import com.todoroo.astrid.data.RemoteModel; import com.todoroo.astrid.data.UserActivity; +import com.todoroo.astrid.helper.UUIDHelper; import java.util.List; -import javax.inject.Inject; - -public class UserActivityDao { +@Dao +public abstract class UserActivityDao { - private final RemoteModelDao dao; + @Insert + public abstract void insert(UserActivity userActivity); - @Inject - public UserActivityDao(Database database) { - dao = new RemoteModelDao<>(database, UserActivity.class); - } + @Query("SELECT * FROM userActivity WHERE `action` = 'task_comment' AND target_id = :taskUuid AND deleted_at = 0 ORDER BY created_at DESC ") + public abstract List getCommentsForTask(String taskUuid); public void createNew(UserActivity item) { - if (!item.containsValue(UserActivity.CREATED_AT)) { - item.setCreatedAt(DateUtilities.now()); + if (item.getCreated() == null || item.getCreated() == 0L) { + item.setCreated(DateUtilities.now()); } - dao.createNew(item); - } - - public List getCommentsForTask(String taskUuid) { - return dao.toList(Query.select(UserActivity.PROPERTIES).where( - Criterion.and(UserActivity.ACTION.eq(UserActivity.ACTION_TASK_COMMENT), - UserActivity.TARGET_ID.eq(taskUuid), - UserActivity.DELETED_AT.eq(0))) - .orderBy(Order.desc(UserActivity.CREATED_AT))); + if (RemoteModel.isUuidEmpty(item.getRemoteId())) { + item.setRemoteId(UUIDHelper.newUUID()); + } + insert(item); } } diff --git a/app/src/main/java/com/todoroo/astrid/data/UserActivity.java b/app/src/main/java/com/todoroo/astrid/data/UserActivity.java index 3e5e4343c..72f3059f1 100644 --- a/app/src/main/java/com/todoroo/astrid/data/UserActivity.java +++ b/app/src/main/java/com/todoroo/astrid/data/UserActivity.java @@ -1,124 +1,176 @@ package com.todoroo.astrid.data; -import android.content.ContentValues; +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 android.net.Uri; +import android.os.Parcel; +import android.os.Parcelable; -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; +import org.tasks.backup.XmlReader; +import org.tasks.backup.XmlWriter; -public class UserActivity extends RemoteModel { +@Entity(tableName = "userActivity") +public class UserActivity implements Parcelable { - // --- table - - /** table for this model */ - public static final Table TABLE = new Table("userActivity", UserActivity.class); - - // --- properties + public static final String ACTION_TASK_COMMENT = "task_comment"; - /** ID */ - @SuppressWarnings("WeakerAccess") - public static final LongProperty ID = new LongProperty( - TABLE, ID_PROPERTY_NAME); + @PrimaryKey(autoGenerate = true) + @ColumnInfo(name = "_id") + private Long id; - /** Remote ID */ - @SuppressWarnings("WeakerAccess") - public static final StringProperty UUID = new StringProperty( - TABLE, UUID_PROPERTY_NAME); + @ColumnInfo(name = "remoteId") + private String remoteId = RemoteModel.NO_UUID; - /** Action */ - public static final StringProperty ACTION = new StringProperty( - TABLE, "action"); + @ColumnInfo(name = "action") + private String action = ""; - /** Message */ - @SuppressWarnings("WeakerAccess") - public static final StringProperty MESSAGE = new StringProperty( - TABLE, "message"); + @ColumnInfo(name = "message") + private String message = ""; - /** Picture */ - @SuppressWarnings("WeakerAccess") - public static final StringProperty PICTURE = new StringProperty( - TABLE, "picture", Property.PROP_FLAG_JSON | Property.PROP_FLAG_PICTURE); + @ColumnInfo(name = "picture") + private String picture = ""; - /** Target id */ - public static final StringProperty TARGET_ID = new StringProperty( - TABLE, "target_id"); + @ColumnInfo(name = "target_id") + private String targetId = RemoteModel.NO_UUID; - /** Created at */ - public static final LongProperty CREATED_AT = new LongProperty( - TABLE, "created_at", Property.PROP_FLAG_DATE); + @ColumnInfo(name = "created_at") + private Long created = 0L; - /** Deleted at */ - public static final LongProperty DELETED_AT = new LongProperty( - TABLE, "deleted_at", Property.PROP_FLAG_DATE); + @ColumnInfo(name = "deleted_at") + private Long deleted = 0L; public UserActivity() { - super(); } - // --- Action codes - public static final String ACTION_TASK_COMMENT = "task_comment"; - - // --- helpers + @Ignore + public UserActivity(XmlReader reader) { + reader.readString("remoteId", this::setRemoteId); + reader.readString("action", this::setAction); + reader.readString("message", this::setMessage); + reader.readString("picture", this::setPicture); + reader.readString("target_id", this::setTargetId); + reader.readLong("created_at", this::setCreated); + reader.readLong("deleted_at", this::setDeleted); + } - /** Default values container */ - private static final ContentValues defaultValues = new ContentValues(); + @Ignore + private UserActivity(Parcel parcel) { + id = parcel.readLong(); + remoteId = parcel.readString(); + action = parcel.readString(); + message = parcel.readString(); + picture = parcel.readString(); + targetId = parcel.readString(); + created = parcel.readLong(); + deleted = parcel.readLong(); + } - @Override - public ContentValues getDefaultValues() { - return defaultValues; + public void writeToXml(XmlWriter writer) { + writer.writeString("remoteId", remoteId); + writer.writeString("action", action); + writer.writeString("message", message); + writer.writeString("picture", picture); + writer.writeString("target_id", targetId); + writer.writeLong("created_at", created); + writer.writeLong("deleted_at", deleted); } - static { - defaultValues.put(UUID.name, NO_UUID); - defaultValues.put(ACTION.name, ""); - defaultValues.put(MESSAGE.name, ""); - defaultValues.put(PICTURE.name, ""); - defaultValues.put(TARGET_ID.name, NO_UUID); - defaultValues.put(CREATED_AT.name, 0L); - defaultValues.put(DELETED_AT.name, 0L); + public Long getId() { + return id; } - /** List of all properties for this model */ - public static final Property[] PROPERTIES = generateProperties(UserActivity.class); + public void setId(Long id) { + this.id = id; + } - @Override - public long getId() { - return getIdHelper(ID); + public String getRemoteId() { + return remoteId; } - private static final Creator CREATOR = new ModelCreator<>(UserActivity.class); + public void setRemoteId(String remoteId) { + this.remoteId = remoteId; + } - public Long getCreatedAt() { - return getValue(CREATED_AT); + public String getAction() { + return action; } - public void setCreatedAt(Long createdAt) { - setValue(CREATED_AT, createdAt); + public void setAction(String action) { + this.action = action; } public String getMessage() { - return getValue(MESSAGE); + return message; } public void setMessage(String message) { - setValue(MESSAGE, message); + this.message = message; + } + + public String getPicture() { + return picture; + } + + public void setPicture(String picture) { + this.picture = picture; + } + + public String getTargetId() { + return targetId; } public void setTargetId(String targetId) { - setValue(TARGET_ID, targetId); + this.targetId = targetId; } - public void setAction(String action) { - setValue(ACTION, action); + public Long getCreated() { + return created; } - public void setPicture(String picture) { - setValue(PICTURE, picture); + public void setCreated(Long created) { + this.created = created; + } + + public Long getDeleted() { + return deleted; + } + + public void setDeleted(Long deleted) { + this.deleted = deleted; } public Uri getPictureUri() { - return PictureHelper.getPictureUri(getValue(PICTURE)); + return RemoteModel.PictureHelper.getPictureUri(picture); + } + + public static final Creator CREATOR = new Creator() { + @Override + public UserActivity createFromParcel(Parcel source) { + return new UserActivity(source); + } + + @Override + public UserActivity[] newArray(int size) { + return new UserActivity[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeLong(id); + dest.writeString(remoteId); + dest.writeString(action); + dest.writeString(message); + dest.writeString(picture); + dest.writeString(targetId); + dest.writeLong(created); + dest.writeLong(deleted); } } diff --git a/app/src/main/java/com/todoroo/astrid/notes/CommentsController.java b/app/src/main/java/com/todoroo/astrid/notes/CommentsController.java index ff0315402..f5d8de5b5 100644 --- a/app/src/main/java/com/todoroo/astrid/notes/CommentsController.java +++ b/app/src/main/java/com/todoroo/astrid/notes/CommentsController.java @@ -104,7 +104,7 @@ public class CommentsController { // date final TextView date = view.findViewById(R.id.date); - date.setText(DateUtilities.getLongDateStringWithTime(activity, item.getCreatedAt())); + date.setText(DateUtilities.getLongDateStringWithTime(activity, item.getCreated())); // picture final ImageView commentPictureView = view.findViewById(R.id.comment_picture); diff --git a/app/src/main/java/org/tasks/db/Migrations.java b/app/src/main/java/org/tasks/db/Migrations.java index 55d59a5ab..1b5a9e5cb 100644 --- a/app/src/main/java/org/tasks/db/Migrations.java +++ b/app/src/main/java/org/tasks/db/Migrations.java @@ -51,12 +51,20 @@ public class Migrations { } }; + private static final Migration MIGRATION_40_41 = new Migration(40, 41) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase database) { + + } + }; + public static Migration[] MIGRATIONS = new Migration[] { MIGRATION_35_36, MIGRATION_36_37, MIGRATION_37_38, MIGRATION_38_39, - MIGRATION_39_40 + MIGRATION_39_40, + MIGRATION_40_41 }; public static RoomDatabase.Callback ON_CREATE = new RoomDatabase.Callback() { diff --git a/app/src/main/java/org/tasks/injection/ApplicationModule.java b/app/src/main/java/org/tasks/injection/ApplicationModule.java index 425a9c47f..791b341f5 100644 --- a/app/src/main/java/org/tasks/injection/ApplicationModule.java +++ b/app/src/main/java/org/tasks/injection/ApplicationModule.java @@ -5,6 +5,7 @@ import android.content.Context; import com.todoroo.astrid.dao.Database; import com.todoroo.astrid.dao.TagDataDao; +import com.todoroo.astrid.dao.UserActivityDao; import com.todoroo.astrid.provider.Astrid2TaskProvider; import org.tasks.ErrorReportingSingleThreadExecutor; @@ -67,4 +68,9 @@ public class ApplicationModule { public TagDataDao getTagDataDao(Database database) { return database.getTagDataDao(); } + + @Provides + public UserActivityDao getUserActivityDao(Database database) { + return database.getUserActivityDao(); + } }