@ -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,13 +22,12 @@ 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 ( private val database : Database ) {
abstract class CaldavDao {
@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
@ -99,24 +98,24 @@ ORDER BY CASE cda_account_type
@Update
@Update
abstract suspend fun update ( caldavCalendar : CaldavCalendar )
abstract suspend fun update ( caldavCalendar : CaldavCalendar )
suspend fun insert ( task : Task , caldavTask : CaldavTask , addToTop : Boolean ) : Long =
@Transaction
database . withTransaction {
open suspend fun insert ( task : Task , caldavTask : CaldavTask , addToTop : Boolean ) : Long {
if ( task . order != null ) {
if ( task . order != null ) {
return @withTransaction insert ( caldavTask )
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 )
id
}
}
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 ( """
@Query ( """
SELECT MIN ( IFNULL ( `order` , ( created - $ APPLE _EPOCH ) / 1000 ) )
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) " )
+ " 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 )
suspend fun move (
@Transaction
open suspend fun move (
task : TaskContainer ,
task : TaskContainer ,
previousParent : Long ,
previousParent : Long ,
newParent : Long ,
newParent : Long ,
newPosition : Long ? ,
newPosition : Long ? ,
) {
) {
database . withTransaction {
val previousPosition = task . caldavSortOrder
val previousPosition = task . caldavSortOrder
if ( newPosition != null ) {
if ( newPosition != null ) {
if ( newParent == previousParent && newPosition < previousPosition ) {
if ( newParent == previousParent && newPosition < previousPosition ) {
shiftDown ( task . caldav !! , newParent , newPosition , previousPosition )
shiftDown ( task . caldav !! , newParent , newPosition , previousPosition )
} else {
} else {
val list =
val list =
newParent . takeIf { it > 0 } ?. let { getTask ( it ) ?. calendar } ?: task . caldav !!
newParent . takeIf { it > 0 } ?. let { getTask ( it ) ?. calendar } ?: task . caldav !!
shiftDown ( list , newParent , newPosition )
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 ) {
@Transaction
database . withTransaction {
open suspend fun shiftDown ( calendar : String , parent : Long , from : Long , to : Long ? = null ) {
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) " )