Restore @Transaction annotations

pull/2908/head
Alex Baker 3 weeks ago
parent 92f62450ae
commit b35090cd43

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

@ -3,16 +3,15 @@ package org.tasks.data.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Query
import androidx.room.Transaction
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.eachChunk
import org.tasks.data.entity.CaldavAccount
import org.tasks.data.entity.CaldavCalendar
import org.tasks.data.withTransaction
@Dao
abstract class DeletionDao(private val database: Database) {
abstract class DeletionDao {
@Query("DELETE FROM tasks WHERE _id IN(:ids)")
internal abstract suspend fun deleteTasks(ids: List<Long>)
@ -59,13 +58,13 @@ WHERE recurring = 1
@Delete
internal abstract suspend fun deleteCaldavCalendar(caldavCalendar: CaldavCalendar)
suspend fun delete(caldavCalendar: CaldavCalendar): List<Long> =
database.withTransaction {
val tasks = getActiveCaldavTasks(caldavCalendar.uuid!!)
delete(tasks)
deleteCaldavCalendar(caldavCalendar)
tasks
}
@Transaction
open suspend fun delete(caldavCalendar: CaldavCalendar): List<Long> {
val tasks = getActiveCaldavTasks(caldavCalendar.uuid!!)
delete(tasks)
deleteCaldavCalendar(caldavCalendar)
return tasks
}
@Query("SELECT * FROM caldav_lists WHERE cdl_account = :account")
abstract suspend fun getCalendars(account: String): List<CaldavCalendar>
@ -76,13 +75,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)")
abstract suspend fun purgeDeleted()
suspend fun delete(caldavAccount: CaldavAccount): List<Long> =
database.withTransaction {
val deleted = ArrayList<Long>()
for (calendar in getCalendars(caldavAccount.uuid!!)) {
deleted.addAll(delete(calendar))
}
deleteCaldavAccount(caldavAccount)
deleted
@Transaction
open suspend fun delete(caldavAccount: CaldavAccount): List<Long> {
val deleted = ArrayList<Long>()
for (calendar in getCalendars(caldavAccount.uuid!!)) {
deleted.addAll(delete(calendar))
}
deleteCaldavAccount(caldavAccount)
return deleted
}
}

@ -4,32 +4,30 @@ import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Transaction
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.CaldavTask
import org.tasks.data.entity.Task
import org.tasks.data.withTransaction
@Dao
abstract class GoogleTaskDao(private val database: Database) {
abstract class GoogleTaskDao {
@Insert
abstract suspend fun insert(task: CaldavTask): Long
@Insert
abstract suspend fun insert(tasks: Iterable<CaldavTask>)
suspend fun insertAndShift(task: Task, caldavTask: CaldavTask, top: Boolean) {
database.withTransaction {
if (top) {
task.order = 0
shiftDown(caldavTask.calendar!!, task.parent, 0)
} else {
task.order = getBottom(caldavTask.calendar!!, task.parent)
}
insert(caldavTask)
update(task)
@Transaction
open suspend fun insertAndShift(task: Task, caldavTask: CaldavTask, top: Boolean) {
if (top) {
task.order = 0
shiftDown(caldavTask.calendar!!, task.parent, 0)
} else {
task.order = getBottom(caldavTask.calendar!!, task.parent)
}
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)")
@ -44,25 +42,24 @@ abstract class GoogleTaskDao(private val database: Database) {
@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)
suspend fun move(task: Task, list: String, newParent: Long, newPosition: Long) {
database.withTransaction {
val previousParent = task.parent
val previousPosition = task.order!!
if (newParent == previousParent) {
if (previousPosition < newPosition) {
shiftUp(list, newParent, previousPosition, newPosition)
} else {
shiftDown(list, newParent, previousPosition, newPosition)
}
@Transaction
open suspend fun move(task: Task, list: String, newParent: Long, newPosition: Long) {
val previousParent = task.parent
val previousPosition = task.order!!
if (newParent == previousParent) {
if (previousPosition < newPosition) {
shiftUp(list, newParent, previousPosition, newPosition)
} else {
shiftUp(list, previousParent, previousPosition)
shiftDown(list, newParent, newPosition)
shiftDown(list, newParent, previousPosition, newPosition)
}
task.parent = newParent
task.order = newPosition
update(task)
setMoved(task.id, list)
} else {
shiftUp(list, previousParent, previousPosition)
shiftDown(list, newParent, newPosition)
}
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")
@ -168,27 +165,26 @@ WHERE cd_remote_id = :id
""")
abstract suspend fun updatePosition(id: String, parent: String?, position: String)
suspend fun reposition(caldavDao: CaldavDao, listId: String) {
database.withTransaction {
caldavDao.updateParents(listId)
val orderedTasks = getByRemoteOrder(listId)
var subtasks = 0L
var parent = 0L
for (task in orderedTasks) {
if (task.parent > 0) {
if (task.order != subtasks) {
task.order = subtasks
update(task)
}
subtasks++
} else {
subtasks = 0
if (task.order != parent) {
task.order = parent
update(task)
}
parent++
@Transaction
open suspend fun reposition(caldavDao: CaldavDao, listId: String) {
caldavDao.updateParents(listId)
val orderedTasks = getByRemoteOrder(listId)
var subtasks = 0L
var parent = 0L
for (task in orderedTasks) {
if (task.parent > 0) {
if (task.order != subtasks) {
task.order = subtasks
update(task)
}
subtasks++
} else {
subtasks = 0
if (task.order != parent) {
task.order = parent
update(task)
}
parent++
}
}
}

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

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

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

Loading…
Cancel
Save