Move cd_order to task table

pull/2146/head
Alex Baker 2 years ago
parent 2006e2c84b
commit ac62b4f385

@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 88,
"identityHash": "8ddd120bc22139ab9c9d69dbc727df37",
"identityHash": "2b5bd6d7c523006b902d035f71093be2",
"entities": [
{
"tableName": "notification",
@ -254,7 +254,7 @@
},
{
"tableName": "tasks",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `importance` INTEGER NOT NULL, `dueDate` INTEGER NOT NULL, `hideUntil` INTEGER NOT NULL, `created` INTEGER NOT NULL, `modified` INTEGER NOT NULL, `completed` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `notes` TEXT, `estimatedSeconds` INTEGER NOT NULL, `elapsedSeconds` INTEGER NOT NULL, `timerStart` INTEGER NOT NULL, `notificationFlags` INTEGER NOT NULL, `lastNotified` INTEGER NOT NULL, `recurrence` TEXT, `repeat_from` INTEGER NOT NULL DEFAULT 0, `calendarUri` TEXT, `remoteId` TEXT, `collapsed` INTEGER NOT NULL, `parent` INTEGER NOT NULL, `read_only` INTEGER NOT NULL DEFAULT 0)",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `importance` INTEGER NOT NULL, `dueDate` INTEGER NOT NULL, `hideUntil` INTEGER NOT NULL, `created` INTEGER NOT NULL, `modified` INTEGER NOT NULL, `completed` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `notes` TEXT, `estimatedSeconds` INTEGER NOT NULL, `elapsedSeconds` INTEGER NOT NULL, `timerStart` INTEGER NOT NULL, `notificationFlags` INTEGER NOT NULL, `lastNotified` INTEGER NOT NULL, `recurrence` TEXT, `repeat_from` INTEGER NOT NULL DEFAULT 0, `calendarUri` TEXT, `remoteId` TEXT, `collapsed` INTEGER NOT NULL, `parent` INTEGER NOT NULL, `order` INTEGER, `read_only` INTEGER NOT NULL DEFAULT 0)",
"fields": [
{
"fieldPath": "id",
@ -383,6 +383,12 @@
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "order",
"columnName": "order",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "readOnly",
"columnName": "read_only",
@ -1303,7 +1309,7 @@
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '8ddd120bc22139ab9c9d69dbc727df37')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '2b5bd6d7c523006b902d035f71093be2')"
]
}
}

