mirror of https://github.com/tasks/tasks
Attachment changes
* Add attachment table to map attachment to file * Convert TaskAttachment to immutable data class * Copy attachments when duplicating taskspull/1967/head
parent
226687fee8
commit
2ac6c2413b
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,37 @@
|
|||||||
|
package org.tasks.data
|
||||||
|
|
||||||
|
import androidx.room.*
|
||||||
|
import com.todoroo.astrid.data.Task
|
||||||
|
|
||||||
|
@Entity(
|
||||||
|
tableName = "attachment",
|
||||||
|
foreignKeys = [
|
||||||
|
ForeignKey(
|
||||||
|
entity = Task::class,
|
||||||
|
parentColumns = ["_id"],
|
||||||
|
childColumns = ["task"],
|
||||||
|
onDelete = ForeignKey.CASCADE,
|
||||||
|
),
|
||||||
|
ForeignKey(
|
||||||
|
entity = TaskAttachment::class,
|
||||||
|
parentColumns = ["file_id"],
|
||||||
|
childColumns = ["file"],
|
||||||
|
onDelete = ForeignKey.CASCADE,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
indices = [Index(value = ["task", "file"], unique = true)],
|
||||||
|
)
|
||||||
|
data class Attachment(
|
||||||
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
@ColumnInfo(name = "attachment_id")
|
||||||
|
@Transient
|
||||||
|
val id: Long? = null,
|
||||||
|
@ColumnInfo(name = "task", index = true)
|
||||||
|
@Transient
|
||||||
|
val task: Long,
|
||||||
|
@ColumnInfo(name = "file", index = true)
|
||||||
|
@Transient
|
||||||
|
val fileId: Long,
|
||||||
|
@ColumnInfo(name = "file_uuid")
|
||||||
|
val attachmentUid: String,
|
||||||
|
)
|
@ -1,61 +1,50 @@
|
|||||||
package org.tasks.data
|
package org.tasks.data
|
||||||
|
|
||||||
import android.net.Uri
|
import android.os.Parcel
|
||||||
|
import android.os.Parcelable
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.Ignore
|
import androidx.room.Ignore
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import com.todoroo.astrid.data.Task
|
import com.todoroo.astrid.helper.UUIDHelper
|
||||||
import org.tasks.Strings
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
@Entity(tableName = "task_attachments")
|
@Entity(tableName = "attachment_file")
|
||||||
class TaskAttachment {
|
data class TaskAttachment(
|
||||||
@PrimaryKey(autoGenerate = true)
|
@PrimaryKey(autoGenerate = true)
|
||||||
@ColumnInfo(name = "_id")
|
@ColumnInfo(name = "file_id")
|
||||||
@Transient
|
@Transient
|
||||||
var id: Long? = null
|
val id: Long? = null,
|
||||||
|
@ColumnInfo(name = "file_uuid")
|
||||||
@ColumnInfo(name = "remoteId")
|
val remoteId: String = UUIDHelper.newUUID(),
|
||||||
var remoteId: String? = Task.NO_UUID
|
@ColumnInfo(name = "filename")
|
||||||
|
val name: String,
|
||||||
// -- Constants
|
@ColumnInfo(name = "uri")
|
||||||
@ColumnInfo(name = "task_id")
|
val uri: String,
|
||||||
var taskId: String? = Task.NO_UUID
|
) : Parcelable {
|
||||||
|
|
||||||
@ColumnInfo(name = "name")
|
|
||||||
var name: String? = ""
|
|
||||||
|
|
||||||
@ColumnInfo(name = "path")
|
|
||||||
var uri: String? = ""
|
|
||||||
private set
|
|
||||||
|
|
||||||
@ColumnInfo(name = "content_type")
|
|
||||||
var contentType: String? = ""
|
|
||||||
|
|
||||||
constructor()
|
|
||||||
|
|
||||||
@Ignore
|
@Ignore
|
||||||
constructor(taskUuid: String, uri: Uri?, fileName: String) {
|
constructor(parcel: Parcel) : this(
|
||||||
taskId = taskUuid
|
remoteId = parcel.readString()!!,
|
||||||
name = fileName
|
name = parcel.readString()!!,
|
||||||
setUri(uri?.toString())
|
uri = parcel.readString()!!,
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun describeContents() = 0
|
||||||
|
|
||||||
|
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||||
|
parcel.writeString(remoteId)
|
||||||
|
parcel.writeString(name)
|
||||||
|
parcel.writeString(uri)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setUri(uri: String?) {
|
|
||||||
this.uri = uri
|
|
||||||
}
|
|
||||||
|
|
||||||
fun convertPathUri() {
|
|
||||||
setUri(Uri.fromFile(File(uri!!)).toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun parseUri(): Uri? = if (Strings.isNullOrEmpty(uri)) null else Uri.parse(uri)
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val KEY = "attachment"
|
const val KEY = "attachment"
|
||||||
|
const val FILES_DIRECTORY_DEFAULT = "attachments"
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val CREATOR = object : Parcelable.Creator<TaskAttachment> {
|
||||||
|
override fun createFromParcel(parcel: Parcel) = TaskAttachment(parcel)
|
||||||
|
|
||||||
/** default directory for files on external storage */
|
override fun newArray(size: Int): Array<TaskAttachment?> = arrayOfNulls(size)
|
||||||
const val FILES_DIRECTORY_DEFAULT = "attachments" // $NON-NLS-1$
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,37 +1,36 @@
|
|||||||
package org.tasks.data
|
package org.tasks.data
|
||||||
|
|
||||||
import androidx.room.*
|
import androidx.room.*
|
||||||
import com.todoroo.astrid.data.Task
|
|
||||||
import com.todoroo.astrid.helper.UUIDHelper
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
abstract class TaskAttachmentDao {
|
interface TaskAttachmentDao {
|
||||||
@Query("SELECT * FROM task_attachments WHERE task_id = :taskUuid")
|
@Query("SELECT * FROM attachment WHERE task = :task")
|
||||||
abstract suspend fun getAttachments(taskUuid: String): List<TaskAttachment>
|
suspend fun getAttachmentsForTask(task: Long): List<Attachment>
|
||||||
|
|
||||||
@Query("SELECT task_attachments.* FROM task_attachments INNER JOIN tasks ON tasks._id = :task WHERE task_id = tasks.remoteId")
|
@Query("SELECT attachment_file.* FROM attachment_file INNER JOIN attachment ON attachment_file.file_uuid = attachment.file_uuid WHERE task = :task")
|
||||||
abstract suspend fun getAttachments(task: Long): List<TaskAttachment>
|
suspend fun getAttachments(task: Long): List<TaskAttachment>
|
||||||
|
|
||||||
@Query("SELECT * FROM task_attachments")
|
@Query("SELECT * FROM attachment_file")
|
||||||
abstract suspend fun getAttachments(): List<TaskAttachment>
|
suspend fun getAttachments(): List<TaskAttachment>
|
||||||
|
|
||||||
@Query("SELECT * FROM task_attachments WHERE task_id = :taskUuid")
|
@Query("SELECT * FROM attachment_file WHERE file_uuid = :remoteId")
|
||||||
abstract fun watchAttachments(taskUuid: String): Flow<List<TaskAttachment>>
|
suspend fun getAttachment(remoteId: String): TaskAttachment?
|
||||||
|
|
||||||
@Delete
|
@Query("DELETE FROM attachment WHERE task = :taskId AND file_uuid = :attachment")
|
||||||
abstract suspend fun delete(taskAttachment: TaskAttachment)
|
suspend fun delete(taskId: Long, attachment: String)
|
||||||
|
|
||||||
|
@Query("DELETE FROM attachment WHERE task = :taskId AND file_uuid IN (:attachments)")
|
||||||
|
suspend fun delete(taskId: Long, attachments: List<String>)
|
||||||
|
|
||||||
|
@Insert
|
||||||
|
suspend fun insert(attachments: List<Attachment>)
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
abstract suspend fun insert(attachment: TaskAttachment)
|
suspend fun insert(attachment: TaskAttachment)
|
||||||
|
|
||||||
@Update
|
@Update
|
||||||
abstract suspend fun update(attachment: TaskAttachment)
|
suspend fun update(attachment: TaskAttachment)
|
||||||
|
|
||||||
suspend fun createNew(attachment: TaskAttachment) {
|
@Delete
|
||||||
if (Task.isUuidEmpty(attachment.remoteId)) {
|
fun delete(value: List<TaskAttachment>)
|
||||||
attachment.remoteId = UUIDHelper.newUUID()
|
|
||||||
}
|
|
||||||
insert(attachment)
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue