Revert "Restore @Transaction annotations"

This reverts commit b35090cd43.
pull/2908/head
Alex Baker 4 weeks ago
parent b35090cd43
commit ea7f051d85

@ -4,13 +4,13 @@ import androidx.room.Dao
import androidx.room.Delete import androidx.room.Delete
import androidx.room.Insert import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update import androidx.room.Update
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import org.tasks.data.CaldavFilters import org.tasks.data.CaldavFilters
import org.tasks.data.CaldavTaskContainer import org.tasks.data.CaldavTaskContainer
import org.tasks.data.NO_ORDER import org.tasks.data.NO_ORDER
import org.tasks.data.TaskContainer import org.tasks.data.TaskContainer
import org.tasks.data.db.Database
import org.tasks.data.db.DbUtils.dbchunk import org.tasks.data.db.DbUtils.dbchunk
import org.tasks.data.db.SuspendDbUtils.chunkedMap import org.tasks.data.db.SuspendDbUtils.chunkedMap
import org.tasks.data.entity.CaldavAccount import org.tasks.data.entity.CaldavAccount
@ -22,12 +22,13 @@ import org.tasks.data.entity.CaldavAccount.Companion.TYPE_TASKS
import org.tasks.data.entity.CaldavCalendar import org.tasks.data.entity.CaldavCalendar
import org.tasks.data.entity.CaldavTask import org.tasks.data.entity.CaldavTask
import org.tasks.data.entity.Task import org.tasks.data.entity.Task
import org.tasks.data.withTransaction
import org.tasks.time.DateTimeUtils2.currentTimeMillis import org.tasks.time.DateTimeUtils2.currentTimeMillis
const val APPLE_EPOCH = 978307200000L // 1/1/2001 GMT const val APPLE_EPOCH = 978307200000L // 1/1/2001 GMT
@Dao @Dao
abstract class CaldavDao { abstract class CaldavDao(private val database: Database) {
@Query("SELECT COUNT(*) FROM caldav_lists WHERE cdl_account = :account") @Query("SELECT COUNT(*) FROM caldav_lists WHERE cdl_account = :account")
abstract suspend fun listCount(account: String): Int abstract suspend fun listCount(account: String): Int
@ -98,24 +99,24 @@ ORDER BY CASE cda_account_type
@Update @Update
abstract suspend fun update(caldavCalendar: CaldavCalendar) abstract suspend fun update(caldavCalendar: CaldavCalendar)
@Transaction suspend fun insert(task: Task, caldavTask: CaldavTask, addToTop: Boolean): Long =
open suspend fun insert(task: Task, caldavTask: CaldavTask, addToTop: Boolean): Long { database.withTransaction {
if (task.order != null) { if (task.order != null) {
return insert(caldavTask) return@withTransaction insert(caldavTask)
} }
if (addToTop) { if (addToTop) {
task.order = findFirstTask(caldavTask.calendar!!, task.parent) task.order = findFirstTask(caldavTask.calendar!!, task.parent)
?.takeIf { task.creationDate.toAppleEpoch() >= it } ?.takeIf { task.creationDate.toAppleEpoch() >= it }
?.minus(1) ?.minus(1)
} else { } else {
task.order = findLastTask(caldavTask.calendar!!, task.parent) task.order = findLastTask(caldavTask.calendar!!, task.parent)
?.takeIf { task.creationDate.toAppleEpoch() <= it } ?.takeIf { task.creationDate.toAppleEpoch() <= it }
?.plus(1) ?.plus(1)
}
val id = insert(caldavTask)
update(task)
id
} }
val id = insert(caldavTask)
update(task)
return id
}
@Query(""" @Query("""
SELECT MIN(IFNULL(`order`, (created - $APPLE_EPOCH) / 1000)) SELECT MIN(IFNULL(`order`, (created - $APPLE_EPOCH) / 1000))
@ -311,47 +312,49 @@ GROUP BY caldav_lists.cdl_uuid
+ "WHERE _id IN (SELECT _id FROM tasks INNER JOIN caldav_tasks ON _id = cd_task WHERE cd_deleted = 0 AND cd_calendar = :calendar)") + "WHERE _id IN (SELECT _id FROM tasks INNER JOIN caldav_tasks ON _id = cd_task WHERE cd_deleted = 0 AND cd_calendar = :calendar)")
abstract suspend fun updateParents(calendar: String) abstract suspend fun updateParents(calendar: String)
@Transaction suspend fun move(
open suspend fun move(
task: TaskContainer, task: TaskContainer,
previousParent: Long, previousParent: Long,
newParent: Long, newParent: Long,
newPosition: Long?, newPosition: Long?,
) { ) {
val previousPosition = task.caldavSortOrder database.withTransaction {
if (newPosition != null) { val previousPosition = task.caldavSortOrder
if (newParent == previousParent && newPosition < previousPosition) { if (newPosition != null) {
shiftDown(task.caldav!!, newParent, newPosition, previousPosition) if (newParent == previousParent && newPosition < previousPosition) {
} else { shiftDown(task.caldav!!, newParent, newPosition, previousPosition)
val list = } else {
newParent.takeIf { it > 0 }?.let { getTask(it)?.calendar } ?: task.caldav!! val list =
shiftDown(list, newParent, newPosition) newParent.takeIf { it > 0 }?.let { getTask(it)?.calendar } ?: task.caldav!!
shiftDown(list, newParent, newPosition)
}
} }
task.task.order = newPosition
setTaskOrder(task.id, newPosition)
} }
task.task.order = newPosition
setTaskOrder(task.id, newPosition)
} }
@Transaction suspend fun shiftDown(calendar: String, parent: Long, from: Long, to: Long? = null) {
open suspend fun shiftDown(calendar: String, parent: Long, from: Long, to: Long? = null) { database.withTransaction {
val updated = ArrayList<Task>() val updated = ArrayList<Task>()
val tasks = getTasksToShift(calendar, parent, from, to) val tasks = getTasksToShift(calendar, parent, from, to)
for (i in tasks.indices) { for (i in tasks.indices) {
val task = tasks[i] val task = tasks[i]
val current = from + i val current = from + i
if (task.sortOrder == current) { if (task.sortOrder == current) {
val task = task.task val task = task.task
task.order = current + 1 task.order = current + 1
updated.add(task) updated.add(task)
} else if (task.sortOrder > current) { } else if (task.sortOrder > current) {
break break
}
} }
updateTasks(updated)
updated
.map(Task::id)
.dbchunk()
.forEach { touchInternal(it) }
} }
updateTasks(updated)
updated
.map(Task::id)
.dbchunk()
.forEach { touchInternal(it) }
} }
@Query("UPDATE tasks SET modified = :modificationTime WHERE _id in (:ids)") @Query("UPDATE tasks SET modified = :modificationTime WHERE _id in (:ids)")

@ -3,15 +3,16 @@ package org.tasks.data.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete import androidx.room.Delete
import androidx.room.Query import androidx.room.Query
import androidx.room.Transaction
import org.tasks.data.dao.CaldavDao.Companion.LOCAL import org.tasks.data.dao.CaldavDao.Companion.LOCAL
import org.tasks.data.db.Database
import org.tasks.data.db.SuspendDbUtils.chunkedMap import org.tasks.data.db.SuspendDbUtils.chunkedMap
import org.tasks.data.db.SuspendDbUtils.eachChunk import org.tasks.data.db.SuspendDbUtils.eachChunk
import org.tasks.data.entity.CaldavAccount import org.tasks.data.entity.CaldavAccount
import org.tasks.data.entity.CaldavCalendar import org.tasks.data.entity.CaldavCalendar
import org.tasks.data.withTransaction
@Dao @Dao
abstract class DeletionDao { abstract class DeletionDao(private val database: Database) {
@Query("DELETE FROM tasks WHERE _id IN(:ids)") @Query("DELETE FROM tasks WHERE _id IN(:ids)")
internal abstract suspend fun deleteTasks(ids: List<Long>) internal abstract suspend fun deleteTasks(ids: List<Long>)
@ -58,13 +59,13 @@ WHERE recurring = 1
@Delete @Delete
internal abstract suspend fun deleteCaldavCalendar(caldavCalendar: CaldavCalendar) internal abstract suspend fun deleteCaldavCalendar(caldavCalendar: CaldavCalendar)
@Transaction suspend fun delete(caldavCalendar: CaldavCalendar): List<Long> =
open suspend fun delete(caldavCalendar: CaldavCalendar): List<Long> { database.withTransaction {
val tasks = getActiveCaldavTasks(caldavCalendar.uuid!!) val tasks = getActiveCaldavTasks(caldavCalendar.uuid!!)
delete(tasks) delete(tasks)
deleteCaldavCalendar(caldavCalendar) deleteCaldavCalendar(caldavCalendar)
return tasks tasks
} }
@Query("SELECT * FROM caldav_lists WHERE cdl_account = :account") @Query("SELECT * FROM caldav_lists WHERE cdl_account = :account")
abstract suspend fun getCalendars(account: String): List<CaldavCalendar> abstract suspend fun getCalendars(account: String): List<CaldavCalendar>
@ -75,13 +76,13 @@ WHERE recurring = 1
@Query("DELETE FROM tasks WHERE _id IN (SELECT _id FROM tasks INNER JOIN caldav_tasks ON _id = cd_task INNER JOIN caldav_lists ON cdl_uuid = cd_calendar WHERE cdl_account = '$LOCAL' AND deleted > 0 AND cd_deleted = 0)") @Query("DELETE FROM tasks WHERE _id IN (SELECT _id FROM tasks INNER JOIN caldav_tasks ON _id = cd_task INNER JOIN caldav_lists ON cdl_uuid = cd_calendar WHERE cdl_account = '$LOCAL' AND deleted > 0 AND cd_deleted = 0)")
abstract suspend fun purgeDeleted() abstract suspend fun purgeDeleted()
@Transaction suspend fun delete(caldavAccount: CaldavAccount): List<Long> =
open suspend fun delete(caldavAccount: CaldavAccount): List<Long> { database.withTransaction {
val deleted = ArrayList<Long>() val deleted = ArrayList<Long>()
for (calendar in getCalendars(caldavAccount.uuid!!)) { for (calendar in getCalendars(caldavAccount.uuid!!)) {
deleted.addAll(delete(calendar)) deleted.addAll(delete(calendar))
}
deleteCaldavAccount(caldavAccount)
deleted
} }
deleteCaldavAccount(caldavAccount)
return deleted
}
} }

@ -4,30 +4,32 @@ import androidx.room.Dao
import androidx.room.Delete import androidx.room.Delete
import androidx.room.Insert import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update import androidx.room.Update
import org.tasks.data.db.Database
import org.tasks.data.entity.CaldavAccount.Companion.TYPE_GOOGLE_TASKS import org.tasks.data.entity.CaldavAccount.Companion.TYPE_GOOGLE_TASKS
import org.tasks.data.entity.CaldavTask import org.tasks.data.entity.CaldavTask
import org.tasks.data.entity.Task import org.tasks.data.entity.Task
import org.tasks.data.withTransaction
@Dao @Dao
abstract class GoogleTaskDao { abstract class GoogleTaskDao(private val database: Database) {
@Insert @Insert
abstract suspend fun insert(task: CaldavTask): Long abstract suspend fun insert(task: CaldavTask): Long
@Insert @Insert
abstract suspend fun insert(tasks: Iterable<CaldavTask>) abstract suspend fun insert(tasks: Iterable<CaldavTask>)
@Transaction suspend fun insertAndShift(task: Task, caldavTask: CaldavTask, top: Boolean) {
open suspend fun insertAndShift(task: Task, caldavTask: CaldavTask, top: Boolean) { database.withTransaction {
if (top) { if (top) {
task.order = 0 task.order = 0
shiftDown(caldavTask.calendar!!, task.parent, 0) shiftDown(caldavTask.calendar!!, task.parent, 0)
} else { } else {
task.order = getBottom(caldavTask.calendar!!, task.parent) task.order = getBottom(caldavTask.calendar!!, task.parent)
}
insert(caldavTask)
update(task)
} }
insert(caldavTask)
update(task)
} }
@Query("UPDATE tasks SET `order` = `order` + 1 WHERE parent = :parent AND `order` >= :position AND _id IN (SELECT cd_task FROM caldav_tasks WHERE cd_calendar = :listId)") @Query("UPDATE tasks SET `order` = `order` + 1 WHERE parent = :parent AND `order` >= :position AND _id IN (SELECT cd_task FROM caldav_tasks WHERE cd_calendar = :listId)")
@ -42,24 +44,25 @@ abstract class GoogleTaskDao {
@Query("UPDATE tasks SET `order` = `order` - 1 WHERE parent = :parent AND `order` >= :position AND _id IN (SELECT cd_task FROM caldav_tasks WHERE cd_calendar = :listId)") @Query("UPDATE tasks SET `order` = `order` - 1 WHERE parent = :parent AND `order` >= :position AND _id IN (SELECT cd_task FROM caldav_tasks WHERE cd_calendar = :listId)")
internal abstract suspend fun shiftUp(listId: String, parent: Long, position: Long) internal abstract suspend fun shiftUp(listId: String, parent: Long, position: Long)
@Transaction suspend fun move(task: Task, list: String, newParent: Long, newPosition: Long) {
open suspend fun move(task: Task, list: String, newParent: Long, newPosition: Long) { database.withTransaction {
val previousParent = task.parent val previousParent = task.parent
val previousPosition = task.order!! val previousPosition = task.order!!
if (newParent == previousParent) { if (newParent == previousParent) {
if (previousPosition < newPosition) { if (previousPosition < newPosition) {
shiftUp(list, newParent, previousPosition, newPosition) shiftUp(list, newParent, previousPosition, newPosition)
} else {
shiftDown(list, newParent, previousPosition, newPosition)
}
} else { } else {
shiftDown(list, newParent, previousPosition, newPosition) shiftUp(list, previousParent, previousPosition)
shiftDown(list, newParent, newPosition)
} }
} else { task.parent = newParent
shiftUp(list, previousParent, previousPosition) task.order = newPosition
shiftDown(list, newParent, newPosition) update(task)
setMoved(task.id, list)
} }
task.parent = newParent
task.order = newPosition
update(task)
setMoved(task.id, list)
} }
@Query("UPDATE caldav_tasks SET gt_moved = 1 WHERE cd_task = :task and cd_calendar = :list") @Query("UPDATE caldav_tasks SET gt_moved = 1 WHERE cd_task = :task and cd_calendar = :list")
@ -165,26 +168,27 @@ WHERE cd_remote_id = :id
""") """)
abstract suspend fun updatePosition(id: String, parent: String?, position: String) abstract suspend fun updatePosition(id: String, parent: String?, position: String)
@Transaction suspend fun reposition(caldavDao: CaldavDao, listId: String) {
open suspend fun reposition(caldavDao: CaldavDao, listId: String) { database.withTransaction {
caldavDao.updateParents(listId) caldavDao.updateParents(listId)
val orderedTasks = getByRemoteOrder(listId) val orderedTasks = getByRemoteOrder(listId)
var subtasks = 0L var subtasks = 0L
var parent = 0L var parent = 0L
for (task in orderedTasks) { for (task in orderedTasks) {
if (task.parent > 0) { if (task.parent > 0) {
if (task.order != subtasks) { if (task.order != subtasks) {
task.order = subtasks task.order = subtasks
update(task) update(task)
}
subtasks++
} else {
subtasks = 0
if (task.order != parent) {
task.order = parent
update(task)
}
parent++
} }
subtasks++
} else {
subtasks = 0
if (task.order != parent) {
task.order = parent
update(task)
}
parent++
} }
} }
} }

@ -4,39 +4,43 @@ import androidx.room.Dao
import androidx.room.Delete import androidx.room.Delete
import androidx.room.Insert import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update import androidx.room.Update
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import org.tasks.data.PrincipalWithAccess import org.tasks.data.PrincipalWithAccess
import org.tasks.data.db.Database
import org.tasks.data.entity.CaldavAccount import org.tasks.data.entity.CaldavAccount
import org.tasks.data.entity.CaldavCalendar import org.tasks.data.entity.CaldavCalendar
import org.tasks.data.entity.Principal import org.tasks.data.entity.Principal
import org.tasks.data.entity.PrincipalAccess import org.tasks.data.entity.PrincipalAccess
import org.tasks.data.withTransaction
@Dao @Dao
interface PrincipalDao { abstract class PrincipalDao(private val database: Database) {
@Insert @Insert
suspend fun insert(principal: Principal): Long abstract suspend fun insert(principal: Principal): Long
@Insert @Insert
suspend fun insert(access: PrincipalAccess): Long abstract suspend fun insert(access: PrincipalAccess): Long
@Update @Update
suspend fun update(access: PrincipalAccess) abstract suspend fun update(access: PrincipalAccess)
@Query(""" @Query("""
DELETE DELETE
FROM principal_access FROM principal_access
WHERE list = :list WHERE list = :list
AND id NOT IN (:access)""") AND id NOT IN (:access)""")
suspend fun deleteRemoved(list: Long, access: List<Long>) abstract suspend fun deleteRemoved(list: Long, access: List<Long>)
@Delete @Delete
suspend fun delete(access: PrincipalAccess) abstract suspend fun delete(access: PrincipalAccess)
suspend fun getAll(): List<PrincipalWithAccess> = database.withTransaction {
getAllInternal()
}
@Transaction
@Query("SELECT * FROM principal_access") @Query("SELECT * FROM principal_access")
suspend fun getAll(): List<PrincipalWithAccess> internal abstract suspend fun getAllInternal(): List<PrincipalWithAccess>
suspend fun getOrCreatePrincipal(account: CaldavAccount, href: String, displayName: String? = null) = suspend fun getOrCreatePrincipal(account: CaldavAccount, href: String, displayName: String? = null) =
findPrincipal(account.id, href) findPrincipal(account.id, href)
@ -65,12 +69,12 @@ WHERE list = :list
).apply { id = insert(this) } ).apply { id = insert(this) }
@Query("SELECT * FROM principals WHERE account = :account AND href = :href") @Query("SELECT * FROM principals WHERE account = :account AND href = :href")
suspend fun findPrincipal(account: Long, href: String): Principal? abstract suspend fun findPrincipal(account: Long, href: String): Principal?
@Query("SELECT * FROM principal_access WHERE list = :list and principal = :principal") @Query("SELECT * FROM principal_access WHERE list = :list and principal = :principal")
suspend fun findAccess(list: Long, principal: Long): PrincipalAccess? abstract suspend fun findAccess(list: Long, principal: Long): PrincipalAccess?
@Transaction
@Query("SELECT * FROM principal_access WHERE list = :id") @Query("SELECT * FROM principal_access WHERE list = :id")
fun getPrincipals(id: Long): Flow<List<PrincipalWithAccess>> abstract fun getPrincipals(id: Long): Flow<List<PrincipalWithAccess>>
}
}

@ -4,13 +4,14 @@ import androidx.room.Dao
import androidx.room.Delete import androidx.room.Delete
import androidx.room.Insert import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import androidx.room.Transaction import org.tasks.data.db.Database
import org.tasks.data.entity.Tag import org.tasks.data.entity.Tag
import org.tasks.data.entity.TagData import org.tasks.data.entity.TagData
import org.tasks.data.entity.Task import org.tasks.data.entity.Task
import org.tasks.data.withTransaction
@Dao @Dao
abstract class TagDao { abstract class TagDao(private val database: Database) {
@Query("UPDATE tags SET name = :name WHERE tag_uid = :tagUid") @Query("UPDATE tags SET name = :name WHERE tag_uid = :tagUid")
abstract suspend fun rename(tagUid: String, name: String) abstract suspend fun rename(tagUid: String, name: String)
@ -35,15 +36,16 @@ abstract class TagDao {
@Delete @Delete
abstract suspend fun delete(tags: List<Tag>) abstract suspend fun delete(tags: List<Tag>)
@Transaction
open suspend fun applyTags(task: Task, tagDataDao: TagDataDao, current: List<TagData>) { open suspend fun applyTags(task: Task, tagDataDao: TagDataDao, current: List<TagData>) {
val taskId = task.id database.withTransaction {
val existing = HashSet(tagDataDao.getTagDataForTask(taskId)) val taskId = task.id
val selected = HashSet<TagData>(current) val existing = HashSet(tagDataDao.getTagDataForTask(taskId))
val added = selected subtract existing val selected = HashSet<TagData>(current)
val removed = existing subtract selected val added = selected subtract existing
deleteTags(taskId, removed.map { td -> td.remoteId!! }) val removed = existing subtract selected
insert(task, added) deleteTags(taskId, removed.map { td -> td.remoteId!! })
insert(task, added)
}
} }
suspend fun insert(task: Task, tags: Collection<TagData>) { suspend fun insert(task: Task, tags: Collection<TagData>) {

@ -4,19 +4,20 @@ import androidx.room.Dao
import androidx.room.Delete import androidx.room.Delete
import androidx.room.Insert import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update import androidx.room.Update
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import org.tasks.data.NO_ORDER import org.tasks.data.NO_ORDER
import org.tasks.data.TagFilters import org.tasks.data.TagFilters
import org.tasks.data.db.Database
import org.tasks.data.db.DbUtils import org.tasks.data.db.DbUtils
import org.tasks.data.entity.Tag import org.tasks.data.entity.Tag
import org.tasks.data.entity.TagData import org.tasks.data.entity.TagData
import org.tasks.data.entity.Task import org.tasks.data.entity.Task
import org.tasks.data.withTransaction
import org.tasks.time.DateTimeUtils2.currentTimeMillis import org.tasks.time.DateTimeUtils2.currentTimeMillis
@Dao @Dao
abstract class TagDataDao { abstract class TagDataDao(private val database: Database) {
@Query("SELECT * FROM tagdata") @Query("SELECT * FROM tagdata")
abstract fun subscribeToTags(): Flow<List<TagData>> abstract fun subscribeToTags(): Flow<List<TagData>>
@ -79,12 +80,11 @@ abstract class TagDataDao {
+ " GROUP BY tasks._id") + " GROUP BY tasks._id")
internal abstract suspend fun getAllTags(tasks: List<Long>): List<String?> internal abstract suspend fun getAllTags(tasks: List<Long>): List<String?>
@Transaction suspend fun applyTags(
open suspend fun applyTags(
tasks: List<Task>, tasks: List<Task>,
partiallySelected: List<TagData>, partiallySelected: List<TagData>,
selected: List<TagData> selected: List<TagData>
): List<Long> { ): List<Long> = database.withTransaction {
val modified = HashSet<Long>() val modified = HashSet<Long>()
val keep = partiallySelected.plus(selected).map { it.remoteId!! } val keep = partiallySelected.plus(selected).map { it.remoteId!! }
for (sublist in tasks.chunked(DbUtils.MAX_SQLITE_ARGS - keep.size)) { for (sublist in tasks.chunked(DbUtils.MAX_SQLITE_ARGS - keep.size)) {
@ -108,13 +108,14 @@ abstract class TagDataDao {
) )
} }
} }
return ArrayList(modified) ArrayList(modified)
} }
@Transaction suspend fun delete(tagData: TagData) {
open suspend fun delete(tagData: TagData) { database.withTransaction {
deleteTags(tagData.remoteId!!) deleteTags(tagData.remoteId!!)
deleteTagData(tagData) deleteTagData(tagData)
}
} }
@Delete @Delete

Loading…
Cancel
Save