Use kotlin serialization for backups

pull/2883/head
Alex Baker 1 month ago
parent 55adbc2025
commit d556863fda

@ -11,6 +11,7 @@ plugins {
id("com.google.android.gms.oss-licenses-plugin") id("com.google.android.gms.oss-licenses-plugin")
id("kotlin-parcelize") id("kotlin-parcelize")
id("com.google.devtools.ksp") id("com.google.devtools.ksp")
kotlin("plugin.serialization") version "1.9.10"
} }
repositories { repositories {
@ -215,6 +216,7 @@ dependencies {
implementation(libs.kotlin.jdk8) implementation(libs.kotlin.jdk8)
implementation(libs.kotlin.immutable) implementation(libs.kotlin.immutable)
implementation(libs.kotlinx.serialization)
implementation(libs.okhttp) implementation(libs.okhttp)
implementation(libs.persistent.cookiejar) implementation(libs.persistent.cookiejar)
implementation(libs.gson) implementation(libs.gson)

@ -1,8 +1,10 @@
package org.tasks.backup package org.tasks.backup
import org.tasks.data.entity.Task import kotlinx.serialization.Serializable
import org.tasks.backup.TasksJsonImporter.LegacyLocation import org.tasks.backup.TasksJsonImporter.LegacyLocation
import org.tasks.data.* import org.tasks.data.GoogleTask
import org.tasks.data.GoogleTaskAccount
import org.tasks.data.GoogleTaskList
import org.tasks.data.entity.Alarm import org.tasks.data.entity.Alarm
import org.tasks.data.entity.Attachment import org.tasks.data.entity.Attachment
import org.tasks.data.entity.CaldavAccount import org.tasks.data.entity.CaldavAccount
@ -13,10 +15,13 @@ import org.tasks.data.entity.Geofence
import org.tasks.data.entity.Place import org.tasks.data.entity.Place
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.TaskAttachment import org.tasks.data.entity.TaskAttachment
import org.tasks.data.entity.TaskListMetadata import org.tasks.data.entity.TaskListMetadata
import org.tasks.data.entity.UserActivity import org.tasks.data.entity.UserActivity
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
@Serializable
class BackupContainer( class BackupContainer(
val tasks: List<TaskBackup>?, val tasks: List<TaskBackup>?,
val places: List<Place>?, val places: List<Place>?,
@ -30,10 +35,11 @@ class BackupContainer(
val longPrefs: Map<String, java.lang.Long>?, val longPrefs: Map<String, java.lang.Long>?,
val stringPrefs: Map<String, String>?, val stringPrefs: Map<String, String>?,
val boolPrefs: Map<String, java.lang.Boolean>?, val boolPrefs: Map<String, java.lang.Boolean>?,
val setPrefs: Map<String, java.util.Set<*>>?, val setPrefs: Map<String, java.util.Set<String>>?,
val googleTaskAccounts: List<GoogleTaskAccount>? = emptyList(), val googleTaskAccounts: List<GoogleTaskAccount>? = emptyList(),
val googleTaskLists: List<GoogleTaskList>? = emptyList(), val googleTaskLists: List<GoogleTaskList>? = emptyList(),
) { ) {
@Serializable
class TaskBackup( class TaskBackup(
val task: Task, val task: Task,
val alarms: List<Alarm>, val alarms: List<Alarm>,

@ -7,10 +7,12 @@ import android.content.Context
import android.net.Uri import android.net.Uri
import android.os.Handler import android.os.Handler
import com.google.common.io.Files import com.google.common.io.Files
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.todoroo.andlib.utility.DialogUtilities import com.todoroo.andlib.utility.DialogUtilities
import org.tasks.data.entity.Task import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.encodeToJsonElement
import org.tasks.BuildConfig import org.tasks.BuildConfig
import org.tasks.R import org.tasks.R
import org.tasks.backup.BackupContainer.TaskBackup import org.tasks.backup.BackupContainer.TaskBackup
@ -26,6 +28,7 @@ import org.tasks.data.dao.TaskAttachmentDao
import org.tasks.data.dao.TaskDao import org.tasks.data.dao.TaskDao
import org.tasks.data.dao.TaskListMetadataDao import org.tasks.data.dao.TaskListMetadataDao
import org.tasks.data.dao.UserActivityDao import org.tasks.data.dao.UserActivityDao
import org.tasks.data.entity.Task
import org.tasks.date.DateTimeUtils.newDateTime import org.tasks.date.DateTimeUtils.newDateTime
import org.tasks.extensions.Context.toast import org.tasks.extensions.Context.toast
import org.tasks.files.FileHelper import org.tasks.files.FileHelper
@ -132,27 +135,32 @@ class TasksJsonExporter @Inject constructor(
vtodoCache.getVtodo( caldavTasks.firstOrNull { !it.isDeleted() }) vtodoCache.getVtodo( caldavTasks.firstOrNull { !it.isDeleted() })
)) ))
} }
val data: MutableMap<String, Any> = HashMap() val data = JsonObject(
data["version"] = BuildConfig.VERSION_CODE mapOf(
data["timestamp"] = currentTimeMillis() "version" to JsonPrimitive(BuildConfig.VERSION_CODE),
data["data"] = BackupContainer( "timestamp" to JsonPrimitive(currentTimeMillis()),
taskBackups, "data" to Json.encodeToJsonElement(
locationDao.getPlaces(), BackupContainer(
tagDataDao.getAll(), taskBackups,
filterDao.getFilters(), locationDao.getPlaces(),
caldavDao.getAccounts(), tagDataDao.getAll(),
caldavDao.getCalendars(), filterDao.getFilters(),
taskListMetadataDao.getAll(), caldavDao.getAccounts(),
taskAttachmentDao.getAttachments(), caldavDao.getCalendars(),
preferences.getPrefs(Integer::class.java), taskListMetadataDao.getAll(),
preferences.getPrefs(java.lang.Long::class.java), taskAttachmentDao.getAttachments(),
preferences.getPrefs(String::class.java), preferences.getPrefs(Integer::class.java),
preferences.getPrefs(java.lang.Boolean::class.java), preferences.getPrefs(java.lang.Long::class.java),
preferences.getPrefs(java.util.Set::class.java), preferences.getPrefs(String::class.java),
preferences.getPrefs(java.lang.Boolean::class.java),
preferences.getPrefs(java.util.Set::class.java) as Map<String, java.util.Set<String>>,
)
)
)
) )
val out = OutputStreamWriter(os, UTF_8) val out = OutputStreamWriter(os, UTF_8)
val gson = if (BuildConfig.DEBUG) GsonBuilder().setPrettyPrinting().create() else Gson() val json = if (BuildConfig.DEBUG) Json { prettyPrint = true } else Json
out.write(gson.toJson(data)) out.write(json.encodeToString(data))
out.close() out.close()
exportCount = taskBackups.size exportCount = taskBackups.size
} }

@ -4,10 +4,7 @@ import android.app.ProgressDialog
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import android.os.Handler import android.os.Handler
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.todoroo.astrid.dao.TaskDao import com.todoroo.astrid.dao.TaskDao
import org.tasks.data.entity.Task
import com.todoroo.astrid.service.TaskCreator.Companion.getDefaultAlarms import com.todoroo.astrid.service.TaskCreator.Companion.getDefaultAlarms
import com.todoroo.astrid.service.TaskMover import com.todoroo.astrid.service.TaskMover
import com.todoroo.astrid.service.Upgrade_13_2 import com.todoroo.astrid.service.Upgrade_13_2
@ -16,27 +13,34 @@ import com.todoroo.astrid.service.Upgrader.Companion.V12_4
import com.todoroo.astrid.service.Upgrader.Companion.V12_8 import com.todoroo.astrid.service.Upgrader.Companion.V12_8
import com.todoroo.astrid.service.Upgrader.Companion.V6_4 import com.todoroo.astrid.service.Upgrader.Companion.V6_4
import com.todoroo.astrid.service.Upgrader.Companion.getAndroidColor import com.todoroo.astrid.service.Upgrader.Companion.getAndroidColor
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromJsonElement
import kotlinx.serialization.json.int
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import org.tasks.LocalBroadcastManager import org.tasks.LocalBroadcastManager
import org.tasks.R import org.tasks.R
import org.tasks.caldav.VtodoCache import org.tasks.caldav.VtodoCache
import org.tasks.data.dao.AlarmDao import org.tasks.data.dao.AlarmDao
import org.tasks.data.dao.CaldavDao
import org.tasks.data.dao.FilterDao
import org.tasks.data.dao.LocationDao
import org.tasks.data.dao.TagDao
import org.tasks.data.dao.TagDataDao
import org.tasks.data.dao.TaskAttachmentDao
import org.tasks.data.dao.TaskListMetadataDao
import org.tasks.data.dao.UserActivityDao
import org.tasks.data.entity.Attachment import org.tasks.data.entity.Attachment
import org.tasks.data.entity.CaldavAccount import org.tasks.data.entity.CaldavAccount
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.CaldavCalendar import org.tasks.data.entity.CaldavCalendar
import org.tasks.data.dao.CaldavDao
import org.tasks.data.entity.CaldavTask import org.tasks.data.entity.CaldavTask
import org.tasks.data.dao.FilterDao
import org.tasks.data.entity.Geofence import org.tasks.data.entity.Geofence
import org.tasks.data.dao.LocationDao
import org.tasks.data.entity.Place import org.tasks.data.entity.Place
import org.tasks.data.entity.Tag import org.tasks.data.entity.Tag
import org.tasks.data.dao.TagDao
import org.tasks.data.entity.TagData import org.tasks.data.entity.TagData
import org.tasks.data.dao.TagDataDao import org.tasks.data.entity.Task
import org.tasks.data.dao.TaskAttachmentDao
import org.tasks.data.dao.TaskListMetadataDao
import org.tasks.data.dao.UserActivityDao
import org.tasks.db.Migrations.repeatFrom import org.tasks.db.Migrations.repeatFrom
import org.tasks.db.Migrations.withoutFrom import org.tasks.db.Migrations.withoutFrom
import org.tasks.filters.FilterCriteriaProvider import org.tasks.filters.FilterCriteriaProvider
@ -78,18 +82,17 @@ class TasksJsonImporter @Inject constructor(
suspend fun importTasks(context: Context, backupFile: Uri?, progressDialog: ProgressDialog?): ImportResult { suspend fun importTasks(context: Context, backupFile: Uri?, progressDialog: ProgressDialog?): ImportResult {
val handler = Handler(context.mainLooper) val handler = Handler(context.mainLooper)
val gson = Gson()
val `is`: InputStream? = try { val `is`: InputStream? = try {
context.contentResolver.openInputStream(backupFile!!) context.contentResolver.openInputStream(backupFile!!)
} catch (e: FileNotFoundException) { } catch (e: FileNotFoundException) {
throw IllegalStateException(e) throw IllegalStateException(e)
} }
val reader = InputStreamReader(`is`, TasksJsonExporter.UTF_8) val reader = InputStreamReader(`is`, TasksJsonExporter.UTF_8)
val input = gson.fromJson(reader, JsonObject::class.java) val input = Json.parseToJsonElement(reader.readText())
try { try {
val data = input["data"] val data = input.jsonObject["data"]!!
val version = input["version"].asInt val version = input.jsonObject["version"]!!.jsonPrimitive.int
val backupContainer = gson.fromJson(data, BackupContainer::class.java) val backupContainer = Json.decodeFromJsonElement<BackupContainer>(data)
backupContainer.tags?.forEach { tagData -> backupContainer.tags?.forEach { tagData ->
findTagData(tagData)?.let { findTagData(tagData)?.let {
return@forEach return@forEach
@ -345,6 +348,7 @@ class TasksJsonImporter @Inject constructor(
var skipCount = 0 var skipCount = 0
} }
@Serializable
class LegacyLocation { class LegacyLocation {
var name: String? = null var name: String? = null
var address: String? = null var address: String? = null

@ -3,6 +3,7 @@ plugins {
kotlin("android") kotlin("android")
id("com.google.devtools.ksp") id("com.google.devtools.ksp")
id("kotlin-parcelize") id("kotlin-parcelize")
kotlin("plugin.serialization") version "1.9.10"
} }
repositories { repositories {
@ -51,7 +52,7 @@ android {
dependencies { dependencies {
implementation(libs.androidx.lifecycle.livedata) implementation(libs.androidx.lifecycle.livedata)
implementation(libs.androidx.room) implementation(libs.androidx.room)
implementation(libs.gson) implementation(libs.kotlinx.serialization)
implementation(libs.timber) implementation(libs.timber)
ksp(libs.androidx.room.compiler) ksp(libs.androidx.room.compiler)
} }

@ -1,6 +1,9 @@
package org.tasks.data package org.tasks.data
import kotlinx.serialization.Serializable
@Deprecated("For backup use only") @Deprecated("For backup use only")
@Serializable
data class GoogleTask( data class GoogleTask(
var remoteId: String? = "", var remoteId: String? = "",
var listId: String? = "", var listId: String? = "",

@ -1,6 +1,9 @@
package org.tasks.data package org.tasks.data
import kotlinx.serialization.Serializable
@Deprecated("Only used for backup migration") @Deprecated("Only used for backup migration")
@Serializable
data class GoogleTaskAccount( data class GoogleTaskAccount(
var account: String? = null, var account: String? = null,
var etag: String? = null, var etag: String? = null,

@ -1,6 +1,9 @@
package org.tasks.data package org.tasks.data
import kotlinx.serialization.Serializable
@Deprecated("Only used for backup migration") @Deprecated("Only used for backup migration")
@Serializable
data class GoogleTaskList( data class GoogleTaskList(
var account: String? = null, var account: String? = null,
var remoteId: String? = null, var remoteId: String? = null,

@ -7,10 +7,13 @@ import androidx.room.Entity
import androidx.room.ForeignKey import androidx.room.ForeignKey
import androidx.room.Ignore import androidx.room.Ignore
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import org.tasks.data.db.Table import org.tasks.data.db.Table
import org.tasks.time.printTimestamp import org.tasks.time.printTimestamp
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@Serializable
@Entity( @Entity(
tableName = Alarm.TABLE_NAME, tableName = Alarm.TABLE_NAME,
foreignKeys = [ foreignKeys = [

@ -5,7 +5,11 @@ import androidx.room.Entity
import androidx.room.ForeignKey import androidx.room.ForeignKey
import androidx.room.Index import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import org.tasks.data.entity.Task.Companion.NO_ID
@Serializable
@Entity( @Entity(
tableName = "attachment", tableName = "attachment",
foreignKeys = [ foreignKeys = [
@ -31,10 +35,10 @@ data class Attachment(
val id: Long? = null, val id: Long? = null,
@ColumnInfo(name = "task", index = true) @ColumnInfo(name = "task", index = true)
@Transient @Transient
val task: Long, val task: Long = NO_ID,
@ColumnInfo(name = "file", index = true) @ColumnInfo(name = "file", index = true)
@Transient @Transient
val fileId: Long, val fileId: Long = NO_ID,
@ColumnInfo(name = "file_uuid") @ColumnInfo(name = "file_uuid")
val attachmentUid: String, val attachmentUid: String,
) )

@ -4,10 +4,13 @@ import android.os.Parcelable
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import org.tasks.data.db.Table
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import org.tasks.data.db.Table
import java.net.HttpURLConnection import java.net.HttpURLConnection
@Serializable
@Parcelize @Parcelize
@Entity(tableName = "caldav_accounts") @Entity(tableName = "caldav_accounts")
data class CaldavAccount( data class CaldavAccount(

@ -4,11 +4,14 @@ import android.os.Parcelable
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import org.tasks.data.db.Table
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import org.tasks.data.LIST import org.tasks.data.LIST
import org.tasks.data.NO_ORDER import org.tasks.data.NO_ORDER
import org.tasks.data.db.Table
@Serializable
@Parcelize @Parcelize
@Entity(tableName = "caldav_lists") @Entity(tableName = "caldav_lists")
data class CaldavCalendar( data class CaldavCalendar(

@ -4,9 +4,13 @@ import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.ForeignKey import androidx.room.ForeignKey
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import org.tasks.data.db.Table import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import org.tasks.data.UUIDHelper import org.tasks.data.UUIDHelper
import org.tasks.data.db.Table
import org.tasks.data.entity.Task.Companion.NO_ID
@Serializable
@Entity( @Entity(
tableName = "caldav_tasks", tableName = "caldav_tasks",
foreignKeys = [ foreignKeys = [
@ -25,7 +29,7 @@ data class CaldavTask(
val id: Long = 0, val id: Long = 0,
@ColumnInfo(name = "cd_task", index = true) @ColumnInfo(name = "cd_task", index = true)
@Transient @Transient
val task: Long, val task: Long = NO_ID,
@ColumnInfo(name = "cd_calendar") @ColumnInfo(name = "cd_calendar")
var calendar: String?, var calendar: String?,
@ColumnInfo(name = "cd_remote_id") @ColumnInfo(name = "cd_remote_id")

@ -5,8 +5,11 @@ import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import org.tasks.data.NO_ORDER import org.tasks.data.NO_ORDER
@Serializable
@Parcelize @Parcelize
@Entity(tableName = "filters") @Entity(tableName = "filters")
data class Filter( data class Filter(

@ -6,10 +6,11 @@ import androidx.room.Entity
import androidx.room.ForeignKey import androidx.room.ForeignKey
import androidx.room.Ignore import androidx.room.Ignore
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import org.tasks.data.db.Table
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import java.io.Serializable import kotlinx.serialization.Serializable
import org.tasks.data.db.Table
@Serializable
@Parcelize @Parcelize
@Entity( @Entity(
tableName = Geofence.TABLE_NAME, tableName = Geofence.TABLE_NAME,
@ -36,7 +37,7 @@ data class Geofence(
val isArrival: Boolean = false, val isArrival: Boolean = false,
@ColumnInfo(name = "departure") @ColumnInfo(name = "departure")
var isDeparture: Boolean = false, var isDeparture: Boolean = false,
) : Serializable, Parcelable { ) : java.io.Serializable, Parcelable {
@Ignore @Ignore
constructor( constructor(
task: Long, task: Long,

@ -6,14 +6,16 @@ import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.Index import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import org.tasks.data.db.Table
import org.tasks.data.UUIDHelper
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import org.tasks.data.NO_ORDER import org.tasks.data.NO_ORDER
import java.io.Serializable import org.tasks.data.UUIDHelper
import org.tasks.data.db.Table
import java.util.regex.Pattern import java.util.regex.Pattern
import kotlin.math.abs import kotlin.math.abs
@Serializable
@Parcelize @Parcelize
@Entity( @Entity(
tableName = Place.TABLE_NAME, tableName = Place.TABLE_NAME,
@ -48,7 +50,7 @@ data class Place(
val order: Int = NO_ORDER, val order: Int = NO_ORDER,
@ColumnInfo(name = "radius", defaultValue = "250") @ColumnInfo(name = "radius", defaultValue = "250")
val radius: Int = 250, val radius: Int = 250,
) : Serializable, Parcelable { ) : java.io.Serializable, Parcelable {
val displayName: String val displayName: String
get() { get() {
if (!name.isNullOrEmpty() && !COORDS.matcher(name!!).matches()) { if (!name.isNullOrEmpty() && !COORDS.matcher(name!!).matches()) {

@ -5,8 +5,11 @@ import androidx.room.Entity
import androidx.room.ForeignKey import androidx.room.ForeignKey
import androidx.room.Ignore import androidx.room.Ignore
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import org.tasks.data.db.Table import org.tasks.data.db.Table
@Serializable
@Entity( @Entity(
tableName = "tags", tableName = "tags",
foreignKeys = [ foreignKeys = [

@ -7,9 +7,12 @@ 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 kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import org.tasks.data.LABEL import org.tasks.data.LABEL
import org.tasks.data.NO_ORDER import org.tasks.data.NO_ORDER
@Serializable
@Entity(tableName = "tagdata") @Entity(tableName = "tagdata")
class TagData : Parcelable { class TagData : Parcelable {
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)

@ -7,23 +7,28 @@ import androidx.room.Entity
import androidx.room.Ignore import androidx.room.Ignore
import androidx.room.Index import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.google.gson.annotations.SerializedName
import org.tasks.data.db.Table
import org.tasks.data.sql.Field
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import kotlinx.parcelize.RawValue import kotlinx.parcelize.RawValue
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import kotlinx.serialization.json.JsonNames
import org.tasks.data.db.Table
import org.tasks.data.sql.Field
import timber.log.Timber import timber.log.Timber
const val SUPPRESS_SYNC = "suppress_sync" const val SUPPRESS_SYNC = "suppress_sync"
const val FORCE_CALDAV_SYNC = "force_caldav_sync" const val FORCE_CALDAV_SYNC = "force_caldav_sync"
@Serializable
@Parcelize @Parcelize
@Entity( @Entity(
tableName = Task.TABLE_NAME, tableName = Task.TABLE_NAME,
indices = [ indices = [
Index(name = "t_rid", value = ["remoteId"], unique = true), Index(name = "t_rid", value = ["remoteId"], unique = true),
Index(name = "active_and_visible", value = ["completed", "deleted", "hideUntil"])]) Index(name = "active_and_visible", value = ["completed", "deleted", "hideUntil"])])
data class Task( data class Task @OptIn(ExperimentalSerializationApi::class) constructor(
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "_id") @ColumnInfo(name = "_id")
@Transient @Transient
@ -53,7 +58,8 @@ data class Task(
@ColumnInfo(name = "timerStart") @ColumnInfo(name = "timerStart")
var timerStart: Long = 0L, var timerStart: Long = 0L,
@ColumnInfo(name = "notificationFlags") @ColumnInfo(name = "notificationFlags")
@SerializedName("ringFlags", alternate = ["reminderFlags"]) @SerialName("ringFlags")
@JsonNames("reminderFlags")
var ringFlags: Int = 0, var ringFlags: Int = 0,
@ColumnInfo(name = "lastNotified") @ColumnInfo(name = "lastNotified")
var reminderLast: Long = 0L, var reminderLast: Long = 0L,

@ -4,9 +4,12 @@ import android.os.Parcelable
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import org.tasks.data.UUIDHelper
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import org.tasks.data.UUIDHelper
@Serializable
@Parcelize @Parcelize
@Entity(tableName = "attachment_file") @Entity(tableName = "attachment_file")
data class TaskAttachment( data class TaskAttachment(

@ -3,13 +3,10 @@ package org.tasks.data.entity
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import org.tasks.data.entity.Task import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
/** @Serializable
* Data Model which represents a user.
*
* @author Tim Su <tim></tim>@todoroo.com>
*/
@Entity(tableName = "task_list_metadata") @Entity(tableName = "task_list_metadata")
class TaskListMetadata { class TaskListMetadata {
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)

@ -7,12 +7,15 @@ 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 org.tasks.data.db.Table import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
import org.tasks.data.db.Table
import timber.log.Timber import timber.log.Timber
import java.io.File import java.io.File
@Serializable
@Entity(tableName = "userActivity") @Entity(tableName = "userActivity")
class UserActivity : Parcelable { class UserActivity : Parcelable {
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)

@ -240,7 +240,20 @@
+| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1 -> 1.7.3 (*) +| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1 -> 1.7.3 (*)
+| | +--- androidx.room:room-common:2.6.1 (c) +| | +--- androidx.room:room-common:2.6.1 (c)
+| | \--- androidx.room:room-runtime:2.6.1 (c) +| | \--- androidx.room:room-runtime:2.6.1 (c)
+| +--- com.google.code.gson:gson:2.10.1 +| +--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2
+| | \--- org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.6.2
+| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.9.21 -> 1.9.23 (*)
+| | +--- org.jetbrains.kotlinx:kotlinx-serialization-bom:1.6.2
+| | | +--- org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.2 (c)
+| | | +--- org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.6.2 (c)
+| | | +--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2 (c)
+| | | \--- org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.6.2 (c)
+| | +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.9.21 -> 1.9.23 (*)
+| | \--- org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.2
+| | \--- org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.6.2
+| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.9.21 -> 1.9.23 (*)
+| | +--- org.jetbrains.kotlinx:kotlinx-serialization-bom:1.6.2 (*)
+| | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.9.21 -> 1.9.23 (*)
+| +--- com.jakewharton.timber:timber:5.0.1 +| +--- com.jakewharton.timber:timber:5.0.1
+| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.5.21 -> 1.9.23 (*) +| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.5.21 -> 1.9.23 (*)
+| | \--- org.jetbrains:annotations:20.1.0 -> 23.0.0 +| | \--- org.jetbrains:annotations:20.1.0 -> 23.0.0
@ -602,6 +615,7 @@
++--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 ++--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7
+| \--- org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.7 +| \--- org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.7
+| \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.21 -> 1.9.23 (*) +| \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.21 -> 1.9.23 (*)
++--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2 (*)
++--- com.squareup.okhttp3:okhttp:4.12.0 (*) ++--- com.squareup.okhttp3:okhttp:4.12.0 (*)
++--- com.github.franmontiel:PersistentCookieJar:1.0.1 ++--- com.github.franmontiel:PersistentCookieJar:1.0.1
+| \--- com.squareup.okhttp3:okhttp:3.1.2 -> 4.12.0 (*) +| \--- com.squareup.okhttp3:okhttp:3.1.2 -> 4.12.0 (*)

@ -600,7 +600,20 @@
+| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1 -> 1.7.3 (*) +| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1 -> 1.7.3 (*)
+| | +--- androidx.room:room-common:2.6.1 (c) +| | +--- androidx.room:room-common:2.6.1 (c)
+| | \--- androidx.room:room-runtime:2.6.1 (c) +| | \--- androidx.room:room-runtime:2.6.1 (c)
+| +--- com.google.code.gson:gson:2.10.1 +| +--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2
+| | \--- org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.6.2
+| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.9.21 -> 1.9.23 (*)
+| | +--- org.jetbrains.kotlinx:kotlinx-serialization-bom:1.6.2
+| | | +--- org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.2 (c)
+| | | +--- org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.6.2 (c)
+| | | +--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2 (c)
+| | | \--- org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.6.2 (c)
+| | +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.9.21 -> 1.9.23 (*)
+| | \--- org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.2
+| | \--- org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.6.2
+| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.9.21 -> 1.9.23 (*)
+| | +--- org.jetbrains.kotlinx:kotlinx-serialization-bom:1.6.2 (*)
+| | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.9.21 -> 1.9.23 (*)
+| +--- com.jakewharton.timber:timber:5.0.1 +| +--- com.jakewharton.timber:timber:5.0.1
+| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.5.21 -> 1.9.23 (*) +| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.5.21 -> 1.9.23 (*)
+| | \--- org.jetbrains:annotations:20.1.0 -> 23.0.0 +| | \--- org.jetbrains:annotations:20.1.0 -> 23.0.0
@ -831,6 +844,7 @@
++--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 ++--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7
+| \--- org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.7 +| \--- org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.7
+| \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.21 -> 1.9.23 (*) +| \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.21 -> 1.9.23 (*)
++--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2 (*)
++--- com.squareup.okhttp3:okhttp:4.12.0 (*) ++--- com.squareup.okhttp3:okhttp:4.12.0 (*)
++--- com.github.franmontiel:PersistentCookieJar:1.0.1 ++--- com.github.franmontiel:PersistentCookieJar:1.0.1
+| \--- com.squareup.okhttp3:okhttp:3.1.2 -> 4.12.0 (*) +| \--- com.squareup.okhttp3:okhttp:3.1.2 -> 4.12.0 (*)

@ -131,6 +131,7 @@ kotlin-immutable = { module = "org.jetbrains.kotlinx:kotlinx-collections-immutab
kotlin-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" } kotlin-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" }
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" } kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" }
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines-test" } kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines-test" }
kotlinx-serialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version = "1.6.2" }
leakcanary = { module = "com.squareup.leakcanary:leakcanary-android", version.ref = "leakcanary" } leakcanary = { module = "com.squareup.leakcanary:leakcanary-android", version.ref = "leakcanary" }
locale = { module = "com.github.twofortyfouram:android-plugin-api-for-locale", version.ref = "locale" } locale = { module = "com.github.twofortyfouram:android-plugin-api-for-locale", version.ref = "locale" }
make-it-easy = { module = "com.natpryce:make-it-easy", version.ref = "make-it-easy" } make-it-easy = { module = "com.natpryce:make-it-easy", version.ref = "make-it-easy" }

Loading…
Cancel
Save