Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generalize syncer #907

Merged
merged 53 commits into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from 50 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
1e14139
Use address book contacts content provider provided by syncer
sunkup Jul 13, 2024
a0cff24
Close any acquired content provider after sync
sunkup Jul 13, 2024
cd02f64
Acquire/Check task provider provider as preparation step
sunkup Jul 13, 2024
b319b2d
Provide sync arguments at syncer creation
sunkup Jul 13, 2024
32a5e5f
Acquire ContentProviderClient in syncer implementations
sunkup Jul 13, 2024
4b6cdc4
Merge branch 'main-ose' into 896-generalize-syncer
sunkup Jul 15, 2024
ce1bbf9
Generalize sync algorithm in Syncer
sunkup Jul 15, 2024
6655bab
Use contacts authority for address books
sunkup Jul 16, 2024
7d16109
Generalize sync algorithm in CalendarSyncer
sunkup Jul 15, 2024
ad8aeaa
Generalize sync algorithm in SyncerTest
sunkup Jul 15, 2024
663beff
Generalize sync algorithm in TaskSyncer
sunkup Jul 16, 2024
0444d23
Rename preparation method and add an after sync method
sunkup Jul 16, 2024
f421ad1
Generalize sync algorithm in JtxSyncer
sunkup Jul 16, 2024
a8f83f3
Generalize sync algorithm in AddressBookSyncer
sunkup Jul 16, 2024
6e5a014
Use repositories instead of DAOs
sunkup Jul 16, 2024
5e244a2
Replace deprecated log statements
sunkup Jul 16, 2024
a762023
Use generic type for collection types
sunkup Jul 17, 2024
d407e70
Infer authorities when possible and pass only task authorities along
sunkup Jul 17, 2024
0d199a3
Merge branch 'main-ose' into 896-generalize-syncer
sunkup Jul 22, 2024
c671167
No need to close TaskProvider explicitly
sunkup Jul 22, 2024
439224e
Use colors only where needed
sunkup Jul 22, 2024
0e1acd6
Merge branch 'main-ose' into 896-generalize-syncer
sunkup Jul 29, 2024
dbf5338
Use provider with auto closable
sunkup Jul 29, 2024
c39f615
Get sync collections in syncer implementations
sunkup Jul 29, 2024
a7ad1a9
Delete syncer test
sunkup Jul 30, 2024
5da127d
Pass provider through methods instead of using lateinit property
sunkup Jul 30, 2024
89bc6f8
Reorder constructor arguments
sunkup Jul 30, 2024
3b5dbe4
Remove trailing commas
sunkup Jul 30, 2024
4e67988
Remove obsolete undocumented conditional
sunkup Jul 30, 2024
9f626ce
Reorder methods
sunkup Jul 31, 2024
fa60322
Reorder methods
sunkup Jul 31, 2024
6703eb2
Abort sync when preparations fail
sunkup Jul 31, 2024
c2fd5ae
Drop obsolete permission check
sunkup Jul 31, 2024
bf96333
Use generics for url and delete
sunkup Jul 31, 2024
bff4e2e
Use generic for update
sunkup Jul 31, 2024
c144940
Use generic for syncCollection
sunkup Jul 31, 2024
0ade0ae
Rename create to createCollection for consistency
sunkup Jul 31, 2024
ed07855
Revert "Rename create to createCollection for consistency"
sunkup Aug 1, 2024
fd84b04
Revert "Use generic for syncCollection"
sunkup Aug 1, 2024
0b61d4d
Revert "Use generic for update"
sunkup Aug 1, 2024
73896cf
Revert "Use generics for url and delete"
sunkup Aug 1, 2024
9a7c28a
Move delete() to LocalCollection
sunkup Aug 1, 2024
5e82f27
Move url to LocalCollection
sunkup Aug 1, 2024
eceef11
Fix local test collection
sunkup Aug 1, 2024
71f5811
Minor changes
rfc2822 Aug 2, 2024
712edb7
Minor changes
sunkup Aug 5, 2024
765f00f
Query for sync collections once only
sunkup Aug 5, 2024
3229ead
Add KDoc and update comments
sunkup Aug 5, 2024
8608883
Make property a local variable
sunkup Aug 5, 2024
c4af620
Update KDoc
sunkup Aug 5, 2024
4802fe0
Add back ose conditional
sunkup Aug 5, 2024
6568fe0
Remove blank line at beginning of method
sunkup Aug 5, 2024
e85b022
Merge branch 'main-ose' into 896-generalize-syncer
sunkup Aug 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import at.bitfire.davdroid.resource.LocalCollection
class LocalTestCollection: LocalCollection<LocalTestResource> {

override val tag = "LocalTestCollection"
override val url: String
get() = "https://example.com"
override val title = "Local Test Collection"

override var lastSyncState: SyncState? = null
Expand All @@ -19,6 +21,8 @@ class LocalTestCollection: LocalCollection<LocalTestResource> {
override val readOnly: Boolean
get() = throw NotImplementedError()

override fun delete(): Boolean = true

override fun findDeleted() = entries.filter { it.deleted }
override fun findDirty() = entries.filter { it.dirty }

Expand Down
94 changes: 0 additions & 94 deletions app/src/androidTest/kotlin/at/bitfire/davdroid/sync/SyncerTest.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ package at.bitfire.davdroid.repository

import android.accounts.Account
import android.content.Context
import android.provider.CalendarContract
import android.provider.ContactsContract
import at.bitfire.dav4jvm.DavResource
import at.bitfire.dav4jvm.XmlUtils
import at.bitfire.dav4jvm.XmlUtils.insertTag
Expand All @@ -27,6 +29,7 @@ import at.bitfire.davdroid.network.HttpClient
import at.bitfire.davdroid.servicedetection.RefreshCollectionsWorker
import at.bitfire.davdroid.settings.AccountSettings
import at.bitfire.davdroid.util.DavUtils
import at.bitfire.ical4android.TaskProvider
import at.bitfire.ical4android.util.DateUtils
import dagger.Module
import dagger.hilt.InstallIn
Expand Down Expand Up @@ -184,6 +187,14 @@ class DavCollectionRepository @Inject constructor(

fun getFlow(id: Long) = dao.getFlow(id)

fun getByServiceAndSync(serviceId: Long) = dao.getByServiceAndSync(serviceId)

fun getSyncCalendars(serviceId: Long) = dao.getSyncCalendars(serviceId)

fun getSyncJtxCollections(serviceId: Long) = dao.getSyncJtxCollections(serviceId)

fun getSyncTaskLists(serviceId: Long) = dao.getSyncTaskLists(serviceId)

/** Returns all collections that are both selected for synchronization and push-capable. */
suspend fun getSyncableAndPushCapable(): List<Collection> =
dao.getPushCapableSyncCollections()
Expand Down Expand Up @@ -379,7 +390,6 @@ class DavCollectionRepository @Inject constructor(
}
}


fun interface OnChangeListener {
/**
* Will be called when collections have changed. Will run in the coroutine context/thread
Expand Down
sunkup marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,35 @@ class DavServiceRepository @Inject constructor(

private val dao = db.serviceDao()

fun get(id: Long): Service? = dao.get(id)

fun deleteAll() = dao.deleteAll()
// Read

suspend fun deleteByAccount(accountName: String) {
dao.deleteByAccount(accountName)
}
fun get(id: Long): Service? = dao.get(id)

fun getByAccountAndType(name: String, serviceType: String): Service? =
dao.getByAccountAndType(name, serviceType)

fun getCalDavServiceFlow(accountName: String) =
dao.getByAccountAndTypeFlow(accountName, Service.TYPE_CALDAV)

fun getCardDavServiceFlow(accountName: String) =
dao.getByAccountAndTypeFlow(accountName, Service.TYPE_CARDDAV)


// Create & update

fun insertOrReplace(service: Service) =
dao.insertOrReplace(service)

suspend fun renameAccount(oldName: String, newName: String) {
suspend fun renameAccount(oldName: String, newName: String) =
dao.renameAccount(oldName, newName)
}


// Delete

fun deleteAll() = dao.deleteAll()

suspend fun deleteByAccount(accountName: String) =
dao.deleteByAccount(accountName)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/

package at.bitfire.davdroid.repository

import at.bitfire.davdroid.db.AppDatabase
import at.bitfire.davdroid.db.Principal
import javax.inject.Inject

class PrincipalRepository @Inject constructor(
db: AppDatabase
) {

private val dao = db.principalDao()

fun get(id: Long): Principal = dao.get(id)

}
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ open class LocalAddressBook @Inject constructor(
fun requireMainAccount(): Account =
mainAccount ?: throw IllegalArgumentException("No main account assigned to address book $account")

var url: String
override var url: String
get() = AccountManager.get(context).getUserData(account, USER_DATA_URL)
?: throw IllegalStateException("Address book has no URL")
set(url) = AccountManager.get(context).setAndVerifyUserData(account, USER_DATA_URL, url)
Expand Down Expand Up @@ -304,9 +304,9 @@ open class LocalAddressBook @Inject constructor(
updateSyncFrameworkSettings()
}

fun delete() {
override fun delete(): Boolean {
val accountManager = AccountManager.get(context)
accountManager.removeAccount(account, null, null, null)
return accountManager.removeAccountExplicitly(account)
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ import java.util.LinkedList
import java.util.logging.Level
import java.util.logging.Logger

/**
* Application-specific subclass of [AndroidCalendar] for local calendars.
*
* [Calendars.NAME] is used to store the calendar URL.
*/
class LocalCalendar private constructor(
account: Account,
provider: ContentProviderClient,
Expand Down Expand Up @@ -89,6 +94,9 @@ class LocalCalendar private constructor(

}

override val url: String?
get() = name

override val tag: String
get() = "events-${account.name}-$id"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ import at.bitfire.davdroid.db.SyncState

interface LocalCollection<out T: LocalResource<*>> {

/** a tag that uniquely identifies the collection (DAVx5-wide) */
/** A tag that uniquely identifies the collection (DAVx5-wide) */
val tag: String

/** Address of the remote collection */
@Deprecated("Local collection should be identified by ID, not by URL")
val url: String?

/** collection title (used for user notifications etc.) **/
val title: String

Expand All @@ -23,6 +27,13 @@ interface LocalCollection<out T: LocalResource<*>> {
*/
val readOnly: Boolean

/**
* Deletes the local collection.
*
* @return true if the collection was deleted, false otherwise
*/
fun delete(): Boolean

/**
* Finds local resources of this collection which have been marked as *deleted* by the user
* or an app acting on their behalf.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ import org.dmfs.tasks.contract.TaskContract.*
import java.util.logging.Level
import java.util.logging.Logger

/**
* App-specific implementation of a task list.
*
* [TaskLists._SYNC_ID] is used to store the task list URL.
*/
class LocalTaskList private constructor(
account: Account,
provider: TaskProvider,
Expand Down Expand Up @@ -77,6 +82,9 @@ class LocalTaskList private constructor(
accessLevel != TaskListColumns.ACCESS_LEVEL_UNDEFINED &&
accessLevel <= TaskListColumns.ACCESS_LEVEL_READ

override val url: String?
get() = syncId

override val tag: String
get() = "tasks-${account.name}-$id"

Expand Down
Loading
Loading