@ -11,13 +11,7 @@ import com.todoroo.astrid.data.Task
import com.todoroo.astrid.data.Task.Companion.HIDE_UNTIL_SPECIFIC_DAY
import org.tasks.BuildConfig
import org.tasks.LocalBroadcastManager
import org.tasks.data.CaldavDao
import org.tasks.data.CaldavTask
import org.tasks.data.GoogleTask
import org.tasks.data.GoogleTaskDao
import org.tasks.data.SubsetCaldav
import org.tasks.data.SubsetGoogleTask
import org.tasks.data.TaskContainer
import org.tasks.data.*
import org.tasks.date.DateTimeUtils.toAppleEpoch
import org.tasks.date.DateTimeUtils.toDateTime
import org.tasks.tasklist.SectionedDataSource.Companion.HEADER_COMPLETED
@ -279,7 +273,7 @@ open class TaskAdapter(
caldavTask.cd_calendar = list
caldavTask.cd_remote_parent = parentTask.remoteId
}
caldavTask.cd_order = if (newTasksOnTop) {
task.task.order = if (newTasksOnTop) {
caldavDao.findFirstTask(list, newParentId)
?.takeIf { task.creationDate.toAppleEpoch() >= it}
?.minus(1)
@ -290,13 +284,13 @@ open class TaskAdapter(
}
if (caldavTask.cd_id == 0L) {
val newTask = CaldavTask(task.id, list)
newTask.order = caldavTask.cd_order
newTask.remoteParent = caldavTask.cd_remote_parent
caldavTask.cd_id = caldavDao.insert(newTask)
task.caldavTask = caldavTask
} else {
caldavDao.update(caldavTask)
}
taskDao.setOrder(task.id, task.task.order)
taskDao.setParent(newParentId, listOf(task.id))
taskDao.touch(task.id)
localBroadcastManager.broadcastRefresh()

@ -39,7 +39,7 @@ public class SortHelper {
public static final long APPLE_EPOCH = 978307200000L; // 1/1/2001 GMT
@SuppressLint("DefaultLocale")
public static final String CALDAV_ORDER_COLUMN =
String.format("IFNULL(caldav_tasks.cd_order, (tasks.created - %d) / 1000)", APPLE_EPOCH);
String.format("IFNULL(tasks.`order`, (tasks.created - %d) / 1000)", APPLE_EPOCH);
private static final String ADJUSTED_DUE_DATE =
"(CASE WHEN (dueDate / 1000) % 60 > 0 THEN dueDate ELSE (dueDate + 43140000) END)";

@ -69,6 +69,8 @@ class TaskDao @Inject constructor(
syncAdapters.sync()
}
suspend fun setOrder(taskId: Long, order: Long?) = taskDao.setOrder(taskId, order)
suspend fun setParent(parent: Long, tasks: List<Long>) = taskDao.setParent(parent, tasks)
suspend fun getChildren(ids: List<Long>) = taskDao.getChildren(ids)

@ -103,6 +103,9 @@ class Task : Parcelable {
@Transient
var parent = 0L
@ColumnInfo(name = "order")
var order: Long? = null
@ColumnInfo(name = "read_only", defaultValue = "0")
var readOnly: Boolean = false
@ -136,6 +139,7 @@ class Task : Parcelable {
isCollapsed = ParcelCompat.readBoolean(parcel)
parent = parcel.readLong()
readOnly = ParcelCompat.readBoolean(parcel)
order = ParcelCompat.readSerializable(parcel, Long::class.java.classLoader, Long::class.java)
}
var uuid: String
@ -270,6 +274,7 @@ class Task : Parcelable {
ParcelCompat.writeBoolean(dest, isCollapsed)
dest.writeLong(parent)
ParcelCompat.writeBoolean(dest, readOnly)
dest.writeSerializable(order)
}
fun insignificantChange(task: Task?): Boolean {
@ -295,6 +300,7 @@ class Task : Parcelable {
&& calendarURI == task.calendarURI
&& parent == task.parent
&& remoteId == task.remoteId
&& order == task.order
}
fun googleTaskUpToDate(original: Task?): Boolean {
@ -309,6 +315,7 @@ class Task : Parcelable {
&& deletionDate == original.deletionDate
&& parent == original.parent
&& notes == original.notes
&& order == original.order
}
fun caldavUpToDate(original: Task?): Boolean {
@ -327,6 +334,7 @@ class Task : Parcelable {
&& recurrence == original.recurrence
&& parent == original.parent
&& isCollapsed == original.isCollapsed
&& order == original.order
}
val isSaved: Boolean
@ -414,6 +422,7 @@ class Task : Parcelable {
if (parent != other.parent) return false
if (transitoryData != other.transitoryData) return false
if (readOnly != other.readOnly) return false
if (order != other.order) return false
return true
}
@ -441,11 +450,12 @@ class Task : Parcelable {
result = 31 * result + parent.hashCode()
result = 31 * result + (transitoryData?.hashCode() ?: 0)
result = 31 * result + readOnly.hashCode()
result = 31 * result + order.hashCode()
return result
}
override fun toString(): String {
return "Task(id=$id, title=$title, priority=$priority, dueDate=$dueDate, hideUntil=$hideUntil, creationDate=$creationDate, modificationDate=$modificationDate, completionDate=$completionDate, deletionDate=$deletionDate, notes=$notes, estimatedSeconds=$estimatedSeconds, elapsedSeconds=$elapsedSeconds, timerStart=$timerStart, ringFlags=$ringFlags, reminderLast=$reminderLast, recurrence=$recurrence, calendarURI=$calendarURI, remoteId='$remoteId', isCollapsed=$isCollapsed, parent=$parent, transitoryData=$transitoryData, readOnly=$readOnly)"
return "Task(id=$id, title=$title, priority=$priority, dueDate=$dueDate, hideUntil=$hideUntil, creationDate=$creationDate, modificationDate=$modificationDate, completionDate=$completionDate, deletionDate=$deletionDate, notes=$notes, estimatedSeconds=$estimatedSeconds, elapsedSeconds=$elapsedSeconds, timerStart=$timerStart, ringFlags=$ringFlags, reminderLast=$reminderLast, recurrence=$recurrence, calendarURI=$calendarURI, remoteId='$remoteId', isCollapsed=$isCollapsed, parent=$parent, transitoryData=$transitoryData, readOnly=$readOnly, order=$order)"
}
@Retention(AnnotationRetention.SOURCE)

@ -152,8 +152,7 @@ class Upgrader @Inject constructor(
val remoteTask = vtodoCache.getVtodo(task)?.let { fromVtodo(it) } ?: continue
val order: Long? = remoteTask.order
if (order != null) {
task.order = order
caldavDao.update(task)
taskDao.setOrder(task.task, order)
}
}
}

@ -235,6 +235,7 @@ class TasksJsonImporter @Inject constructor(
?.let { taskAttachmentDao.insert(it) }
backup.caldavTasks?.forEach { caldavTask ->
caldavTask.task = taskId
caldavTask.order?.let { task.order = it }
caldavDao.insert(caldavTask)
}
backup.vtodo?.let {

@ -438,7 +438,7 @@ class iCalendar @Inject constructor(
else -> if (priority > 5) min(9, priority) else 9
}
parent = if (task.parent == 0L) null else caldavTask.remoteParent
order = caldavTask.order
order = task.order
collapsed = task.isCollapsed
}

@ -30,12 +30,12 @@ fun com.todoroo.astrid.data.Task.applyRemote(
applyDue(remote, local)
applyStart(remote, local)
applyCollapsed(remote, local)
applyOrder(remote, local)
return this
}
fun CaldavTask.applyRemote(remote: Task, local: Task?): CaldavTask {
applyParent(remote, local)
applyOrder(remote, local)
return this
}
@ -108,7 +108,7 @@ private fun com.todoroo.astrid.data.Task.applyCollapsed(remote: Task, local: Tas
}
}
private fun CaldavTask.applyOrder(remote: Task, local: Task?) {
private fun com.todoroo.astrid.data.Task.applyOrder(remote: Task, local: Task?) {
if (local == null || local.order == order) {
order = remote.order
}

@ -93,15 +93,15 @@ ORDER BY CASE cda_account_type
@Transaction
open suspend fun insert(task: Task, caldavTask: CaldavTask, addToTop: Boolean): Long {
if (caldavTask.order != null) {
if (task.order != null) {
return insert(caldavTask)
}
if (addToTop) {
caldavTask.order = findFirstTask(caldavTask.calendar!!, task.parent)
task.order = findFirstTask(caldavTask.calendar!!, task.parent)
?.takeIf { task.creationDate.toAppleEpoch() >= it }
?.minus(1)
} else {
caldavTask.order = findLastTask(caldavTask.calendar!!, task.parent)
task.order = findLastTask(caldavTask.calendar!!, task.parent)
?.takeIf { task.creationDate.toAppleEpoch() <= it }
?.plus(1)
}
@ -109,7 +109,7 @@ ORDER BY CASE cda_account_type
}
@Query("""
SELECT MIN(IFNULL(cd_order, (created - $APPLE_EPOCH) / 1000))
SELECT MIN(IFNULL(`order`, (created - $APPLE_EPOCH) / 1000))
FROM caldav_tasks
INNER JOIN tasks ON _id = cd_task
WHERE cd_calendar = :calendar
@ -120,7 +120,7 @@ WHERE cd_calendar = :calendar
internal abstract suspend fun findFirstTask(calendar: String, parent: Long): Long?
@Query("""
SELECT MAX(IFNULL(cd_order, (created - $APPLE_EPOCH) / 1000))
SELECT MAX(IFNULL(`order`, (created - $APPLE_EPOCH) / 1000))
FROM caldav_tasks
INNER JOIN tasks ON _id = cd_task
WHERE cd_calendar = :calendar
@ -139,16 +139,13 @@ WHERE cd_calendar = :calendar
@Update
abstract suspend fun update(caldavTask: CaldavTask)
@Update
abstract suspend fun updateTasks(tasks: Iterable<Task>)
suspend fun update(caldavTask: SubsetCaldav) {
update(caldavTask.cd_id, caldavTask.cd_order, caldavTask.cd_remote_parent)
update(caldavTask.cd_id, caldavTask.cd_remote_parent)
}
@Query("UPDATE caldav_tasks SET cd_order = :position, cd_remote_parent = :parent WHERE cd_id = :id")
internal abstract suspend fun update(id: Long, position: Long?, parent: String?)
@Query("UPDATE caldav_tasks SET cd_order = :position WHERE cd_id = :id")
internal abstract suspend fun update(id: Long, position: Long?)
@Query("UPDATE caldav_tasks SET cd_remote_parent = :remoteParent WHERE cd_id = :id")
internal abstract suspend fun update(id: Long, remoteParent: String?)
@ -303,7 +300,6 @@ GROUP BY caldav_lists.cdl_uuid
@Transaction
open suspend fun move(task: TaskContainer, newParent: Long, newPosition: Long?) {
val previousParent = task.parent
val caldavTask = task.caldavTask
val previousPosition = task.caldavSortOrder
if (newPosition != null) {
if (newParent == previousParent && newPosition < previousPosition) {
@ -312,28 +308,28 @@ GROUP BY caldav_lists.cdl_uuid
shiftDown(task.caldav!!, newParent, newPosition)
}
}
caldavTask.cd_order = newPosition
update(caldavTask.cd_id, caldavTask.cd_order)
task.task.order = newPosition
setTaskOrder(task.id, newPosition)
}
@Transaction
open suspend fun shiftDown(calendar: String, parent: Long, from: Long, to: Long? = null) {
val updated = ArrayList<CaldavTask>()
val updated = ArrayList<Task>()
val tasks = getTasksToShift(calendar, parent, from, to)
for (i in tasks.indices) {
val task = tasks[i]
val current = from + i
if (task.sortOrder == current) {
val caldavTask = task.caldavTask
caldavTask.order = current + 1
updated.add(caldavTask)
val task = task.task
task.order = current + 1
updated.add(task)
} else if (task.sortOrder > current) {
break
}
}
update(updated)
updateTasks(updated)
updated
.map(CaldavTask::task)
.map(Task::id)
.dbchunk()
.forEach { touchInternal(it) }
}
@ -342,7 +338,7 @@ GROUP BY caldav_lists.cdl_uuid
internal abstract suspend fun touchInternal(ids: List<Long>, modificationTime: Long = now())
@Query("""
SELECT task.*, caldav_task.*, IFNULL(cd_order, (created - $APPLE_EPOCH) / 1000) AS primary_sort
SELECT task.*, caldav_task.*, IFNULL(`order`, (created - $APPLE_EPOCH) / 1000) AS primary_sort
FROM caldav_tasks AS caldav_task
INNER JOIN tasks AS task ON _id = cd_task
WHERE cd_calendar = :calendar
@ -361,6 +357,9 @@ ORDER BY primary_sort
@Query("UPDATE caldav_lists SET cdl_order = :order WHERE cdl_id = :id")
abstract suspend fun setOrder(id: Long, order: Int)
@Query("UPDATE tasks SET `order` = :order WHERE _id = :id")
abstract suspend fun setTaskOrder(id: Long, order: Long?)
suspend fun setupLocalAccount(context: Context): CaldavAccount = mutex.withLock {
val account = getLocalAccount()
getLocalList(context, account)

@ -1,10 +1,6 @@
package org.tasks.data
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Ignore
import androidx.room.PrimaryKey
import androidx.room.*
import com.todoroo.andlib.data.Table
import com.todoroo.astrid.data.Task
import com.todoroo.astrid.helper.UUIDHelper
@ -87,7 +83,7 @@ class CaldavTask {
fun isDeleted() = deleted > 0
override fun toString(): String =
"CaldavTask(id=$id, task=$task, calendar=$calendar, `object`=$`object`, remoteId=$remoteId, etag=$etag, lastSync=$lastSync, deleted=$deleted, remoteParent=$remoteParent, order=$order)"
"CaldavTask(id=$id, task=$task, calendar=$calendar, `object`=$`object`, remoteId=$remoteId, etag=$etag, lastSync=$lastSync, deleted=$deleted, remoteParent=$remoteParent)"
companion object {
const val KEY = "caldav"

@ -18,7 +18,7 @@ class CaldavTaskContainer {
get() = task.isDeleted
val sortOrder: Long
get() = caldavTask.order ?: DateTime(task.creationDate).toAppleEpoch()
get() = task.order ?: DateTime(task.creationDate).toAppleEpoch()
val startDate: Long
get() = task.hideUntil

@ -147,6 +147,9 @@ SELECT EXISTS(SELECT 1 FROM tasks WHERE parent > 0 AND deleted = 0) AS hasSubtas
@Query("UPDATE tasks SET modified = :now WHERE _id in (:ids)")
internal abstract suspend fun internalTouch(ids: List<Long>, now: Long = currentTimeMillis())
@Query("UPDATE tasks SET `order` = :order WHERE _id = :id")
internal abstract suspend fun setOrder(id: Long, order: Long?)
suspend fun setParent(parent: Long, tasks: List<Long>) =
tasks.eachChunk { setParentInternal(parent, it) }

@ -591,11 +591,19 @@ object Migrations {
private val MIGRATION_87_88 = object : Migration(87, 88) {
override fun migrate(database: SupportSQLiteDatabase) {
// migrate google task accounts and lists to caldav table
database.execSQL("ALTER TABLE `caldav_lists` ADD COLUMN `cdl_last_sync` INTEGER NOT NULL DEFAULT 0")
database.execSQL("INSERT INTO `caldav_accounts` (`cda_account_type`, `cda_server_type`, `cda_uuid`, `cda_name`, `cda_username`, `cda_collapsed`) SELECT $TYPE_GOOGLE_TASKS, $SERVER_UNKNOWN, `gta_account`, `gta_account`, `gta_account`, `gta_collapsed` FROM `google_task_accounts`")
database.execSQL("INSERT INTO `caldav_lists` (`cdl_account`, `cdl_uuid`, `cdl_name`, `cdl_color`, `cdl_icon`, `cdl_order`, `cdl_last_sync`) SELECT `gtl_account`, `gtl_remote_id`, `gtl_title`, `gtl_color`, `gtl_icon`, `gtl_remote_order`, `gtl_last_sync` FROM `google_task_lists`")
database.execSQL("DROP TABLE `google_task_accounts`")
database.execSQL("DROP TABLE `google_task_lists`")
// move cd_order to task table
database.execSQL("ALTER TABLE `tasks` ADD COLUMN `order` INTEGER")
database.execSQL("UPDATE `tasks` SET `order` = (SELECT `cd_order` FROM `caldav_tasks` WHERE `cd_task` = `_id`)")
database.execSQL("ALTER TABLE `caldav_tasks` RENAME TO `caldav-temp`")
database.execSQL("CREATE TABLE IF NOT EXISTS `caldav_tasks` (`cd_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `cd_task` INTEGER NOT NULL, `cd_calendar` TEXT, `cd_object` TEXT, `cd_remote_id` TEXT, `cd_etag` TEXT, `cd_last_sync` INTEGER NOT NULL, `cd_deleted` INTEGER NOT NULL, `cd_remote_parent` TEXT, FOREIGN KEY(`cd_task`) REFERENCES `tasks`(`_id`) ON UPDATE NO ACTION ON DELETE CASCADE )")
database.execSQL("INSERT INTO `caldav_tasks` (`cd_id`, `cd_task`, `cd_calendar`, `cd_object`, `cd_remote_id`, `cd_etag`, `cd_last_sync`, `cd_deleted`, `cd_remote_parent`) SELECT `cd_id`, `cd_task`, `cd_calendar`, `cd_object`, `cd_remote_id`, `cd_etag`, `cd_last_sync`, `cd_deleted`, `cd_remote_parent` FROM `caldav-temp`")
database.execSQL("DROP TABLE `caldav-temp`")
}
}

Loading…
Cancel
Save